Skip to content

Commit 6ccc9fd

Browse files
authored
Backport "Fix stale symbol crashes in some path depended types in macro contexts" to LTS (#19051)
Backports #18077 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents bc4a74b + e523923 commit 6ccc9fd

File tree

7 files changed

+143
-7
lines changed

7 files changed

+143
-7
lines changed

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

Lines changed: 12 additions & 7 deletions
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)
@@ -2751,14 +2754,16 @@ object Types {
27512754
/** A reference like this one, but with the given prefix. */
27522755
final def withPrefix(prefix: Type)(using Context): Type = {
27532756
def reload(): NamedType = {
2754-
val lastSym = lastSymbol.nn
2755-
val allowPrivate = !lastSym.exists || lastSym.is(Private)
2757+
val sym =
2758+
if lastSymbol.nn.isValidInCurrentRun then lastSymbol.nn
2759+
else computeSymbol
2760+
val allowPrivate = !sym.exists || sym.is(Private)
27562761
var d = memberDenot(prefix, name, allowPrivate)
2757-
if (d.isOverloaded && lastSym.exists)
2762+
if (d.isOverloaded && sym.exists)
27582763
d = disambiguate(d,
2759-
if (lastSym.signature == Signature.NotAMethod) Signature.NotAMethod
2760-
else lastSym.asSeenFrom(prefix).signature,
2761-
lastSym.targetName)
2764+
if (sym.signature == Signature.NotAMethod) Signature.NotAMethod
2765+
else sym.asSeenFrom(prefix).signature,
2766+
sym.targetName)
27622767
NamedType(prefix, name, d)
27632768
}
27642769
if (prefix eq this.prefix) this

tests/neg-macros/i17152/DFBits.scala

Lines changed: 82 additions & 0 deletions
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

tests/neg-macros/i17152/DFVal.scala

Lines changed: 25 additions & 0 deletions
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

tests/neg-macros/i17294/DFVal.scala

Lines changed: 3 additions & 0 deletions
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 = ???

tests/neg-macros/i17294/Width.scala

Lines changed: 12 additions & 0 deletions
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)

tests/pos-macros/i17294/Bar.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted.*
2+
3+
class Bar[T]
4+
object Bar:
5+
transparent inline def bar[T](a: Foo, b: a.Out): Bar[T] = ${ getBarMacro[T] }
6+
def getBarMacro[T](using Quotes, Type[T]): Expr[Bar[T]] = '{ new Bar[T] }

tests/pos-macros/i17294/Foo.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo:
2+
type Out = Int
3+
val a = Bar.bar(new Foo(), 0)

0 commit comments

Comments
 (0)