Skip to content

Commit f3c2b1d

Browse files
committed
Fix StaleSymbol for path dependent result type in macro context
The reason for the stale symbols was the fact that they were derived from the previous (suspended) run (by calling a method from that run), and path depended types seem to use an optimized path utilizing initial designator, unlike the other kinds of types, which seem to either not need calculating denotation or the denotation there is able to update it's own validity. Since that is impossible to do for those path dependent types, if they are invalid in the run recaluclate the Symbol, otherwise use `currentSymbol` as before.
1 parent 6acaf95 commit f3c2b1d

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/Types.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -2677,7 +2677,10 @@ object Types {
26772677
else {
26782678
if (isType) {
26792679
val res =
2680-
if (currentSymbol.isAllOf(ClassTypeParam)) argForParam(prefix)
2680+
val sym =
2681+
if (currentSymbol.isValidInCurrentRun) currentSymbol
2682+
else computeSymbol
2683+
if (sym.isAllOf(ClassTypeParam)) argForParam(prefix)
26812684
else prefix.lookupRefined(name)
26822685
if (res.exists) return res
26832686
if (Config.splitProjections)

Diff for: tests/neg-macros/i17152/DFBits.scala

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// nopos-error
2+
package crash
3+
4+
import scala.quoted.*
5+
6+
class IRDFType
7+
class IRDFBoolOrBit extends IRDFType
8+
class IRDFDecimal extends IRDFType
9+
class IRDFBits extends IRDFType
10+
11+
final class DFType[+T <: IRDFType, +A]
12+
type DFTypeAny = DFType[IRDFType, Any]
13+
14+
trait Baz
15+
16+
trait Width[T]:
17+
type Out <: Int
18+
object Width:
19+
given fromDFBoolOrBit[T <: DFBoolOrBit]: Width[T] with
20+
type Out = 1
21+
transparent inline given [T]: Width[T] = ${ getWidthMacro[T] }
22+
def getWidthMacro[T](using Quotes, Type[T]): Expr[Width[T]] =
23+
'{
24+
new Width[T]:
25+
type Out = 1
26+
}
27+
end Width
28+
29+
extension [T](t: T)(using baz: Baz) def width: 1 = ???
30+
31+
trait Check[T1 <: Int, T2 <: Int]
32+
33+
type DFBits[W <: Int] = DFType[IRDFBits, Tuple1[W]]
34+
35+
private object CompanionsDFBits:
36+
object Val:
37+
trait Candidate[R]:
38+
type OutW <: Int
39+
def apply(value: R): DFValOf[DFBits[OutW]]
40+
object Candidate:
41+
given fromDFUInt[W <: Int, R <: DFValOf[DFDecimal]]: Candidate[R] with
42+
type OutW = W
43+
def apply(value: R): DFValOf[DFBits[W]] =
44+
import DFVal.Ops.bits
45+
value.bits
46+
???
47+
end Candidate
48+
49+
object TC:
50+
import DFVal.TC
51+
given DFBitsFromCandidate[
52+
LW <: Int,
53+
V
54+
](using candidate: Candidate[V])(using
55+
check: Check[LW, candidate.OutW]
56+
): TC[DFBits[LW], V] with
57+
def conv(dfType: DFBits[LW], value: V): DFValOf[DFBits[LW]] =
58+
val dfVal = candidate(value)
59+
???
60+
end TC
61+
end Val
62+
63+
end CompanionsDFBits
64+
65+
type DFBoolOrBit = DFType[IRDFBoolOrBit, Any]
66+
type DFDecimal = DFType[IRDFDecimal, Any]
67+
object DFDecimal:
68+
def foo(arg1: Int, arg2: Int): Unit = ???
69+
70+
object Val:
71+
object TC:
72+
import DFVal.TC
73+
given [R]: TC[DFDecimal, R] = ???
74+
def apply(
75+
dfType: DFDecimal,
76+
dfVal: DFValOf[DFDecimal]
77+
): DFValOf[DFDecimal] =
78+
foo(dfType.width, dfVal.width)
79+
dfVal
80+
end TC
81+
end Val
82+
end DFDecimal

Diff for: tests/neg-macros/i17152/DFVal.scala

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package crash
2+
3+
trait TCConv[T <: DFTypeAny, V, O]:
4+
type Out <: O
5+
def conv(dfType: T, value: V): Out
6+
7+
class DFVal[+T <: DFTypeAny]
8+
type DFValAny = DFVal[DFTypeAny]
9+
type DFValOf[+T <: DFTypeAny] = DFVal[T]
10+
11+
object DFVal:
12+
trait TC[T <: DFTypeAny, R] extends TCConv[T, R, DFValAny]:
13+
type Out = DFValOf[T]
14+
final def apply(dfType: T, value: R): Out = ???
15+
16+
object TC:
17+
export CompanionsDFBits.Val.TC.given
18+
end TC
19+
20+
object Ops:
21+
extension [T <: DFTypeAny, A, C, I](dfVal: DFVal[T])
22+
def bits(using w: Width[T]): DFValOf[DFBits[w.Out]] = ???
23+
end extension
24+
end Ops
25+
end DFVal

Diff for: tests/neg-macros/i17294/DFVal.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package crash
2+
3+
def bits[T](t: T)(using w: Width[T]): w.Out = ???

Diff for: tests/neg-macros/i17294/Width.scala

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// nopos-error
2+
package crash
3+
import scala.quoted.*
4+
5+
trait Width[T]:
6+
type Out
7+
object Width:
8+
transparent inline given [T]: Width[T] = ${ getWidthMacro[T] }
9+
def getWidthMacro[T](using Quotes, Type[T]): Expr[Width[T]] = '{ new Width[T] {} }
10+
end Width
11+
12+
val x = bits(1)

0 commit comments

Comments
 (0)