Skip to content

Commit d1cb044

Browse files
committed
eliminate type reference in bounds for tvars in child instantiation
1 parent 9d66791 commit d1cb044

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
@@ -585,17 +585,19 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
585585
def childTypeMap(implicit ctx: Context) = new TypeMap {
586586
def apply(t: Type): Type = t.dealias match {
587587
case tp @ ThisType(tref) if !tref.symbol.isStaticOwner =>
588-
if (tref.symbol.is(Module)) mapOver(tref)
588+
if (tref.symbol.is(Module)) this(tref)
589589
else newTypeVar(TypeBounds.upper(tp.underlying))
590+
590591
case tp: TypeRef if tp.underlying.isInstanceOf[TypeBounds] =>
591-
// Note that the logic for contra- and co-variance is reverse of `typeParamMap`
592+
// Note that the logic for contra- and co-variance is reverse of `parentTypeMap`
592593
// This is because we are checking the possibility of `tp1 <:< tp2`, thus we should
593594
// minimize `tp1` while maximize `tp2`. See tests/patmat/3645b.scala
595+
val lo = tp.underlying.loBound
596+
val hi = tp.underlying.hiBound
594597
val exposed =
595-
if (variance == 0) newTypeVar(tp.underlying.bounds)
596-
else if (variance == 1) mapOver(tp.underlying.loBound)
597-
else mapOver(tp.underlying.hiBound)
598-
598+
if (variance == 0) newTypeVar(TypeBounds(this(lo), this(hi)))
599+
else if (variance == 1) this(lo)
600+
else this(hi)
599601
debug.println(s"$tp exposed to =====> $exposed")
600602
exposed
601603
case _ =>
@@ -608,10 +610,12 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
608610
def apply(t: Type): Type = t.dealias match {
609611
case tp: TypeRef if tp.underlying.isInstanceOf[TypeBounds] =>
610612
// See tests/patmat/gadt.scala tests/patmat/exhausting.scala tests/patmat/t9657.scala
613+
val lo = tp.underlying.loBound
614+
val hi = tp.underlying.hiBound
611615
val exposed =
612-
if (variance == 0) newTypeVar(tp.underlying.bounds)
613-
else if (variance == 1) mapOver(tp.underlying.hiBound)
614-
else mapOver(tp.underlying.loBound)
616+
if (variance == 0) newTypeVar(TypeBounds(this(lo), this(hi)))
617+
else if (variance == 1) this(hi)
618+
else this(lo)
615619

616620
debug.println(s"$tp exposed to =====> $exposed")
617621
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)