Skip to content

Commit 8dcd9aa

Browse files
committed
record pattern path
1 parent 2157a45 commit 8dcd9aa

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

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

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ sealed abstract class GadtConstraint extends Showable {
7373
/** Set the scrutinee path. */
7474
def withScrutineePath[T](path: TermRef | Null)(op: => T): T
7575

76+
/** Supply the real pattern path. */
77+
def supplyPatternPath(path: TermRef)(using Context): Unit
78+
79+
/** Create a skolem type for pattern. */
80+
def createPatternSkolem(pat: Type): SkolemType
81+
7682
/** Is the symbol registered in the constraint?
7783
*
7884
* @note this is true even if the symbol is constrained to be equal to another type, unlike [[Constraint.contains]].
@@ -114,7 +120,8 @@ final class ProperGadtConstraint private(
114120
private var pathDepReverseMapping: SimpleIdentityMap[TypeParamRef, TypeRef],
115121
private var wasConstrained: Boolean,
116122
private var myScrutineePath: TermRef | Null,
117-
private var myUnionFind: SimpleIdentityMap[PathType, PathType]
123+
private var myUnionFind: SimpleIdentityMap[PathType, PathType],
124+
private var myPatternSkolem: SkolemType | Null,
118125
) extends GadtConstraint with ConstraintHandling {
119126
import dotty.tools.dotc.config.Printers.{gadts, gadtsConstr}
120127

@@ -126,7 +133,8 @@ final class ProperGadtConstraint private(
126133
pathDepReverseMapping = SimpleIdentityMap.empty,
127134
wasConstrained = false,
128135
myScrutineePath = null,
129-
myUnionFind = SimpleIdentityMap.empty
136+
myUnionFind = SimpleIdentityMap.empty,
137+
myPatternSkolem = null,
130138
)
131139

132140
// /** Exposes ConstraintHandling.subsumes */
@@ -672,7 +680,8 @@ final class ProperGadtConstraint private(
672680
pathDepReverseMapping,
673681
wasConstrained,
674682
myScrutineePath,
675-
myUnionFind
683+
myUnionFind,
684+
myPatternSkolem,
676685
)
677686

678687
def restore(other: GadtConstraint): Unit = other match {
@@ -685,17 +694,40 @@ final class ProperGadtConstraint private(
685694
this.wasConstrained = other.wasConstrained
686695
this.myScrutineePath = other.myScrutineePath
687696
this.myUnionFind = other.myUnionFind
697+
this.myPatternSkolem = other.myPatternSkolem
688698
case _ => ;
689699
}
690700

691701
override def scrutineePath: TermRef | Null = myScrutineePath
692702

693703
override def resetScrutineePath(): Unit = myScrutineePath = null
694704

705+
override def supplyPatternPath(path: TermRef)(using Context): Unit =
706+
if myPatternSkolem eq null then
707+
()
708+
else
709+
pathDepMapping(myPatternSkolem.nn) match {
710+
case null =>
711+
case m: SimpleIdentityMap[Symbol, TypeVar] =>
712+
pathDepMapping = pathDepMapping.updated(path, m)
713+
m foreachBinding { (sym, tvar) =>
714+
val tpr = tvar.origin
715+
pathDepReverseMapping = pathDepReverseMapping.updated(tpr, TypeRef(path, sym))
716+
}
717+
}
718+
end supplyPatternPath
719+
720+
override def createPatternSkolem(pat: Type): SkolemType =
721+
myPatternSkolem = SkolemType(pat)
722+
myPatternSkolem.nn
723+
end createPatternSkolem
724+
695725
override def withScrutineePath[T](path: TermRef | Null)(op: => T): T =
696726
val saved = this.myScrutineePath
697727
this.myScrutineePath = path
728+
698729
val result = op
730+
699731
this.myScrutineePath = saved
700732
result
701733

@@ -827,6 +859,10 @@ final class ProperGadtConstraint private(
827859

828860
override def withScrutineePath[T](path: TermRef | Null)(op: => T): T = op
829861

862+
override def supplyPatternPath(path: TermRef)(using Context): Unit = ()
863+
864+
override def createPatternSkolem(pat: Type): SkolemType = unsupported("EmptyGadtConstraint.createPatternSkolem")
865+
830866
override def fresh = new ProperGadtConstraint
831867
override def restore(other: GadtConstraint): Unit =
832868
assert(!other.isNarrowing, "cannot restore a non-empty GADTMap")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ trait PatternTypeConstrainer { self: TypeComparer =>
184184
val scrutineePath: TermRef | SkolemType = realScrutineePath match
185185
case null => SkolemType(scrut)
186186
case _ => realScrutineePath
187-
val patternPath: SkolemType = SkolemType(pat)
187+
val patternPath: SkolemType = ctx.gadt.createPatternSkolem(pat)
188188

189189
val saved = state.nn.constraint
190190
val savedGadt = ctx.gadt.fresh

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
17771777
val pat1 = gadtCtx.gadt.withScrutineePath(scrutineePath) {
17781778
typedPattern(tree.pat, wideSelType)(using gadtCtx)
17791779
}
1780+
1781+
if scrutineePath.ne(null) && pat1.symbol.isPatternBound then
1782+
gadtCtx.gadt.supplyPatternPath(pat1.symbol.termRef)
1783+
17801784
caseRest(pat1)(
17811785
using Nullables.caseContext(sel, pat1)(
17821786
using gadtCtx))

0 commit comments

Comments
 (0)