Skip to content

Commit 486b029

Browse files
authored
Merge pull request #1893 from dotty-staging/fix-#1891
Fix #1891: Don't add redundant constraint
2 parents d62a2c9 + 918a3fb commit 486b029

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ trait ConstraintHandling {
5757
b match {
5858
case b: AndOrType => occursIn(b.tp1) || occursIn(b.tp2)
5959
case b: TypeVar => occursIn(b.origin)
60+
case b: TermRef => occursIn(b.underlying)
6061
case _ => false
6162
}
6263
}

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,22 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
375375
thirdTryNamed(tp1, tp2)
376376
case tp2: PolyParam =>
377377
def comparePolyParam =
378-
(ctx.mode is Mode.TypevarsMissContext) ||
379-
isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || {
378+
(ctx.mode is Mode.TypevarsMissContext) || {
379+
val alwaysTrue =
380+
// The following condition is carefully formulated to catch all cases
381+
// where the subtype relation is true without needing to add a constraint
382+
// It's tricky because we might need to either appriximate tp2 by its
383+
// lower bound or else widen tp1 and check that the result is a subtype of tp2.
384+
// So if the constraint is not yet frozen, we do the same comparison again
385+
// with a frozen constraint, which means that we get a chance to do the
386+
// widening in `fourthTry` before adding to the constraint.
387+
if (frozenConstraint || alwaysFluid) isSubType(tp1, bounds(tp2).lo)
388+
else isSubTypeWhenFrozen(tp1, tp2)
389+
alwaysTrue || {
380390
if (canConstrain(tp2)) addConstraint(tp2, tp1.widenExpr, fromBelow = true)
381391
else fourthTry(tp1, tp2)
382392
}
393+
}
383394
comparePolyParam
384395
case tp2: RefinedType =>
385396
def compareRefinedSlow: Boolean = {

tests/pos/i1891.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object Test {
2+
class CC2[A, B](a: A, b: B)
3+
4+
type T2[A, B] = CC2[A, B]
5+
6+
class ArrowAssoc[A](val self: A) {
7+
@inline def f[B](y: B): CC2[A, B] = new CC2(self, y)
8+
}
9+
10+
def foo = (new ArrowAssoc(1)).f(2)
11+
}

0 commit comments

Comments
 (0)