Skip to content

Commit 74d7ae0

Browse files
authored
Fix stale top level synthetic package object being used in later runs (#23464)
Fixes #13821 To explain what was happening: We previously got a completion assertion crash, because a stale symbol (`val candidate`) was brought forward into a new run, even though it should not have been, when searching for implicits. This was caused by the synthetic top level package object (`file$package`, generated only when top level definitions require it to, which is why the issue appeared only when `type DFBits = Long` was present) passing `stillValid` check, despite not being found in the Symbols owned by owner (`package <empty>`). This would cause all of the stale members of that to also be brought forward (as they would fulfill the requirements of `stillValidInOwner`). The stale top level package would incorrectly pass the `(denot.is(Synthetic) && denot.is(ModuleClass) && stillValidInOwner(denot.companionClass))` check in stillValidInOwner, despite companionClass of that package object being a noSymbol. Now we also check if companionClass is a `noSymbol` explicitly to avoid this issue.
2 parents 4011514 + 08b8340 commit 74d7ae0

File tree

12 files changed

+48
-16
lines changed

12 files changed

+48
-16
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2720,7 +2720,7 @@ object SymDenotations {
27202720
|| owner.isRefinementClass
27212721
|| owner.is(Scala2x)
27222722
|| owner.unforcedDecls.contains(denot.name, denot.symbol)
2723-
|| (denot.is(Synthetic) && denot.is(ModuleClass) && stillValidInOwner(denot.companionClass))
2723+
|| (denot.is(Synthetic) && denot.is(ModuleClass) && denot.companionClass.exists && stillValidInOwner(denot.companionClass))
27242724
|| denot.isSelfSym
27252725
|| denot.isLocalDummy)
27262726
catch case ex: StaleSymbol => false

tests/neg/i19351.check

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/neg/i19351/A.scala

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/neg/i19351a.check

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/pos-macros/i13821-a/Macro.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
trait Conversions:
2+
given conv(using DFBits.Candidate): Conversion[Int, DFVal] = ???
3+
4+
import scala.quoted.*
5+
transparent inline def f: Short = ${ getWidthMacro }
6+
private def getWidthMacro(using Quotes): Expr[Short] = '{ ??? }

tests/pos-macros/i13821-a/Test.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type DFBits = Long
2+
object DFBits:
3+
def a: Unit = f // forces suspension of this compilation unit in typer
4+
def b: DFVal = 2 // uses implicit conversion `DFVal.conv`
5+
6+
trait Candidate
7+
object Candidate:
8+
given candidate: Candidate = ??? // completed in run 3 but created in run 2
9+
end DFBits
10+
11+
trait DFVal
12+
object DFVal extends Conversions

tests/pos-macros/i13821-b/Macro.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import outer._
2+
trait Conversions:
3+
given conv(using DFBits.Candidate): Conversion[Int, DFVal] = ???
4+
5+
import scala.quoted.*
6+
transparent inline def f: Short = ${ getWidthMacro }
7+
private def getWidthMacro(using Quotes): Expr[Short] = '{ ??? }

tests/pos-macros/i13821-b/Test.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type outer = Int
2+
object outer:
3+
type DFBits = Long
4+
object DFBits:
5+
def a: Unit = f // forces suspension of this compilation unit in typer
6+
def b: DFVal = 2 // uses implicit conversion `DFVal.conv`
7+
8+
trait Candidate
9+
object Candidate:
10+
given candidate: Candidate = ??? // completed in run 3 but created in run 2
11+
end DFBits
12+
13+
trait DFVal
14+
object DFVal extends Conversions

tests/pos-macros/i19351/A.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// object A:
2+
val x: Int = 1
3+
inline def myMacro(): x.type = ${myMacroExpr}
4+
def test = myMacro()
5+
6+
@main def main() = ()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import scala.quoted.*
2-
//import A.*
2+
// import A.*
33
def myMacroExpr(using Quotes): Expr[x.type] = '{???}
File renamed without changes.

tests/neg/i19351a/Test.scala renamed to tests/pos-macros/i19351a/Test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type Bool = [R] => (R, R) => R
55
val True: Bool = [R] => (t: R, _: R) => t
66
val False: Bool = [R] => (_: R, f: R) => f
77

8-
inline def not(b: Bool): Bool = ${notMacro('b)} // error
8+
inline def not(b: Bool): Bool = ${notMacro('b)}
99
inline def show(b: Bool): String = ${showMacro('b)}
1010
//inline def not(b: Bool): Bool = ${foldMacro('b, 'False, 'True)}
1111
//inline def show(b: Bool): String = ${foldMacro('b, '{"TRUE"}, '{"FALSE"})}

0 commit comments

Comments
 (0)