Skip to content

Commit cc1e37e

Browse files
committed
Add GADT symbols when typing typing-ahead lambda bodies
1 parent 641ab7a commit cc1e37e

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1733,8 +1733,14 @@ class Namer { typer: Typer =>
17331733
val tpe = (paramss: @unchecked) match
17341734
case TypeSymbols(tparams) :: TermSymbols(vparams) :: Nil => tpFun(tparams, vparams)
17351735
case TermSymbols(vparams) :: Nil => tpFun(Nil, vparams)
1736+
val rhsCtx = (paramss: @unchecked) match
1737+
case TypeSymbols(tparams) :: TermSymbols(_) :: Nil =>
1738+
val rhsCtx = ctx.fresh.setFreshGADTBounds
1739+
rhsCtx.gadtState.addToConstraint(tparams)
1740+
rhsCtx
1741+
case TermSymbols(_) :: Nil => ctx
17361742
if (isFullyDefined(tpe, ForceDegree.none)) tpe
1737-
else typedAheadExpr(mdef.rhs, tpe).tpe
1743+
else typedAheadExpr(mdef.rhs, tpe)(using rhsCtx).tpe
17381744

17391745
case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) =>
17401746
mdef match {

tests/pos/i19570.min1.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
enum Op[A]:
2+
case Dup[T]() extends Op[(T, T)]
3+
4+
def foo[R](f: [A] => Op[A] => R): R = ???
5+
6+
def test =
7+
foo([A] => (o: Op[A]) => o match
8+
case o: Op.Dup[u] =>
9+
summon[A =:= (u, u)] // Error: Cannot prove that A =:= (u, u)
10+
()
11+
)
12+
foo[Unit]([A] => (o: Op[A]) => o match
13+
case o: Op.Dup[u] =>
14+
summon[A =:= (u, u)] // Ok
15+
()
16+
)
17+
foo({
18+
val f1 = [B] => (o: Op[B]) => o match
19+
case o: Op.Dup[u] =>
20+
summon[B =:= (u, u)] // Also ok
21+
()
22+
f1
23+
})

tests/pos/i19570.min2.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
sealed trait Op[A, B] { def giveA: A; def giveB: B }
2+
final case class Dup[T](x: T) extends Op[T, (T, T)] { def giveA: T = x; def giveB: (T, T) = (x, x) }
3+
4+
class Test:
5+
def foo[R](f: [A, B] => (o: Op[A, B]) => R): R = ???
6+
7+
def m1: Unit =
8+
foo([A, B] => (o: Op[A, B]) => o match
9+
case o: Dup[t] =>
10+
var a1: t = o.giveA
11+
var a2: A = o.giveA
12+
a1 = a2
13+
a2 = a1
14+
15+
var b1: (t, t) = o.giveB
16+
var b2: B = o.giveB
17+
b1 = b2
18+
b2 = b1
19+
20+
summon[A =:= t] // ERROR: Cannot prove that A =:= t.
21+
summon[B =:= (t, t)] // ERROR: Cannot prove that B =:= (t, t).
22+
23+
()
24+
)

tests/pos/i19570.orig.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
enum Op[A, B]:
2+
case Dup[T]() extends Op[T, (T, T)]
3+
4+
def foo[R](f: [A, B] => (o: Op[A, B]) => R): R =
5+
f(Op.Dup())
6+
7+
def test =
8+
foo([A, B] => (o: Op[A, B]) => {
9+
o match
10+
case o: Op.Dup[t] =>
11+
summon[A =:= t] // ERROR: Cannot prove that A =:= t.
12+
summon[B =:= (t, t)] // ERROR: Cannot prove that B =:= (t, t).
13+
42
14+
})

0 commit comments

Comments
 (0)