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 /compiler/src | |
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`.
Diffstat (limited to 'compiler/src')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Implicits.scala | 47 |
1 files changed, 28 insertions, 19 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) = { |