Skip to content

Commit 65d4dcc

Browse files
committed
eliminate type reference in bounds for tvars in child instantiation
1 parent fecb6d0 commit 65d4dcc

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -604,17 +604,19 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
604604
def childTypeMap(implicit ctx: Context) = new TypeMap {
605605
def apply(t: Type): Type = t.dealias match {
606606
case tp @ ThisType(tref) if !tref.symbol.isStaticOwner =>
607-
if (tref.symbol.is(Module)) mapOver(tref)
607+
if (tref.symbol.is(Module)) this(tref)
608608
else newTypeVar(TypeBounds.upper(tp.underlying))
609+
609610
case tp: TypeRef if tp.underlying.isInstanceOf[TypeBounds] =>
610-
// Note that the logic for contra- and co-variance is reverse of `typeParamMap`
611+
// Note that the logic for contra- and co-variance is reverse of `parentTypeMap`
611612
// This is because we are checking the possibility of `tp1 <:< tp2`, thus we should
612613
// minimize `tp1` while maximize `tp2`. See tests/patmat/3645b.scala
614+
val lo = tp.underlying.loBound
615+
val hi = tp.underlying.hiBound
613616
val exposed =
614-
if (variance == 0) newTypeVar(tp.underlying.bounds)
615-
else if (variance == 1) mapOver(tp.underlying.loBound)
616-
else mapOver(tp.underlying.hiBound)
617-
617+
if (variance == 0) newTypeVar(TypeBounds(this(lo), this(hi)))
618+
else if (variance == 1) this(lo)
619+
else this(hi)
618620
debug.println(s"$tp exposed to =====> $exposed")
619621
exposed
620622
case _ =>
@@ -627,10 +629,12 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
627629
def apply(t: Type): Type = t.dealias match {
628630
case tp: TypeRef if tp.underlying.isInstanceOf[TypeBounds] =>
629631
// See tests/patmat/gadt.scala tests/patmat/exhausting.scala tests/patmat/t9657.scala
632+
val lo = tp.underlying.loBound
633+
val hi = tp.underlying.hiBound
630634
val exposed =
631-
if (variance == 0) newTypeVar(tp.underlying.bounds)
632-
else if (variance == 1) mapOver(tp.underlying.hiBound)
633-
else mapOver(tp.underlying.loBound)
635+
if (variance == 0) newTypeVar(TypeBounds(this(lo), this(hi)))
636+
else if (variance == 1) this(hi)
637+
else this(lo)
634638

635639
debug.println(s"$tp exposed to =====> $exposed")
636640
exposed

tests/patmat/i3645e.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
29: Pattern Match Exhaustivity: K1

tests/patmat/i3645e.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
object App {
2+
def main(args: Array[String]): Unit = {
3+
trait ModuleSig {
4+
type Upper
5+
6+
trait FooSig {
7+
type Type <: Upper
8+
def subst[F[_]](fa: F[Int]): F[Type]
9+
}
10+
11+
val Foo: FooSig
12+
}
13+
val Module: ModuleSig = new ModuleSig {
14+
type Upper = Int
15+
16+
val Foo: FooSig = new FooSig {
17+
type Type = Int
18+
def subst[F[_]](fa: F[Int]): F[Type] = fa
19+
}
20+
}
21+
type Upper = Module.Upper
22+
type Foo = Module.Foo.Type
23+
24+
sealed abstract class K[F]
25+
final case object K1 extends K[Int]
26+
final case object K2 extends K[Foo]
27+
28+
val kv: K[Foo] = Module.Foo.subst[K](K1)
29+
def test(k: K[Foo]): Unit = k match {
30+
case K2 => ()
31+
}
32+
33+
test(kv)
34+
}
35+
}

0 commit comments

Comments
 (0)