aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-02-18 14:07:03 +0100
committerMartin Odersky <odersky@gmail.com>2016-02-20 10:19:56 +0100
commite4989b3cc13f70d8316790e309b5d3b27317d80e (patch)
treef0e2492607d221323585924a003cb57ab665c54e /src/dotty/tools/dotc/typer/Typer.scala
parentf6391c780ce7472352b60da9fdd7ec8d7496a0ea (diff)
downloaddotty-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.scala25
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)