diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 38 | ||||
-rw-r--r-- | tests/neg/i1430.scala | 8 |
2 files changed, 40 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index c60f4c1f2..7c61f8c23 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -17,6 +17,7 @@ import Decorators._ import Uniques._ import config.Printers._ import annotation.tailrec +import reporting._ import collection.mutable object Inferencing { @@ -222,13 +223,38 @@ object Inferencing { val vs = variances(tp, qualifies) var changed = false - vs foreachBinding { (tvar, v) => - if (v != 0) { - typr.println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}") - tvar.instantiate(fromBelow = v == 1) - changed = true - } + val hasUnreportedErrors = ctx.typerState.reporter match { + case r: StoreReporter if r.hasErrors => true + case _ => false } + // Avoid interpolating variables if typerstate has unreported errors. + // Reason: The errors might reflect unsatisfiable constraints. In that + // case interpolating without taking account the constraints risks producing + // nonsensical types that then in turn produce incomprehensible errors. + // An example is in neg/i1240.scala. Without the condition in the next code line + // we get for + // + // val y: List[List[String]] = List(List(1)) + // + // i1430.scala:5: error: type mismatch: + // found : Int(1) + // required: Nothing + // val y: List[List[String]] = List(List(1)) + // ^ + // With the condition, we get the much more sensical: + // + // i1430.scala:5: error: type mismatch: + // found : Int(1) + // required: String + // val y: List[List[String]] = List(List(1)) + if (!hasUnreportedErrors) + vs foreachBinding { (tvar, v) => + if (v != 0) { + typr.println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}") + tvar.instantiate(fromBelow = v == 1) + changed = true + } + } if (changed) // instantiations might have uncovered new typevars to interpolate interpolateUndetVars(tree, ownedBy) else diff --git a/tests/neg/i1430.scala b/tests/neg/i1430.scala new file mode 100644 index 000000000..870780695 --- /dev/null +++ b/tests/neg/i1430.scala @@ -0,0 +1,8 @@ +object Test { + + val x: List[String] = List(1) // error: found Int(1), expected: String + + val y: List[List[String]] = List(List(1)) // error: found Int(1), expected: String + + val z: (List[String], List[Int]) = (List(1), List("a")) // error: found Int(1), expected: String // error: found String(a), expected: Int +} |