diff options
author | Martin Odersky <odersky@gmail.com> | 2016-02-18 14:07:03 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-02-20 10:19:56 +0100 |
commit | e4989b3cc13f70d8316790e309b5d3b27317d80e (patch) | |
tree | f0e2492607d221323585924a003cb57ab665c54e /src/dotty/tools/dotc/typer/Typer.scala | |
parent | f6391c780ce7472352b60da9fdd7ec8d7496a0ea (diff) | |
download | dotty-e4989b3cc13f70d8316790e309b5d3b27317d80e.tar.gz dotty-e4989b3cc13f70d8316790e309b5d3b27317d80e.tar.bz2 dotty-e4989b3cc13f70d8316790e309b5d3b27317d80e.zip |
Synthesize classTags in Typer.
Now diagnoses missing ClassTags of abstract types
as implicit failures.
Also: Simpler API of tpd.clsOf.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index fc2bf2381..445037228 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1477,7 +1477,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case ambi: AmbiguousImplicits => implicitArgError(s"ambiguous implicits: ${ambi.explanation} of $where") case failure: SearchFailure => - implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript) + val arg = synthesizedClassTag(formal) + if (!arg.isEmpty) arg + else implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript) } } if (errors.nonEmpty) { @@ -1538,6 +1540,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } + /** If `formal` is of the form ClassTag[T], where `T` is a class type, + * synthesize a class tag for `T`. + */ + def synthesizedClassTag(formal: Type): Tree = { + if (formal.isRef(defn.ClassTagClass)) + formal.argTypes match { + case arg :: Nil => + arg.underlyingClassRef(refinementOK = false) match { + case tref: TypeRef => + return ref(defn.ClassTagModule) + .select(nme.apply) + .appliedToType(arg) + .appliedTo(clsOf(tref)) + .withPos(tree.pos.endPos) + case _ => + } + case _ => + } + EmptyTree + } + /** Adapt an expression of constant type to a different constant type `tpe`. */ def adaptConstant(tree: Tree, tpe: ConstantType): Tree = { def lit = Literal(tpe.value).withPos(tree.pos) |