Skip to content

Commit fd0548e

Browse files
authored
Avoid using the current denotation in NamedType.disambiguate (#21414)
While recalculating denotation in NamedType (in `NamedType.memberDenot`, which itself can be called from `NamedType.computeDenot` or `NamedType.recomputeDenot`), it might call `NamedType.disambiguate` which uses a denotation to decide about the correct overloaded method. Using current denotation here might cause stale symbol errors, so instead we use the `lastKnownDenotation`, which should be enough for the use case here, as `targetName` should not change between phases/runs. Later in the denotation recalculation a similar thing happens with `SourceLanguage.apply`, where we also now avoid using currentDenotation, as whether the symbol comes from java or Scala 2 should also not change between phases/runs.
2 parents 5e7ab15 + 6e58d25 commit fd0548e

File tree

7 files changed

+53
-4
lines changed

7 files changed

+53
-4
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ object Denotations {
961961
}
962962

963963
def staleSymbolError(using Context): Nothing =
964-
if symbol.isPackageObject && ctx.run != null && ctx.run.nn.isCompilingSuspended
964+
if symbol.lastKnownDenotation.isPackageObject && ctx.run != null && ctx.run.nn.isCompilingSuspended
965965
then throw StaleSymbolTypeError(symbol)
966966
else throw StaleSymbolException(staleSymbolMsg)
967967

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ enum SourceLanguage:
2424
object SourceLanguage:
2525
/** The language in which `sym` was defined. */
2626
def apply(sym: Symbol)(using Context): SourceLanguage =
27-
if sym.is(JavaDefined) then
27+
// We might be using this method while recalculating the denotation,
28+
// so let's use `lastKnownDenotation`.
29+
// This is ok as the source of the symbol and whether it is inline should
30+
// not change between runs/phases.
31+
val denot = sym.lastKnownDenotation
32+
if denot.is(JavaDefined) then
2833
SourceLanguage.Java
2934
// Scala 2 methods don't have Inline set, except for the ones injected with `patchStdlibClass`
3035
// which are really Scala 3 methods.
31-
else if sym.isClass && sym.is(Scala2x) || (sym.maybeOwner.is(Scala2x) && !sym.is(Inline)) then
36+
else if denot.isClass && denot.is(Scala2x) || (denot.maybeOwner.lastKnownDenotation.is(Scala2x) && !denot.is(Inline)) then
3237
SourceLanguage.Scala2
3338
else
3439
SourceLanguage.Scala3

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -2494,7 +2494,10 @@ object Types extends TypeUtils {
24942494
}
24952495

24962496
private def disambiguate(d: Denotation)(using Context): Denotation =
2497-
disambiguate(d, currentSignature, currentSymbol.targetName)
2497+
// this method might be triggered while the denotation is already being recomputed
2498+
// in NamedType, so it's better to use lastKnownDenotation instead, as targetName
2499+
// should not change between phases/runs
2500+
disambiguate(d, currentSignature, currentSymbol.lastKnownDenotation.targetName)
24982501

24992502
private def disambiguate(d: Denotation, sig: Signature | Null, target: Name)(using Context): Denotation =
25002503
if (sig != null)

Diff for: tests/pos-macros/i20574/Exports.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Exports{
2+
export OverloadedInline.*
3+
}

Diff for: tests/pos-macros/i20574/Macros.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import scala.quoted.*
2+
3+
object Macros{
4+
5+
inline def A() : String = {
6+
${ A_impl }
7+
}
8+
9+
def A_impl(using Quotes): Expr[String] = {
10+
Expr("Whatever")
11+
}
12+
13+
inline def B[T]: Int = {
14+
${ B_Impl[T] }
15+
}
16+
17+
def B_Impl[T](using Quotes): Expr[Int] = {
18+
Expr(0)
19+
}
20+
}

Diff for: tests/pos-macros/i20574/OverloadedInline.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Macros.*
2+
3+
object OverloadedInline{
4+
5+
A()
6+
inline def overloaded_inline[T]: Unit = {
7+
overloaded_inline[T](0)
8+
}
9+
10+
inline def overloaded_inline[T](dummy: Int): Unit = {
11+
val crash = B[T]
12+
}
13+
}

Diff for: tests/pos-macros/i20574/Test.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Exports.*
2+
3+
object Test {
4+
overloaded_inline[Unit]
5+
}

0 commit comments

Comments
 (0)