Skip to content

Commit f61026d

Browse files
authored
Fix callTrace of inlined methods (#18738)
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`.
2 parents 319e865 + eb0c408 commit f61026d

File tree

6 files changed

+14
-23
lines changed

6 files changed

+14
-23
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ jobs:
209209
run: sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test"
210210
shell: cmd
211211

212+
- name: Test with Scala 2 library TASTy
213+
run: sbt ";set ThisBuild/Build.useScala2LibraryTasty := true ;scala3-bootstrapped/testCompilation i5" # only test a subset of test to avoid doubling the CI execution time
214+
shell: cmd
215+
212216
- name: Scala.js Test
213217
run: sbt ";sjsJUnitTests/test ;set sjsJUnitTests/scalaJSLinkerConfig ~= switchToESModules ;sjsJUnitTests/test ;sjsCompilerTests/test"
214218
shell: cmd

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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/inlines/Inlines.scala

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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ 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 callTrace = ref(call.symbol)(using ctx.withSource(pos.source)).withSpan(pos.span)
371371
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
372372
case templ: Template =>
373373
withNoCheckNews(templ.parents.flatMap(newPart)) {

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

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