diff --git a/compiler/src/dotty/tools/dotc/core/TypeEval.scala b/compiler/src/dotty/tools/dotc/core/TypeEval.scala index 98578f353b96..5bcd45b61785 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeEval.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeEval.scala @@ -2,6 +2,8 @@ package dotty.tools package dotc package core +import scala.reflect.Typeable + import Types.*, Contexts.*, Symbols.*, Constants.*, Decorators.* import config.Printers.typr import reporting.trace @@ -26,33 +28,22 @@ object TypeEval: if tp1.isStable then tp1.fixForEvaluation else tp case tp => tp - def constValue(tp: Type): Option[Any] = tp.fixForEvaluation match - case ConstantType(Constant(n)) => Some(n) - case _ => None + extension (tp: Type) def constant[T: Typeable]: Option[T] = + TypeComparer.constValue(tp.fixForEvaluation).collect { case Constant(c: T) => c } + + def constValue(tp: Type): Option[Any] = tp.constant[Any] - def boolValue(tp: Type): Option[Boolean] = tp.fixForEvaluation match - case ConstantType(Constant(n: Boolean)) => Some(n) - case _ => None + def boolValue(tp: Type): Option[Boolean] = tp.constant[Boolean] - def intValue(tp: Type): Option[Int] = tp.fixForEvaluation match - case ConstantType(Constant(n: Int)) => Some(n) - case _ => None + def intValue(tp: Type): Option[Int] = tp.constant[Int] - def longValue(tp: Type): Option[Long] = tp.fixForEvaluation match - case ConstantType(Constant(n: Long)) => Some(n) - case _ => None + def longValue(tp: Type): Option[Long] = tp.constant[Long] - def floatValue(tp: Type): Option[Float] = tp.fixForEvaluation match - case ConstantType(Constant(n: Float)) => Some(n) - case _ => None + def floatValue(tp: Type): Option[Float] = tp.constant[Float] - def doubleValue(tp: Type): Option[Double] = tp.fixForEvaluation match - case ConstantType(Constant(n: Double)) => Some(n) - case _ => None + def doubleValue(tp: Type): Option[Double] = tp.constant[Double] - def stringValue(tp: Type): Option[String] = tp.fixForEvaluation match - case ConstantType(Constant(n: String)) => Some(n) - case _ => None + def stringValue(tp: Type): Option[String] = tp.constant[String] // Returns Some(true) if the type is a constant. // Returns Some(false) if the type is not a constant. diff --git a/tests/pos/i24717.scala b/tests/pos/i24717.scala new file mode 100644 index 000000000000..56309f9de547 --- /dev/null +++ b/tests/pos/i24717.scala @@ -0,0 +1,13 @@ +import scala.compiletime.ops.int.+ +import scala.compiletime.ops.int.S + +object test { + object O { + opaque type O = Int + transparent inline def v: O = 123 + } + + val a: 123 & O.O = O.v + val b: S[a.type] = 124 + val c: a.type + 1 = 124 +}