Skip to content

Commit 6843cb1

Browse files
committed
substitute instantiated dependent params
1 parent ac4f6e7 commit 6843cb1

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

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

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -357,17 +357,22 @@ final class ProperGadtConstraint private(
357357
tp.derivedAndOrType(loop(tp1), loop(tp2))
358358
case tp @ OrType(tp1, tp2) if isUpper =>
359359
tp.derivedOrType(loop(tp1), loop(tp2))
360-
case tp @ TypeRef(prefix, des) if prefix eq path =>
360+
case tp @ TypeRef(prefix, _) if prefix eq path =>
361361
typeMemberSymbols indexOf tp.symbol match
362362
case -1 => tp
363363
case idx => pt.paramRefs(idx)
364-
case tp @ TypeRef(_: RecThis, des) =>
364+
case tp @ TypeRef(_: RecThis, _) =>
365365
typeMemberSymbols indexOf tp.symbol match
366366
case -1 => tp
367367
case idx => pt.paramRefs(idx)
368368
case tp: TypeRef =>
369369
tvarOf(tp) match {
370-
case tv: TypeVar => tv.origin
370+
case tv: TypeVar =>
371+
val tp = stripInternalTypeVar(tv)
372+
tp.match {
373+
case tv1: TypeVar => stripTypeVarWhenDependent(tv1)
374+
case tp => tp
375+
}
371376
case null => tp
372377
}
373378
case tp => tp
@@ -450,7 +455,12 @@ final class ProperGadtConstraint private(
450455
params.indexOf(tp.symbol) match {
451456
case -1 =>
452457
mapping(tp.symbol) match {
453-
case tv: TypeVar => tv.origin
458+
case tv: TypeVar =>
459+
val tp = stripInternalTypeVar(tv)
460+
tp.match {
461+
case tv1: TypeVar => stripTypeVarWhenDependent(tv1)
462+
case tp => tp
463+
}
454464
case null => tp
455465
}
456466
case i => pt.paramRefs(i)
@@ -480,13 +490,22 @@ final class ProperGadtConstraint private(
480490
.showing(i"added to constraint: [$poly1] $params%, %\n$debugBoundsDescription", gadts)
481491
}
482492

493+
@annotation.tailrec private def stripInternalTypeVar(tp: Type): Type = tp match {
494+
case tv: TypeVar =>
495+
val inst = constraint.instType(tv)
496+
if (inst.exists) stripInternalTypeVar(inst) else tv
497+
case _ => tp
498+
}
499+
500+
private def stripTypeVarWhenDependent(tv: TypeVar): TypeParamRef | TypeVar =
501+
val tpr = tv.origin
502+
if constraint.contains(tpr) then
503+
tpr
504+
else
505+
tv
506+
end stripTypeVarWhenDependent
507+
483508
private def addBoundForTvar(tvar: TypeVar, bound: Type, isUpper: Boolean, typeRepr: String)(using Context): Boolean = {
484-
@annotation.tailrec def stripInternalTypeVar(tp: Type): Type = tp match {
485-
case tv: TypeVar =>
486-
val inst = constraint.instType(tv)
487-
if (inst.exists) stripInternalTypeVar(inst) else tv
488-
case _ => tp
489-
}
490509

491510
val symTvar: TypeVar = stripInternalTypeVar(tvar) match {
492511
case tv: TypeVar => tv

tests/pos/gadt-dep-param.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
enum Tup[A, B]:
2+
case Data[A, B]() extends Tup[A, B]
3+
4+
def foo1[A, B](e: Tup[A, B]) = e.match {
5+
case _: Tup.Data[a, b] =>
6+
def bar[C >: a <: b, D]() =
7+
val t1: b = ??? : a
8+
}
9+
10+
def foo2[A, B, C >: A <: B]() =
11+
val t1: B = ??? : A
12+

0 commit comments

Comments
 (0)