1
import scala.reflect.runtime.universe._

val a: 42 = 42
val t: Type = typeOf[a.type]
assert(getConstantType(t).get =:= typeOf[42])

def getConstantType(t: Type): Option[ConstantType] = ???

How could I generally implement getConstantType so that the above assertion passes? I assumed that something like this was possible since the assertion below passes:

assert(t <:< typeOf[42])

t.widen goes too far as it return Int. I'm looking for something that returns Int(42).

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
user3773003
  • 101
  • 6

2 Answers2

1

How about

assert(t.resultType =:= typeOf[42])

Updated -

def getConstantType[T](t: T): t.type = t

Update 2 -

def getConstantType(tp: Type): Option[ConstantType] = {
  tp.erasure match {
    case ConstantType(_) => Some(tp.erasure.asInstanceOf[ConstantType])
    case _ => None
  }
}
kgu87
  • 2,050
  • 14
  • 12
1

Try

def getConstantType(tp: Type): Option[ConstantType] = {
  def unrefine(t: Type): Type = t.dealias match {
    case RefinedType(List(t), scope) if scope.isEmpty => unrefine(t)
    case t                                            => t
  }

  unrefine(tp) match {
    case SingleType(_, sym) => sym.typeSignature match {
      case NullaryMethodType(t) => unrefine(t) match {
        case c: ConstantType => Some(c)
        case _               => None
      }
      case _                 => None
    }
    case _                   => None
  }
}
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66