Skip to content

Commit

Permalink
Avoid using the current denotation in NamedType.disambiguate
Browse files Browse the repository at this point in the history
While recalculating denotation we might call NamedType.disambiguate
which uses a denotation to decide about the correct overloaded method.
Using curretn denotation here might cause stale symbol errors, so instead we use
the lastKnownDenotation, which should be enough for the use case here.
  • Loading branch information
jchyb committed Aug 22, 2024
1 parent b64afad commit 5e907fc
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ object Denotations {
}

def staleSymbolError(using Context): Nothing =
if symbol.isPackageObject && ctx.run != null && ctx.run.nn.isCompilingSuspended
if symbol.lastKnownDenotation.isPackageObject && ctx.run != null && ctx.run.nn.isCompilingSuspended
then throw StaleSymbolTypeError(symbol)
else throw StaleSymbolException(staleSymbolMsg)

Expand Down
9 changes: 7 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ enum SourceLanguage:
object SourceLanguage:
/** The language in which `sym` was defined. */
def apply(sym: Symbol)(using Context): SourceLanguage =
if sym.is(JavaDefined) then
// We might be using this method while recalculating the denotation,
// so let's use `lastKnownDenotation`.
// This is ok as the source of the symbol and whether it is inline should
// not change between runs/phases.
val denot = sym.lastKnownDenotation
if denot.is(JavaDefined) then
SourceLanguage.Java
// Scala 2 methods don't have Inline set, except for the ones injected with `patchStdlibClass`
// which are really Scala 3 methods.
else if sym.isClass && sym.is(Scala2x) || (sym.maybeOwner.is(Scala2x) && !sym.is(Inline)) then
else if denot.isClass && denot.is(Scala2x) || (denot.maybeOwner.lastKnownDenotation.is(Scala2x) && !denot.is(Inline)) then
SourceLanguage.Scala2
else
SourceLanguage.Scala3
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2485,7 +2485,7 @@ object Types extends TypeUtils {
}

private def disambiguate(d: Denotation)(using Context): Denotation =
disambiguate(d, currentSignature, currentSymbol.targetName)
disambiguate(d, currentSignature, currentSymbol.lastKnownDenotation.targetName)

private def disambiguate(d: Denotation, sig: Signature | Null, target: Name)(using Context): Denotation =
if (sig != null)
Expand Down
3 changes: 3 additions & 0 deletions tests/pos-macros/i20574/Exports.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object Exports{
export OverloadedInline.*
}
20 changes: 20 additions & 0 deletions tests/pos-macros/i20574/Macros.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import scala.quoted.*

object Macros{

inline def A() : String = {
${ A_impl }
}

def A_impl(using Quotes): Expr[String] = {
Expr("Whatever")
}

inline def B[T]: Int = {
${ B_Impl[T] }
}

def B_Impl[T](using Quotes): Expr[Int] = {
Expr(0)
}
}
13 changes: 13 additions & 0 deletions tests/pos-macros/i20574/OverloadedInline.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Macros.*

object OverloadedInline{

A()
inline def overloaded_inline[T]: Unit = {
overloaded_inline[T](0)
}

inline def overloaded_inline[T](dummy: Int): Unit = {
val crash = B[T]
}
}
5 changes: 5 additions & 0 deletions tests/pos-macros/i20574/Test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Exports.*

object Test {
overloaded_inline[Unit]
}

0 comments on commit 5e907fc

Please sign in to comment.