Skip to content

Commit 3d3ed97

Browse files
authored
Merge pull request #4946 from dotty-staging/fix-4720-4721-account-for-smarter-type-inference
Fix #4720 and #4721: account for type inference being too smart
2 parents 05e27f3 + 69957bb commit 3d3ed97

File tree

9 files changed

+35
-20
lines changed

9 files changed

+35
-20
lines changed

compiler/src/dotty/tools/dotc/ast/Positioned.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ abstract class Positioned extends DotClass with Product {
3434
* destructively and the item itself is returned.
3535
*/
3636
def withPos(pos: Position): this.type = {
37-
val newpd = (if (pos == curPos || curPos.isSynthetic) this else clone).asInstanceOf[Positioned]
37+
val newpd = (if (pos == curPos || curPos.isSynthetic) this else clone.asInstanceOf[Positioned])
3838
newpd.setPos(pos)
3939
newpd.asInstanceOf[this.type]
4040
}

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ object Config {
5858
/** Type comparer will fail with an assert if the upper bound
5959
* of a constrained parameter becomes Nothing. This should be turned
6060
* on only for specific debugging as normally instantiation to Nothing
61-
* is not an error consdition.
61+
* is not an error condition.
6262
*/
6363
final val failOnInstantiationToNothing = false
6464

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ abstract class Constraint extends Showable {
6060
* are not contained in the return bounds.
6161
* @pre `param` is not part of the constraint domain.
6262
*/
63-
def nonParamBounds(param: TypeParamRef): TypeBounds
63+
def nonParamBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds
6464

6565
/** The lower bound of `param` including all known-to-be-smaller parameters */
6666
def fullLowerBound(param: TypeParamRef)(implicit ctx: Context): Type

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

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -341,19 +341,22 @@ trait ConstraintHandling {
341341
* and propagate all bounds.
342342
* @param tvars See Constraint#add
343343
*/
344-
def addToConstraint(tl: TypeLambda, tvars: List[TypeVar]): Unit =
345-
assert {
346-
checkPropagated(i"initialized $tl") {
347-
constraint = constraint.add(tl, tvars)
348-
tl.paramNames.indices.forall { i =>
349-
val param = tl.paramRefs(i)
350-
val bounds = constraint.nonParamBounds(param)
351-
val lower = constraint.lower(param)
352-
val upper = constraint.upper(param)
353-
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
354-
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $tl")
355-
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
356-
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
344+
def addToConstraint(tl: TypeLambda, tvars: List[TypeVar]): Boolean =
345+
checkPropagated(i"initialized $tl") {
346+
constraint = constraint.add(tl, tvars)
347+
tl.paramRefs.forall { param =>
348+
constraint.entry(param) match {
349+
case bounds: TypeBounds =>
350+
val lower = constraint.lower(param)
351+
val upper = constraint.upper(param)
352+
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
353+
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $tl")
354+
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
355+
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
356+
case _ =>
357+
// Happens if param was already solved while processing earlier params of the same TypeLambda.
358+
// See #4720.
359+
true
357360
}
358361
}
359362
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
191191
def isLess(param1: TypeParamRef, param2: TypeParamRef): Boolean =
192192
upper(param1).contains(param2)
193193

194-
def nonParamBounds(param: TypeParamRef): TypeBounds =
195-
entry(param).asInstanceOf[TypeBounds]
194+
def nonParamBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds =
195+
entry(param).bounds
196196

197197
def fullLowerBound(param: TypeParamRef)(implicit ctx: Context): Type =
198198
(nonParamBounds(param).lo /: minLower(param))(_ | _)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,10 @@ object ProtoTypes {
457457
s"inconsistent: no typevars were added to committable constraint ${state.constraint}")
458458

459459
def newTypeVars(tl: TypeLambda): List[TypeTree] =
460-
for (n <- (0 until tl.paramNames.length).toList)
460+
for (paramRef <- tl.paramRefs)
461461
yield {
462462
val tt = new TypeVarBinder().withPos(owningTree.pos)
463-
val tvar = new TypeVar(tl.paramRefs(n), state)
463+
val tvar = new TypeVar(paramRef, state)
464464
state.ownedVars += tvar
465465
tt.withType(tvar)
466466
}

tests/neg/i4721.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test {
2+
def main(args: Array[String]):Unit = m(1) // error
3+
def m[Y<:String, Z>:Int, W>:Z<:Y](d:Y):Unit={}
4+
}

tests/neg/i4721a.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test {
2+
def main(args: Array[String]):Unit = m("1") // error
3+
def m[Y<:String, Z>:Int, W>:Z<:Y](d:Y):Unit={}
4+
}

tests/pos/i4720.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test {
2+
def main(args: Array[String]):Unit = m(1)
3+
def m[Y<:Int, Z>:Int, W>:Z<:Y](d:Y):Unit={}
4+
}

0 commit comments

Comments
 (0)