Skip to content

Commit 760f27a

Browse files
committed
In instantiateToSubType, also infer the prefix of the approximated parent
1 parent 76b1805 commit 760f27a

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ object TypeOps:
701701
// `this`. We perform the following operations to approximate the parameters:
702702
//
703703
// 1. Replace type parameters in T with tvars
704-
// 2. Replace `A.this.C` with `A#C` (see tests/patmat/i12681.scala)
704+
// 2. Replace non-class applied types with a tvar, bounded by its type constructor's underlying type
705705
//
706706
val approximateParent = new TypeMap {
707707
val boundTypeParams = util.HashMap[TypeRef, TypeVar]()
@@ -710,9 +710,6 @@ object TypeOps:
710710
case _: MatchType =>
711711
tp // break cycles
712712

713-
case ThisType(tref: TypeRef) if !tref.symbol.isStaticOwner =>
714-
tref
715-
716713
case tp: TypeRef if !tp.symbol.isClass =>
717714
def lo = LazyRef.of(apply(tp.underlying.loBound))
718715
def hi = LazyRef.of(apply(tp.underlying.hiBound))
@@ -789,9 +786,12 @@ object TypeOps:
789786
}
790787
}
791788

792-
val inferThisMap = new InferPrefixMap
793-
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
794-
val protoTp1 = inferThisMap.apply(tp1).appliedTo(tvars)
789+
def inferPrefix(tp: Type) =
790+
val inferThisMap = new InferPrefixMap
791+
val tvars = tp.typeParams.map(tparam => newTypeVar(tparam.paramInfo.bounds))
792+
inferThisMap(tp).appliedTo(tvars)
793+
794+
val protoTp1 = inferPrefix(tp1)
795795

796796
// If parent contains a reference to an abstract type, then we should
797797
// refine subtype checking to eliminate abstract types according to
@@ -809,7 +809,7 @@ object TypeOps:
809809

810810
if (protoTp1 <:< tp2) instantiate()
811811
else {
812-
val approxTp2 = approximateParent(tp2)
812+
val approxTp2 = inferPrefix(approximateParent(tp2))
813813
if (protoTp1 <:< approxTp2 || parentQualify(protoTp1, approxTp2)) instantiate()
814814
else NoType
815815
}

tests/patmat/t6146.comb1.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Like the "tricksier" variantion in t6146, but less tricksy (less nesting)
2+
// but also with a non-Any type argument, and some invariant usage of the type.
3+
// Used to study why `case _: C.type =>` is considered unreachable
4+
// in the ordinal method object A synthesises.
5+
trait T[X] {
6+
sealed trait A
7+
object A {
8+
case object B extends A
9+
}
10+
11+
def give: X
12+
def take(x: X): X
13+
}
14+
15+
object O extends T[String] {
16+
def give = "O"
17+
def take(x: String) = s"$x. Love, O."
18+
}
19+
20+
case object C extends O.A

0 commit comments

Comments
 (0)