diff options
author | odersky <odersky@gmail.com> | 2017-02-08 22:21:05 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-08 22:21:05 +1100 |
commit | 18d5913821064fffa0c74524ba1a8ead9a7def31 (patch) | |
tree | 502b93ffc33390ec0f433dfa5b71b7e9c384edd2 /compiler/src | |
parent | 99679cffc0a5d20e7e7f3c090eb310a6134eeee7 (diff) | |
parent | abbee9e28ef3f0150c9afa48f485ecc49e0e3787 (diff) | |
download | dotty-18d5913821064fffa0c74524ba1a8ead9a7def31.tar.gz dotty-18d5913821064fffa0c74524ba1a8ead9a7def31.tar.bz2 dotty-18d5913821064fffa0c74524ba1a8ead9a7def31.zip |
Merge pull request #1921 from dotty-staging/fix-#1907
Fix #1907: Improve error message
Diffstat (limited to 'compiler/src')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Implicits.scala | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index d4e74cf7d..6949221fb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -507,7 +507,36 @@ 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) => + if (defn.isBottomClass(tp.typeSymbol)) + error(where => i"attempt to take ClassTag of undetermined type for $where") + 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 +563,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) = { |