Skip to content

Commit af60377

Browse files
committed
Freeze constraints when checking parameter matching and subsumption.
Checking whether two alternatives are the same should not unify them by instantiating type variables.
1 parent f97865a commit af60377

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ trait ConstraintHandling {
2323
implicit val ctx: Context
2424

2525
protected def isSubType(tp1: Type, tp2: Type): Boolean
26+
protected def isSameType(tp1: Type, tp2: Type): Boolean
2627

2728
val state: TyperState
2829
import state.constraint
@@ -111,6 +112,13 @@ trait ConstraintHandling {
111112
finally frozenConstraint = saved
112113
}
113114

115+
final def isSameTypeWhenFrozen(tp1: Type, tp2: Type): Boolean = {
116+
val saved = frozenConstraint
117+
frozenConstraint = true
118+
try isSameType(tp1, tp2)
119+
finally frozenConstraint = saved
120+
}
121+
114122
/** Test whether the lower bounds of all parameters in this
115123
* constraint are a solution to the constraint.
116124
*/

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
686686
case formal1 :: rest1 =>
687687
formals2 match {
688688
case formal2 :: rest2 =>
689-
(isSameType(formal1, formal2)
689+
(isSameTypeWhenFrozen(formal1, formal2)
690690
|| isJava1 && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
691691
|| isJava2 && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
692692
matchingParams(rest1, rest2, isJava1, isJava2)
@@ -701,7 +701,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
701701
case formal1 :: rest1 =>
702702
formals2 match {
703703
case formal2 :: rest2 =>
704-
(isSubType(formal2, formal1)
704+
(isSubTypeWhenFrozen(formal2, formal1)
705705
|| isJava1 && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
706706
|| isJava2 && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
707707
subsumeParams(rest1, rest2, isJava1, isJava2)
@@ -1089,7 +1089,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
10891089
case tp1: ClassInfo =>
10901090
tp2 match {
10911091
case tp2: ClassInfo =>
1092-
isSubType(tp1.prefix, tp2.prefix) || (tp1.cls.owner derivesFrom tp2.cls.owner)
1092+
isSubTypeWhenFrozen(tp1.prefix, tp2.prefix) || (tp1.cls.owner derivesFrom tp2.cls.owner)
10931093
case _ =>
10941094
false
10951095
}
@@ -1105,7 +1105,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
11051105
tp2 match {
11061106
case tp2: MethodType =>
11071107
def asGoodParams(formals1: List[Type], formals2: List[Type]) =
1108-
(formals2 corresponds formals1)(isSubType)
1108+
(formals2 corresponds formals1)(isSubTypeWhenFrozen)
11091109
asGoodParams(tp1.paramTypes, tp2.paramTypes) &&
11101110
(!asGoodParams(tp2.paramTypes, tp1.paramTypes) ||
11111111
isAsGood(tp1.resultType, tp2.resultType))

0 commit comments

Comments
 (0)