diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeErasure.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 16 | ||||
-rw-r--r-- | tests/run/i1284.scala | 8 |
3 files changed, 33 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala index a1dab16cb..1a7342a12 100644 --- a/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/src/dotty/tools/dotc/core/TypeErasure.scala @@ -277,6 +277,22 @@ object TypeErasure { else tp1 } } + + /** Does the (possibly generic) type `tp` have the same erasure in all its + * possible instantiations? + */ + def hasStableErasure(tp: Type)(implicit ctx: Context): Boolean = tp match { + case tp: TypeRef => + tp.info match { + case TypeAlias(alias) => hasStableErasure(alias) + case _: ClassInfo => true + case _ => false + } + case tp: PolyParam => false + case tp: TypeProxy => hasStableErasure(tp.superType) + case tp: AndOrType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2) + case _ => false + } } import TypeErasure._ @@ -493,4 +509,6 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean println(s"no sig for $tp") throw ex } + + } diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index feed398aa..1eba64e2e 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -10,6 +10,7 @@ import printing.Showable import Contexts._ import Types._ import Flags._ +import TypeErasure.{erasure, hasStableErasure} import Mode.ImplicitsEnabled import Denotations._ import NameOps._ @@ -479,15 +480,12 @@ trait Implicits { self: Typer => formal.argTypes match { case arg :: Nil => val tp = fullyDefinedType(arg, "ClassTag argument", pos) - tp.underlyingClassRef(refinementOK = false) match { - case tref: TypeRef => - return ref(defn.ClassTagModule) - .select(nme.apply) - .appliedToType(tp) - .appliedTo(clsOf(tref)) - .withPos(pos) - case _ => - } + if (hasStableErasure(tp)) + return ref(defn.ClassTagModule) + .select(nme.apply) + .appliedToType(tp) + .appliedTo(clsOf(erasure(tp))) + .withPos(pos) case _ => } EmptyTree diff --git a/tests/run/i1284.scala b/tests/run/i1284.scala new file mode 100644 index 000000000..f8b9de0de --- /dev/null +++ b/tests/run/i1284.scala @@ -0,0 +1,8 @@ +case object A +case object B + +object Test { + def main(args: Array[String]): Unit = { + assert(Array(A, B).deep.toString == "Array(A, B)") + } +} |