aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala49
-rw-r--r--compiler/test/dotty/tools/dotc/CompilerTest.scala33
2 files changed, 49 insertions, 33 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) = {
diff --git a/compiler/test/dotty/tools/dotc/CompilerTest.scala b/compiler/test/dotty/tools/dotc/CompilerTest.scala
index eaa0bea84..5d16917cc 100644
--- a/compiler/test/dotty/tools/dotc/CompilerTest.scala
+++ b/compiler/test/dotty/tools/dotc/CompilerTest.scala
@@ -397,20 +397,25 @@ abstract class CompilerTest {
/** Gives an error message for one line where the expected number of errors and
* the number of compiler errors differ. */
def compareLines(fileName: String, expectedLines: List[(Int, Int)], foundLines: List[(Int, Int)]) = {
- expectedLines.foreach({ case (line, expNr) =>
- foundLines.find(_._1 == line) match {
- case Some((_, `expNr`)) => // this line is ok
- case Some((_, foundNr)) => errorMsg(fileName, Some(line), expNr, foundNr)
- case None => errorMsg(fileName, Some(line), expNr, 0)
- }
- })
- foundLines.foreach({ case (line, foundNr) =>
- expectedLines.find(_._1 == line) match {
- case Some((_, `foundNr`)) => // this line is ok
- case Some((_, expNr)) => errorMsg(fileName, Some(line), expNr, foundNr)
- case None => errorMsg(fileName, Some(line), 0, foundNr)
- }
- })
+ expectedLines foreach{
+ case (line, expNr) =>
+ foundLines.find(_._1 == line) match {
+ case Some((_, `expNr`)) => // this line is ok
+ case Some((_, foundNr)) => errorMsg(fileName, Some(line), expNr, foundNr)
+ case None =>
+ println(s"expected lines = $expectedLines%, %")
+ println(s"found lines = $foundLines%, %")
+ errorMsg(fileName, Some(line), expNr, 0)
+ }
+ }
+ foundLines foreach {
+ case (line, foundNr) =>
+ expectedLines.find(_._1 == line) match {
+ case Some((_, `foundNr`)) => // this line is ok
+ case Some((_, expNr)) => errorMsg(fileName, Some(line), expNr, foundNr)
+ case None => errorMsg(fileName, Some(line), 0, foundNr)
+ }
+ }
}
// ========== PARTEST HELPERS =============