diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 0e67fd40991b..67839d10c8cd 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -520,8 +520,9 @@ object TypeErasure { case _: ClassInfo => true case _ => false } - case tp: TypeParamRef => false - case tp: TypeBounds => false + case _: TypeParamRef => false + case _: TypeBounds => false + case _: MatchType => false case tp: TypeProxy => hasStableErasure(tp.translucentSuperType) case tp: AndType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2) case tp: OrType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 71efc27bf673..1a7a4b97855b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -52,14 +52,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): if defn.SpecialClassTagClasses.contains(sym) then classTagModul.select(sym.name.toTermName).withSpan(span) else - def clsOfType(tp: Type): Type = tp.dealias.underlyingMatchType match - case matchTp: MatchType => - matchTp.alternatives.map(clsOfType) match - case ct1 :: cts if cts.forall(ct1 == _) => ct1 - case _ => NoType - case _ => - escapeJavaArray(erasure(tp)) - val ctype = clsOfType(tp) + val ctype = escapeJavaArray(erasure(tp)) if ctype.exists then classTagModul.select(nme.apply) .appliedToType(tp) diff --git a/tests/neg/i15618.check b/tests/neg/i15618.check index 91f557b12dcf..16fadcd9b886 100644 --- a/tests/neg/i15618.check +++ b/tests/neg/i15618.check @@ -16,3 +16,9 @@ | | case Float32 => Float | case Int32 => Int +-- [E172] Type Error: tests/neg/i15618.scala:21:33 --------------------------------------------------------------------- +21 | def toArray: Array[T] = Array() // error + | ^ + | No ClassTag available for T + | + | where: T is a type in class Tensor2 with bounds <: Int | Float diff --git a/tests/neg/i15618.scala b/tests/neg/i15618.scala index fd38c8c48f6b..087bc462b211 100644 --- a/tests/neg/i15618.scala +++ b/tests/neg/i15618.scala @@ -16,8 +16,16 @@ class Tensor[T <: DType](dtype: T): def toSeq: Seq[ScalaType[T]] = Seq() def toArray: Array[ScalaType[T]] = Array() // error +class Tensor2[T <: Int | Float](dtype: T): + def toSeq: Seq[T] = Seq() + def toArray: Array[T] = Array() // error + @main def Test = val t = Tensor(Float32) // Tensor[Float32] println(t.toSeq.headOption) // works, Seq[Float] println(t.toArray.headOption) // ClassCastException + + val t2 = Tensor2(0.0f) // Tensor2[Float] + println(t.toSeq.headOption) + println(t.toArray.headOption) diff --git a/tests/pos/i16706.scala b/tests/pos/i16706.scala new file mode 100644 index 000000000000..87fd015c69bb --- /dev/null +++ b/tests/pos/i16706.scala @@ -0,0 +1,17 @@ +import scala.deriving.Mirror +import scala.reflect.ClassTag + +type TupleUnionLub[T <: Tuple, Lub, Acc <: Lub] <: Lub = T match { + case (h & Lub) *: t => TupleUnionLub[t, Lub, Acc | h] + case EmptyTuple => Acc +} + +transparent inline given derived[A]( + using m: Mirror.SumOf[A], + idClassTag: ClassTag[TupleUnionLub[m.MirroredElemTypes, A, Nothing]] +): Unit = () + +sealed trait Foo +case class FooA(a: Int) extends Foo + +val instance = derived[Foo] // error \ No newline at end of file diff --git a/tests/pos/i16707.scala b/tests/pos/i16707.scala new file mode 100644 index 000000000000..6181471f5246 --- /dev/null +++ b/tests/pos/i16707.scala @@ -0,0 +1,11 @@ +import scala.deriving.Mirror +import scala.reflect.ClassTag + +transparent inline given derived[A]( + using m: Mirror.ProductOf[A], + idClassTag: ClassTag[Tuple.Union[m.MirroredElemTypes]] + ): Unit = ??? + +case class Foo(a: Int) + +val instance = derived[Foo] // error