Skip to content

Commit fc2244e

Browse files
authored
fix(patmat): Add subtype-based fallback in inferPrefixMap and recalculate constraints after application (#23771)
fix #23369 1. Add fallback logic in inferPrefixMap that uses subtype relationships to find a singleton when an exact match cannot be found 2. Ensure that constraints are calculated after applying inferPrefixMap
2 parents 69e97e9 + 4fd7a90 commit fc2244e

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,13 @@ object TypeOps:
830830
prefixTVar.uncheckedNN
831831
case ThisType(tref) if !tref.symbol.isStaticOwner =>
832832
val symbol = tref.symbol
833+
val compatibleSingleton = singletons.valuesIterator.find(_.underlying.derivesFrom(symbol))
833834
if singletons.contains(symbol) then
834835
prefixTVar = singletons(symbol) // e.g. tests/pos/i16785.scala, keep Outer.this
835836
prefixTVar.uncheckedNN
837+
else if compatibleSingleton.isDefined then
838+
prefixTVar = compatibleSingleton.get
839+
prefixTVar.uncheckedNN
836840
else if symbol.is(Module) then
837841
TermRef(this(tref.prefix), symbol.sourceModule)
838842
else if (prefixTVar != null)
@@ -930,10 +934,11 @@ object TypeOps:
930934
}
931935

932936
val inferThisMap = new InferPrefixMap
933-
val tvars = tp1.etaExpand match
937+
val prefixInferredTp = inferThisMap(tp1)
938+
val tvars = prefixInferredTp.etaExpand match
934939
case eta: TypeLambda => constrained(eta)
935940
case _ => Nil
936-
val protoTp1 = inferThisMap.apply(tp1).appliedTo(tvars)
941+
val protoTp1 = prefixInferredTp.appliedTo(tvars)
937942

938943
if gadtSyms.nonEmpty then
939944
ctx.gadtState.addToConstraint(gadtSyms)

tests/warn/i23369.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Module {
2+
type BarTy
3+
sealed trait Adt[A]
4+
case class Foo() extends Adt[String]
5+
case class Bar[A <: BarTy](x: BarTy) extends Adt[A]
6+
}
7+
8+
object Basic extends Module {
9+
type BarTy = String
10+
}
11+
12+
def test(a: Basic.Adt[String]) = {
13+
a match { // warn: match may not be exhaustive
14+
case Basic.Foo() =>
15+
}
16+
}
17+
18+
object Basic2 extends Module {
19+
type BarTy = Int
20+
}
21+
22+
def test2(a: Basic2.Adt[String]) = {
23+
a match {
24+
case Basic2.Foo() =>
25+
}
26+
}

0 commit comments

Comments
 (0)