Skip to content

Commit ebf01a4

Browse files
committed
Fix how intersected bounds are added to Constaint
1 parent ef653b6 commit ebf01a4

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,12 +861,24 @@ trait ConstraintHandling {
861861
addConstraintInvocations += 1
862862
val saved = canWidenAbstract
863863
canWidenAbstract = true
864-
try bound match
864+
865+
def contains(bound: Type) = bound match
866+
case tpr: TypeParamRef => constraint.contains(tpr)
867+
case tv: TypeVar => constraint.contains(tv)
868+
case _ => false
869+
870+
def add(bound: Type): Boolean = bound match
871+
case AndType(bound1, bound2) if contains(bound1) || contains(bound2) =>
872+
add(bound1) && add(bound2)
865873
case bound: TypeParamRef if constraint contains bound =>
866874
addParamBound(bound)
875+
case bound: TypeVar if constraint.contains(bound) =>
876+
addParamBound(bound.origin)
867877
case _ =>
868878
val pbound = avoidLambdaParams(bound)
869879
kindCompatible(param, pbound) && addBoundTransitively(param, pbound, !fromBelow)
880+
881+
try add(bound)
870882
finally
871883
canWidenAbstract = saved
872884
addConstraintInvocations -= 1

compiler/test/dotty/tools/dotc/core/ConstraintsTest.scala

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package dotty.tools
2-
package dotc.core
2+
package dotc
3+
package core
34

45
import vulpix.TestConfiguration
56

6-
import dotty.tools.dotc.core.Contexts.{*, given}
7-
import dotty.tools.dotc.core.Decorators.{*, given}
8-
import dotty.tools.dotc.core.Symbols.*
9-
import dotty.tools.dotc.core.Types.*
10-
import dotty.tools.dotc.ast.tpd.*
11-
import dotty.tools.dotc.typer.ProtoTypes.constrained
7+
import Contexts.{*, given}, Decorators.{*, given}, Symbols.*, Types.*
8+
import ast.tpd.*
9+
import typer.ProtoTypes.*
10+
import util.SimpleIdentitySet
1211

1312
import org.junit.Test
1413

15-
import dotty.tools.DottyTest
16-
1714
class ConstraintsTest:
1815

1916
@Test def mergeParamsTransitivity: Unit =
@@ -91,3 +88,19 @@ class ConstraintsTest:
9188
assert(!ctx.typerState.constraint.occursAtToplevel(tvar.origin, entry),
9289
i"cyclic bound for ${tvar.origin}: ${entry} in ${ctx.typerState.constraint}")
9390
}
91+
92+
@Test def splitIntersectedBounds: Unit = inCompilerContext(TestConfiguration.basicClasspath) {
93+
val Foo = newTypeVar(TypeBounds.empty, "Foo".toTypeName)
94+
val Bar = newTypeVar(TypeBounds.empty, "Bar".toTypeName)
95+
val Int = defn.IntType
96+
97+
val tp1 = Foo & Int
98+
val tp2 = Bar & Int
99+
val log = TypeComparer.explained(_.isSameType(tp1, tp2))
100+
//println(i"$log")
101+
//println(i"${ctx.typerState.constraint}")
102+
103+
val tree = ref(newAnonFun(defn.RootClass, MethodType(Nil, defn.UnitType))).appliedToNone
104+
ctx.typer.interpolateTypeVars(tree, WildcardType, SimpleIdentitySet.empty)
105+
assert(Foo =:= Int && Bar =:= Int, i"Foo=$Foo Bar=$Bar")
106+
}

0 commit comments

Comments
 (0)