Skip to content

Commit 907f9fe

Browse files
authored
Merge pull request #351 from scala/backport-lts-3.3-22928
Backport "Fix existing GADT constraints with introduced pattern-bound symbols" to 3.3 LTS
2 parents 844dff3 + 1d5c8d1 commit 907f9fe

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

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

+15
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ class GadtConstraint private (
3333
reverseMapping = reverseMapping.updated(tv.origin, sym),
3434
)
3535

36+
def replace(param: TypeParamRef, tp: Type)(using Context) =
37+
var constr = constraint
38+
for
39+
poly <- constraint.domainLambdas
40+
paramRef <- poly.paramRefs
41+
do
42+
val entry0 = constr.entry(paramRef)
43+
val entry1 = entry0.substParam(param, tp)
44+
if entry1 ne entry0 then
45+
constr = constr.updateEntry(paramRef, entry1)
46+
withConstraint(constr)
47+
3648
/** Is `sym1` ordered to be less than `sym2`? */
3749
def isLess(sym1: Symbol, sym2: Symbol)(using Context): Boolean =
3850
constraint.isLess(tvarOrError(sym1).origin, tvarOrError(sym2).origin)
@@ -241,6 +253,9 @@ sealed trait GadtState {
241253
result
242254
}
243255

256+
def replace(param: TypeParamRef, tp: Type)(using Context) =
257+
gadt = gadt.replace(param, tp)
258+
244259
/** See [[ConstraintHandling.approximation]] */
245260
def approximation(sym: Symbol, fromBelow: Boolean, maxLevel: Int = Int.MaxValue)(using Context): Type = {
246261
approximation(gadt.tvarOrError(sym).origin, fromBelow, maxLevel).match

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,15 @@ object Inferencing {
442442
}
443443
}
444444
}
445-
val res = patternBindings.toList.map { (boundSym, _) =>
445+
val res = patternBindings.toList.map { (boundSym, origin) =>
446446
// substitute bounds of pattern bound variables to deal with possible F-bounds
447447
for (wildCard, param) <- patternBindings do
448448
boundSym.info = boundSym.info.substParam(param, wildCard.typeRef)
449+
450+
// also substitute in any GADT bounds
451+
// e.g. in i22879, replace the `T` in `X <: Iterable[T]` with the pattern bound `T$1`
452+
ctx.gadtState.replace(origin, boundSym.typeRef)
453+
449454
boundSym
450455
}
451456

tests/pos/i22879.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sealed trait E[S]
2+
final case class I[T, U <: Iterable[T]]() extends E[U]
3+
class Test {
4+
def test[X](a: E[X]): Unit = {
5+
a match {
6+
case I() => ???
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)