diff options
author | Martin Odersky <odersky@gmail.com> | 2017-02-01 16:43:00 +1100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-02-01 16:43:00 +1100 |
commit | b11e6d678a92187e5e9f821ba1116cec2cce0f8c (patch) | |
tree | 81efac5e249e680d23c777752c98e3e649508b5d | |
parent | 2ce93287d809ed0012546c8466712a40e5a9c2e5 (diff) | |
download | dotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.tar.gz dotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.tar.bz2 dotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.zip |
Handle Array classtags in the same way as others
The previous implicit definition of arrayTag in DottyPredef
priorities arrayTag over all other classtag searches, which
led to surprising results in `i1907a.scala`.
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Implicits.scala | 47 | ||||
-rw-r--r-- | library/src/dotty/DottyPredef.scala | 3 |
2 files changed, 28 insertions, 22 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 183dff282..2112b1221 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -507,7 +507,34 @@ trait Implicits { self: Typer => * which is itself parameterized by another string, * indicating where the implicit parameter is needed */ - def inferImplicitArg(formal: Type, error: (String => String) => Unit, pos: Position)(implicit ctx: Context): Tree = + def inferImplicitArg(formal: Type, error: (String => String) => Unit, pos: Position)(implicit ctx: Context): Tree = { + + /** If `formal` is of the form ClassTag[T], where `T` is a class type, + * synthesize a class tag for `T`. + */ + def synthesizedClassTag(formal: Type, pos: Position)(implicit ctx: Context): Tree = { + if (formal.isRef(defn.ClassTagClass)) + formal.argTypes match { + case arg :: Nil => + fullyDefinedType(arg, "ClassTag argument", pos) match { + case defn.ArrayOf(elemTp) => + val etag = inferImplicitArg(defn.ClassTagType.appliedTo(elemTp), error, pos) + if (etag.isEmpty) etag else etag.select(nme.wrap) + case tp if hasStableErasure(tp) => + ref(defn.ClassTagModule) + .select(nme.apply) + .appliedToType(tp) + .appliedTo(clsOf(erasure(tp))) + .withPos(pos) + case tp => + EmptyTree + } + case _ => + EmptyTree + } + else EmptyTree + } + inferImplicit(formal, EmptyTree, pos) match { case SearchSuccess(arg, _, _, _) => arg @@ -534,24 +561,6 @@ trait Implicits { self: Typer => EmptyTree } } - - /** If `formal` is of the form ClassTag[T], where `T` is a class type, - * synthesize a class tag for `T`. - */ - def synthesizedClassTag(formal: Type, pos: Position)(implicit ctx: Context): Tree = { - if (formal.isRef(defn.ClassTagClass)) - formal.argTypes match { - case arg :: Nil => - val tp = fullyDefinedType(arg, "ClassTag argument", pos) - if (hasStableErasure(tp)) - return ref(defn.ClassTagModule) - .select(nme.apply) - .appliedToType(tp) - .appliedTo(clsOf(erasure(tp))) - .withPos(pos) - case _ => - } - EmptyTree } private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = { diff --git a/library/src/dotty/DottyPredef.scala b/library/src/dotty/DottyPredef.scala index cd90c4882..c7cf2a906 100644 --- a/library/src/dotty/DottyPredef.scala +++ b/library/src/dotty/DottyPredef.scala @@ -9,9 +9,6 @@ import scala.collection.Seq object DottyPredef { implicit def typeTag[T]: TypeTag[T] = ??? - implicit def arrayTag[T](implicit ctag: ClassTag[T]): ClassTag[Array[T]] = - ctag.wrap - /** A fall-back implicit to compare values of any types. * The compiler will restrict implicit instances of `eqAny`. An instance * `eqAny[T, U]` is _valid_ if `T <: U` or `U <: T` or both `T` and `U` are |