Skip to content

Commit 6189ffe

Browse files
authored
Merge pull request #1984 from dotty-staging/fix-#1747-v2
Fix #1747: Improve error message for Scala/Java type mismatch
2 parents 61858c0 + 779eaf6 commit 6189ffe

File tree

7 files changed

+28
-11
lines changed

7 files changed

+28
-11
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import scala.annotation.{ switch, meta }
99
import scala.collection.{ mutable, immutable }
1010
import PartialFunction._
1111
import collection.mutable
12+
import util.common.alwaysZero
1213
import scala.reflect.api.{ Universe => ApiUniverse }
1314

1415
object Definitions {
@@ -152,7 +153,7 @@ class Definitions {
152153
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
153154
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
154155
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
155-
val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
156+
val ptype = PolyType(tparamNames, tparamNames.map(alwaysZero))(_ => tparamBounds, resultTypeFn)
156157
enterMethod(cls, name, ptype, flags)
157158
}
158159

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,7 +2603,7 @@ object Types {
26032603
case t => mapOver(t)
26042604
}
26052605
}
2606-
PolyType(paramNames ++ that.paramNames)(
2606+
PolyType(paramNames ++ that.paramNames, variances ++ that.variances)(
26072607
x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
26082608
that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
26092609
x => shift(that.resultType).subst(that, x).subst(this, x))
@@ -2634,11 +2634,10 @@ object Types {
26342634
}
26352635

26362636
object PolyType {
2637-
def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(
2637+
def apply(paramNames: List[TypeName], variances: List[Int])(
26382638
paramBoundsExp: PolyType => List[TypeBounds],
26392639
resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
2640-
val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances
2641-
unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp))
2640+
unique(new PolyType(paramNames, variances)(paramBoundsExp, resultTypeExp))
26422641
}
26432642

26442643
def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
177177
varianceString(variance) ~ name.toString ~ toText(bounds)
178178
changePrec(GlobalPrec) {
179179
"[" ~ Text((tp.variances, tp.paramNames, tp.paramBounds).zipped.map(paramText), ", ") ~
180-
"] => " ~ toTextGlobal(tp.resultType)
180+
"]" ~ (" => " provided !tp.resultType.isInstanceOf[MethodType]) ~
181+
toTextGlobal(tp.resultType)
181182
}
182183
case tp: PolyParam =>
183184
polyParamNameString(tp) ~ polyHash(tp.binder)

compiler/src/dotty/tools/dotc/transform/FullParameterization.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ trait FullParameterization {
101101
}
102102
val ctparams = if (abstractOverClass) clazz.typeParams else Nil
103103
val ctnames = ctparams.map(_.name.unexpandedName)
104+
val ctvariances = ctparams.map(_.variance)
104105

105106
/** The method result type */
106107
def resultType(mapClassParams: Type => Type) = {
@@ -122,14 +123,14 @@ trait FullParameterization {
122123

123124
info match {
124125
case info: PolyType =>
125-
PolyType(info.paramNames ++ ctnames)(
126+
PolyType(info.paramNames ++ ctnames, info.variances ++ ctvariances)(
126127
pt =>
127128
(info.paramBounds.map(mapClassParams(_, pt).bounds) ++
128129
mappedClassBounds(pt)).mapConserve(_.subst(info, pt).bounds),
129130
pt => resultType(mapClassParams(_, pt)).subst(info, pt))
130131
case _ =>
131132
if (ctparams.isEmpty) resultType(identity)
132-
else PolyType(ctnames)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
133+
else PolyType(ctnames, ctvariances)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
133134
}
134135
}
135136

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,23 @@ object ErrorReporting {
111111
errorTree(tree, typeMismatchMsg(normalize(tree.tpe, pt), pt, implicitFailure.postscript))
112112

113113
/** A subtype log explaining why `found` does not conform to `expected` */
114-
def whyNoMatchStr(found: Type, expected: Type) =
115-
if (ctx.settings.explaintypes.value)
114+
def whyNoMatchStr(found: Type, expected: Type) = {
115+
def dropJavaMethod(tp: Type): Type = tp match {
116+
case tp: PolyType =>
117+
tp.derivedPolyType(resType = dropJavaMethod(tp.resultType))
118+
case tp: JavaMethodType =>
119+
MethodType(tp.paramNames, tp.paramTypes, dropJavaMethod(tp.resultType))
120+
case tp => tp
121+
}
122+
val found1 = dropJavaMethod(found)
123+
val expected1 = dropJavaMethod(expected)
124+
if ((found1 eq found) != (expected eq expected1) && (found1 <:< expected1))
125+
"\n (Note that Scala's and Java's representation of this type differs)"
126+
else if (ctx.settings.explaintypes.value)
116127
"\n" + ctx.typerState.show + "\n" + TypeComparer.explained((found <:< expected)(_))
117128
else
118129
""
130+
}
119131

120132
def typeMismatchMsg(found: Type, expected: Type, postScript: String = "") = {
121133
// replace constrained polyparams and their typevars by their bounds where possible

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ object Implicits {
220220
}
221221

222222
/** The result of an implicit search */
223-
abstract class SearchResult extends Showable {
223+
sealed abstract class SearchResult extends Showable {
224224
def toText(printer: Printer): Text = printer.toText(this)
225225
}
226226

tests/neg/i1747.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Coll[E] extends java.util.Collection[E] { // error: needs to be abstract
2+
def toArray[T](a: Array[T]): Array[T] = ??? // error: cannot override
3+
}

0 commit comments

Comments
 (0)