Skip to content

Commit f68e3be

Browse files
oderskyallanrenucci
authored andcommitted
Fix matchtype redux caching
- Fix isUptoDate conditon - Include TypeVars in footprint
1 parent ceef996 commit f68e3be

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
108108
protected def gadtBounds(sym: Symbol)(implicit ctx: Context) = ctx.gadt.bounds(sym)
109109
protected def gadtSetBounds(sym: Symbol, b: TypeBounds) = ctx.gadt.setBounds(sym, b)
110110

111+
protected def typeVarInstance(tvar: TypeVar)(implicit ctx: Context) = tvar.underlying
112+
111113
// Subtype testing `<:<`
112114

113115
def topLevelSubType(tp1: Type, tp2: Type): Boolean = {
@@ -233,7 +235,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
233235
case tp2: BoundType =>
234236
tp2 == tp1 || secondTry
235237
case tp2: TypeVar =>
236-
recur(tp1, tp2.underlying)
238+
recur(tp1, typeVarInstance(tp2))
237239
case tp2: WildcardType =>
238240
def compareWild = tp2.optBounds match {
239241
case TypeBounds(_, hi) => recur(tp1, hi)
@@ -348,7 +350,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
348350
case _ => thirdTry
349351
}
350352
case tp1: TypeVar =>
351-
recur(tp1.underlying, tp2)
353+
recur(typeVarInstance(tp1), tp2)
352354
case tp1: WildcardType =>
353355
def compareWild = tp1.optBounds match {
354356
case bounds: TypeBounds => recur(bounds.lo, tp2)
@@ -1828,6 +1830,11 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
18281830
super.gadtSetBounds(sym, b)
18291831
}
18301832

1833+
override def typeVarInstance(tvar: TypeVar)(implicit ctx: Context) = {
1834+
footprint += tvar
1835+
super.typeVarInstance(tvar)
1836+
}
1837+
18311838
def matchCase(scrut: Type, cas: Type, instantiate: Boolean)(implicit ctx: Context): Type = {
18321839

18331840
def paramInstances = new TypeAccumulator[Array[Type]] {

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

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,7 +3598,7 @@ object Types {
35983598
def underlying(implicit ctx: Context): Type = bound
35993599

36003600
private[this] var myReduced: Type = null
3601-
private[this] var reductionContext: mutable.Map[Type, TypeBounds] = null
3601+
private[this] var reductionContext: mutable.Map[Type, Type] = null
36023602

36033603
override def tryNormalize(implicit ctx: Context): Type = reduced.normalized
36043604

@@ -3634,38 +3634,41 @@ object Types {
36343634
}
36353635
}
36363636

3637-
def isRelevant(tp: Type) = tp match {
3638-
case tp: TypeParamRef => ctx.typerState.constraint.entry(tp).exists
3637+
def isBounded(tp: Type) = tp match {
3638+
case tp: TypeParamRef =>
36393639
case tp: TypeRef => ctx.gadt.bounds.contains(tp.symbol)
36403640
}
36413641

3642-
def contextBounds(tp: Type): TypeBounds = tp match {
3643-
case tp: TypeParamRef => ctx.typerState.constraint.fullBounds(tp)
3644-
case tp: TypeRef => ctx.gadt.bounds(tp.symbol)
3642+
def contextInfo(tp: Type): Type = tp match {
3643+
case tp: TypeParamRef =>
3644+
val constraint = ctx.typerState.constraint
3645+
if (constraint.entry(tp).exists) constraint.fullBounds(tp)
3646+
else NoType
3647+
case tp: TypeRef =>
3648+
val bounds = ctx.gadt.bounds(tp.symbol)
3649+
if (bounds == null) NoType else bounds
3650+
case tp: TypeVar =>
3651+
tp.underlying
36453652
}
36463653

36473654
def updateReductionContext() = {
36483655
reductionContext = new mutable.HashMap
3649-
for (tp <- cmp.footprint if isRelevant(tp))
3650-
reductionContext(tp) = contextBounds(tp)
3656+
for (tp <- cmp.footprint)
3657+
reductionContext(tp) = contextInfo(tp)
3658+
typr.println(i"footprint for $this $hashCode: ${cmp.footprint.toList.map(x => (x, contextInfo(x)))}%, %")
36513659
}
36523660

36533661
def upToDate =
3654-
cmp.footprint.forall { tp =>
3655-
!isRelevant(tp) || {
3656-
reductionContext.get(tp) match {
3657-
case Some(bounds) => bounds `eq` contextBounds(tp)
3658-
case None => false
3659-
}
3660-
}
3662+
reductionContext.keysIterator.forall { tp =>
3663+
reductionContext(tp) `eq` contextInfo(tp)
36613664
}
36623665

36633666
record("MatchType.reduce called")
36643667
if (!Config.cacheMatchReduced || myReduced == null || !upToDate) {
36653668
record("MatchType.reduce computed")
36663669
if (myReduced != null) record("MatchType.reduce cache miss")
36673670
myReduced =
3668-
trace(i"reduce match type $this", typr, show = true) {
3671+
trace(i"reduce match type $this $hashCode", typr, show = true) {
36693672
try
36703673
if (defn.isBottomType(scrutinee)) defn.NothingType
36713674
else if (reduceInParallel) reduceParallel(trackingCtx)

tests/pos/matchtype.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ object Test {
6565
checkSame[Concat[(Boolean, Boolean), (String, Int)], Boolean *: Boolean *: (String, Int)]
6666
checkSub[(Boolean, Boolean, String, Int), Concat[(Boolean, Boolean), String *: Int *: Unit]]
6767

68-
inline def index[Xs <: NonEmptyTuple](xs: Xs, n: Int): Elem[Xs, n.type] = xs(n).asInstanceOf
68+
def index[Xs <: NonEmptyTuple](xs: Xs, n: Int): Elem[Xs, n.type] = xs(n).asInstanceOf
6969

7070
val test = (1, "hi", true, 2.0)
7171
index(test, 0): Int

0 commit comments

Comments
 (0)