Skip to content

Commit bcc993e

Browse files
committed
Fix callTrace if inlined methods
We need to keep the reference to the called method, not only the symbol of the to level class. This is important for the traces of the `assert` method that is defined in a different file. This might also be useful for macro annotations. This is also a solution to the awkward Select vs. Ident distinction to identify macros in `YCheckPositions`. Ww use `-Ycompile-scala3-library` to avoid the `stdLibPatches` patches in the community build test for `stdLib213` the same way we do in `scala-library-bootstrapped`.
1 parent 9fccb7e commit bcc993e

File tree

7 files changed

+24
-24
lines changed

7 files changed

+24
-24
lines changed

community-build/src/scala/dotty/communitybuild/projects.scala

+1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ object projects:
363363
extraSbtArgs = List("-Dscala.build.compileWithDotty=true"),
364364
sbtTestCommand = """set Global / fatalWarnings := false; library/compile""",
365365
sbtPublishCommand = """set Global / fatalWarnings := false; set library/Compile/packageDoc/publishArtifact := false; library/publishLocal""",
366+
scalacOptions = "-Ycompile-scala3-library" :: SbtCommunityProject.scalacOptions
366367
// sbtDocCommand = "library/doc" // Does no compile? No idea :/
367368
)
368369

compiler/src/dotty/tools/dotc/ast/Trees.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object Trees {
3131

3232
/** Property key for backquoted identifiers and definitions */
3333
val Backquoted: Property.StickyKey[Unit] = Property.StickyKey()
34-
34+
3535
val SyntheticUnit: Property.StickyKey[Unit] = Property.StickyKey()
3636

3737
/** Trees take a parameter indicating what the type of their `tpe` field
@@ -661,7 +661,8 @@ object Trees {
661661
*
662662
* @param call Info about the original call that was inlined
663663
* Until PostTyper, this is the full call, afterwards only
664-
* a reference to the toplevel class from which the call was inlined.
664+
* a reference to the method or the top-level class from
665+
* which the call was inlined.
665666
* @param bindings Bindings for proxies to be used in the inlined code
666667
* @param expansion The inlined tree, minus bindings.
667668
*

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ private sealed trait YSettings:
396396
val YnoExperimental: Setting[Boolean] = BooleanSetting("-Yno-experimental", "Disable experimental language features.")
397397
val YlegacyLazyVals: Setting[Boolean] = BooleanSetting("-Ylegacy-lazy-vals", "Use legacy (pre 3.3.0) implementation of lazy vals.")
398398
val YcompileScala2Library: Setting[Boolean] = BooleanSetting("-Ycompile-scala2-library", "Used when compiling the Scala 2 standard library.")
399+
val YcompileScala3Library: Setting[Boolean] = BooleanSetting("-Ycompile-scala3-library", "Used when compiling the Scala 3 standard library, including the Scala 2 library sources.")
399400
val YoutputOnlyTasty: Setting[Boolean] = BooleanSetting("-Youtput-only-tasty", "Used to only generate the TASTy file without the classfiles")
400401

401402
val YprofileEnabled: Setting[Boolean] = BooleanSetting("-Yprofile-enabled", "Enable profiling.")

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

-14
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,6 @@ object Inlines:
299299
(new Reposition).transform(tree)
300300
end reposition
301301

302-
/** Leave only a call trace consisting of
303-
* - a reference to the top-level class from which the call was inlined,
304-
* - the call's position
305-
* in the call field of an Inlined node.
306-
* The trace has enough info to completely reconstruct positions.
307-
* Note: For macros it returns a Select and for other inline methods it returns an Ident (this distinction is only temporary to be able to run YCheckPositions)
308-
*/
309-
def inlineCallTrace(callSym: Symbol, pos: SourcePosition)(using Context): Tree = {
310-
assert(ctx.source == pos.source)
311-
val topLevelCls = callSym.topLevelClass
312-
if (callSym.is(Macro)) ref(topLevelCls.owner).select(topLevelCls.name)(using ctx.withOwner(topLevelCls.owner)).withSpan(pos.span)
313-
else Ident(topLevelCls.typeRef).withSpan(pos.span)
314-
}
315-
316302
private object Intrinsics:
317303
import dotty.tools.dotc.reporting.Diagnostic.Error
318304
private enum ErrorKind:

compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ object PickleQuotes {
304304
def pickleAsTasty() = {
305305
val body1 =
306306
if body.isType then body
307-
else Inlined(Inlines.inlineCallTrace(ctx.owner, quote.sourcePos), Nil, body)
307+
else Inlined(ref(ctx.owner.topLevelClass.typeRef).withSpan(quote.span), Nil, body)
308308
val pickleQuote = PickledQuotes.pickleQuote(body1)
309309
val pickledQuoteStrings = pickleQuote match
310310
case x :: Nil => Literal(Constant(x))

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

+12-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,18 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
367367
val pos = call.sourcePos
368368
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
369369
withMode(Mode.InlinedCall)(transform(call))
370-
val callTrace = Inlines.inlineCallTrace(call.symbol, pos)(using ctx.withSource(pos.source))
370+
val traceSym =
371+
if ctx.settings.YcompileScala3Library.value && call.symbol.owner == defn.ScalaPredefModuleClass then
372+
// These are inline method overrides that come from `scala.runtime.stdLibPatches.Predef`.
373+
// References to these members can cause conflicts when compiling the standard library.
374+
// FIXME: remove this workaround. Ideally we should not patch Predef when we compile the library to
375+
// avoid the `assert` overrides, but we also need the patches to make `summon` and other new features
376+
// work within the Scala 3 library sources. Note that currently compiling Predef.scala with
377+
// `-Ycompile-scala3-library` or without does not Ycheck. It does with `-Ycompile-scala2-library`,
378+
// because we do not apply the patches.
379+
call.symbol.topLevelClass
380+
else call.symbol
381+
val callTrace = ref(traceSym)(using ctx.withSource(pos.source)).withSpan(pos.span)
371382
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
372383
case templ: Template =>
373384
withNoCheckNews(templ.parents.flatMap(newPart)) {

compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class YCheckPositions extends Phase {
3535
val currentSource = sources.head
3636
assert(tree.source == currentSource, i"wrong source set for $tree # ${tree.uniqueId} of ${tree.getClass}, set to ${tree.source} but context had $currentSource\n ${tree.symbol.flagsString}")
3737

38-
// Recursivlely check children while keeping track of current source
38+
// Recursively check children while keeping track of current source
3939
reporting.trace(i"check pos ${tree.getClass} ${tree.source} ${sources.head} $tree") {
4040
tree match {
4141
case tree @ Inlined(_, bindings, expansion) if tree.inlinedFromOuterScope =>
@@ -46,7 +46,7 @@ class YCheckPositions extends Phase {
4646
sources = old
4747
case tree @ Inlined(call, bindings, expansion) =>
4848
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
49-
sources = call.symbol.topLevelClass.source :: sources
49+
sources = call.symbol.source :: sources
5050
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
5151
traverse(expansion)(using inlineContext(tree).withSource(sources.head))
5252
sources = sources.tail
@@ -61,10 +61,10 @@ class YCheckPositions extends Phase {
6161

6262
private def isMacro(call: Tree)(using Context) =
6363
call.symbol.is(Macro) ||
64-
(call.symbol.isClass && call.tpe.derivesFrom(defn.MacroAnnotationClass)) ||
65-
// The call of a macro after typer is encoded as a Select while other inlines are Ident
66-
// TODO remove this distinction once Inline nodes of expanded macros can be trusted (also in Inliner.inlineCallTrace)
67-
(!(ctx.phase <= postTyperPhase) && call.isInstanceOf[Select])
64+
(call.symbol.isClass && call.tpe.derivesFrom(defn.MacroAnnotationClass)) ||
65+
// In 3.0-3.3, the call of a macro after typer is encoded as a Select while other inlines are Ident.
66+
// In those versions we kept the reference to the top-level class instead of the methods.
67+
(!(ctx.phase <= postTyperPhase) && call.symbol.isClass && call.isInstanceOf[Select])
6868

6969
}
7070

0 commit comments

Comments
 (0)