diff --git a/library/src/scala/compiletime/package.scala b/library/src/scala/compiletime/package.scala index 3821b9dbd2e7..4d53d8dd25c8 100644 --- a/library/src/scala/compiletime/package.scala +++ b/library/src/scala/compiletime/package.scala @@ -193,3 +193,15 @@ def byName[T](x: => T): T = x */ extension [T](x: T) transparent inline def asMatchable: x.type & Matchable = x.asInstanceOf[x.type & Matchable] + +extension (inline self: Any) + /** + * TODO: Write the scaladoc here and how it works + * ??? + * @param self ??? + * @param T ??? + * @return ??? + */ + transparent inline def as[T]: T = inline self match + case self: T => self + case _ => error("Cannot statically prove the correctness of the cast") diff --git a/tests/neg/static-cast.check b/tests/neg/static-cast.check new file mode 100644 index 000000000000..5bba9689fb22 --- /dev/null +++ b/tests/neg/static-cast.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/static-cast.scala:11:18 ---------------------------------------------------------------------------- +11 |val _ = singletons[B, (A.A1.type, A.A2.type, A.A3.type)] // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Cannot statically prove the correctness of the cast diff --git a/tests/neg/static-cast.scala b/tests/neg/static-cast.scala new file mode 100644 index 000000000000..8dfa8ee0e899 --- /dev/null +++ b/tests/neg/static-cast.scala @@ -0,0 +1,11 @@ +import scala.compiletime.* + +trait B +enum A { case A1, A2, A3 } + +private inline def singletons[T, Elem <: Tuple]: Seq[T] = + inline erasedValue[Elem] match + case _: EmptyTuple => Seq.empty + case _: (h *: t) => valueOf[h](using summonInline).as[T] +: singletons[T, t] + +val _ = singletons[B, (A.A1.type, A.A2.type, A.A3.type)] // error diff --git a/tests/pos/static-cast.scala b/tests/pos/static-cast.scala new file mode 100644 index 000000000000..4e8a441bdc06 --- /dev/null +++ b/tests/pos/static-cast.scala @@ -0,0 +1,10 @@ +import scala.compiletime.* + +enum A { case A1, A2, A3 } + +private inline def singletons[T, Elem <: Tuple]: Seq[T] = + inline erasedValue[Elem] match + case _: EmptyTuple => Seq.empty + case _: (h *: t) => valueOf[h](using summonInline).as[T] +: singletons[T, t] + +val x = singletons[A, (A.A1.type, A.A2.type, A.A3.type)]