diff --git a/library/src-bootstrapped/scala/quoted/Type.scala b/library/src-bootstrapped/scala/quoted/Type.scala index 1269371cbd0e..9077a626fc66 100644 --- a/library/src-bootstrapped/scala/quoted/Type.scala +++ b/library/src-bootstrapped/scala/quoted/Type.scala @@ -13,11 +13,31 @@ object Type: /** Show a source code like representation of this type without syntax highlight */ def show[T <: AnyKind](using Type[T])(using Quotes): String = - import quotes.reflect._ + import quotes.reflect.* TypeTree.of[T].show /** Return a quoted.Type with the given type */ @compileTimeOnly("Reference to `scala.quoted.Type.of` was not handled by PickleQuotes") given of[T <: AnyKind](using Quotes): Type[T] = ??? + + /** Extracts the value of singleton constant type, None otherwise. + * + * Example usage: + * ```scala + * ... match + * case '{ $mirrorExpr : Mirror.Sum { type MirroredLabel = label } } => + * Type.valueOfConstant[label] // Option[String] + * } + * ``` + * @syntax markdown + */ + def valueOfConstant[T](using Type[T])(using Quotes): Option[T] = + import quotes.reflect.* + def valueOf(tpe: TypeRepr): Option[T] = + tpe.dealias.widenTermRefByName match + case ConstantType(const) => Some(const.value.asInstanceOf[T]) + case _ => None + valueOf(TypeRepr.of[T]) + end Type diff --git a/tests/run-macros/from-type.check b/tests/run-macros/from-type.check new file mode 100644 index 000000000000..9a5fe95f29aa --- /dev/null +++ b/tests/run-macros/from-type.check @@ -0,0 +1,25 @@ +Some(true) +Some(false) +Some(1) +Some(2) +Some(3) +Some(4) +Some(5) +Some(6.0) +Some(7.0) +Some(a) +Some(abc) +Some(10) +Some(11) +None +None +None +None +None +None +None +None +None +None +None +None diff --git a/tests/run-macros/from-type/Macro_1.scala b/tests/run-macros/from-type/Macro_1.scala new file mode 100644 index 000000000000..7ae97ab32f16 --- /dev/null +++ b/tests/run-macros/from-type/Macro_1.scala @@ -0,0 +1,8 @@ +import scala.quoted.* + +inline def testValueOfType[T]: Unit = ${ testValueOfTypeExpr[T] } + +private def testValueOfTypeExpr[T: Type](using Quotes): Expr[Unit] = + val value = Type.valueOfConstant[T] + val strExpr = Expr(value.toString) + '{ println($strExpr) } diff --git a/tests/run-macros/from-type/Test_2.scala b/tests/run-macros/from-type/Test_2.scala new file mode 100644 index 000000000000..272ea7b5dac8 --- /dev/null +++ b/tests/run-macros/from-type/Test_2.scala @@ -0,0 +1,34 @@ + +@main def Test: Unit = + testValueOfType[true] + testValueOfType[false] + testValueOfByte[1] + testValueOfShort[2] + testValueOfType[3] + testValueOfType[4] + testValueOfType[5L] + testValueOfType[6d] + testValueOfType[7f] + testValueOfType['a'] + testValueOfType["abc"] + val x: 10 = 10 + testValueOfType[x.type] + type A = 11 + testValueOfType[A] + + + testValueOfType[Boolean] + testValueOfType[Byte] + testValueOfType[Short] + testValueOfType[Int] + testValueOfType[Long] + testValueOfType[Double] + testValueOfType[Float] + testValueOfType[Char] + testValueOfType[String] + testValueOfType[Null] + testValueOfType[Any] + testValueOfType[Some[1]] + +transparent inline def testValueOfByte[B <: Byte] = testValueOfType[B] +transparent inline def testValueOfShort[S <: Short] = testValueOfType[S]