aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-02-21 17:08:43 +0100
committerGitHub <noreply@github.com>2017-02-21 17:08:43 +0100
commit6189ffe415c8905cc5802f0505d837b4142999db (patch)
tree40ba46ae1c6e1956939e7614a60bd72031291f63 /compiler/src/dotty/tools/dotc
parent61858c048bacb22aeab1893f8812896cb2b4d6a7 (diff)
parent779eaf6b9898e4ec8e2e3cdfbf0d36aeede3926e (diff)
downloaddotty-6189ffe415c8905cc5802f0505d837b4142999db.tar.gz
dotty-6189ffe415c8905cc5802f0505d837b4142999db.tar.bz2
dotty-6189ffe415c8905cc5802f0505d837b4142999db.zip
Merge pull request #1984 from dotty-staging/fix-#1747-v2
Fix #1747: Improve error message for Scala/Java type mismatch
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FullParameterization.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala2
6 files changed, 25 insertions, 11 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 9e9e39a84..847177e2f 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -9,6 +9,7 @@ import scala.annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
import PartialFunction._
import collection.mutable
+import util.common.alwaysZero
import scala.reflect.api.{ Universe => ApiUniverse }
object Definitions {
@@ -152,7 +153,7 @@ class Definitions {
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
- val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
+ val ptype = PolyType(tparamNames, tparamNames.map(alwaysZero))(_ => tparamBounds, resultTypeFn)
enterMethod(cls, name, ptype, flags)
}
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index ae9122853..1174e863e 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -2603,7 +2603,7 @@ object Types {
case t => mapOver(t)
}
}
- PolyType(paramNames ++ that.paramNames)(
+ PolyType(paramNames ++ that.paramNames, variances ++ that.variances)(
x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
x => shift(that.resultType).subst(that, x).subst(this, x))
@@ -2634,11 +2634,10 @@ object Types {
}
object PolyType {
- def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(
+ def apply(paramNames: List[TypeName], variances: List[Int])(
paramBoundsExp: PolyType => List[TypeBounds],
resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
- val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances
- unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp))
+ unique(new PolyType(paramNames, variances)(paramBoundsExp, resultTypeExp))
}
def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index ac25f7cfd..1c3ff8ea0 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -177,7 +177,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
varianceString(variance) ~ name.toString ~ toText(bounds)
changePrec(GlobalPrec) {
"[" ~ Text((tp.variances, tp.paramNames, tp.paramBounds).zipped.map(paramText), ", ") ~
- "] => " ~ toTextGlobal(tp.resultType)
+ "]" ~ (" => " provided !tp.resultType.isInstanceOf[MethodType]) ~
+ toTextGlobal(tp.resultType)
}
case tp: PolyParam =>
polyParamNameString(tp) ~ polyHash(tp.binder)
diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
index 6c69c735b..9e43fc999 100644
--- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -101,6 +101,7 @@ trait FullParameterization {
}
val ctparams = if (abstractOverClass) clazz.typeParams else Nil
val ctnames = ctparams.map(_.name.unexpandedName)
+ val ctvariances = ctparams.map(_.variance)
/** The method result type */
def resultType(mapClassParams: Type => Type) = {
@@ -122,14 +123,14 @@ trait FullParameterization {
info match {
case info: PolyType =>
- PolyType(info.paramNames ++ ctnames)(
+ PolyType(info.paramNames ++ ctnames, info.variances ++ ctvariances)(
pt =>
(info.paramBounds.map(mapClassParams(_, pt).bounds) ++
mappedClassBounds(pt)).mapConserve(_.subst(info, pt).bounds),
pt => resultType(mapClassParams(_, pt)).subst(info, pt))
case _ =>
if (ctparams.isEmpty) resultType(identity)
- else PolyType(ctnames)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
+ else PolyType(ctnames, ctvariances)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
}
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 1238ad568..9d6a01ab7 100644
--- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -111,11 +111,23 @@ object ErrorReporting {
errorTree(tree, typeMismatchMsg(normalize(tree.tpe, pt), pt, implicitFailure.postscript))
/** A subtype log explaining why `found` does not conform to `expected` */
- def whyNoMatchStr(found: Type, expected: Type) =
- if (ctx.settings.explaintypes.value)
+ def whyNoMatchStr(found: Type, expected: Type) = {
+ def dropJavaMethod(tp: Type): Type = tp match {
+ case tp: PolyType =>
+ tp.derivedPolyType(resType = dropJavaMethod(tp.resultType))
+ case tp: JavaMethodType =>
+ MethodType(tp.paramNames, tp.paramTypes, dropJavaMethod(tp.resultType))
+ case tp => tp
+ }
+ val found1 = dropJavaMethod(found)
+ val expected1 = dropJavaMethod(expected)
+ if ((found1 eq found) != (expected eq expected1) && (found1 <:< expected1))
+ "\n (Note that Scala's and Java's representation of this type differs)"
+ else if (ctx.settings.explaintypes.value)
"\n" + ctx.typerState.show + "\n" + TypeComparer.explained((found <:< expected)(_))
else
""
+ }
def typeMismatchMsg(found: Type, expected: Type, postScript: String = "") = {
// replace constrained polyparams and their typevars by their bounds where possible
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 6949221fb..48cf0cfac 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -220,7 +220,7 @@ object Implicits {
}
/** The result of an implicit search */
- abstract class SearchResult extends Showable {
+ sealed abstract class SearchResult extends Showable {
def toText(printer: Printer): Text = printer.toText(this)
}