Skip to content

Commit eb4962b

Browse files
Revert "Fix callTrace if inlined methods" (#19273)
This reverts commit ec75826. The previous encoding of INLINE nodes in TASTy assumed that the callTrace was a type. We cannot make it a term, or we would not be able to unpickle this tree properly. We need another solution to be able to pickle this correctly. For now we revert the change to avoid generating invalid TASTy.
2 parents 9af39e3 + 29ac576 commit eb4962b

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,7 @@ 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 method or the top-level class from
665-
* which the call was inlined.
664+
* a reference to the toplevel class from which the call was inlined.
666665
* @param bindings Bindings for proxies to be used in the inlined code
667666
* @param expansion The inlined tree, minus bindings.
668667
*

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

+14
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,20 @@ 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+
302316
private object Intrinsics:
303317
import dotty.tools.dotc.reporting.Diagnostic.Error
304318
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(ref(ctx.owner.topLevelClass.typeRef).withSpan(quote.span), Nil, body)
307+
else Inlined(Inlines.inlineCallTrace(ctx.owner, quote.sourcePos), 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

+1-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
370370
val pos = call.sourcePos
371371
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
372372
withMode(Mode.NoInline)(transform(call))
373-
val callTrace = ref(call.symbol)(using ctx.withSource(pos.source)).withSpan(pos.span)
373+
val callTrace = Inlines.inlineCallTrace(call.symbol, pos)(using ctx.withSource(pos.source))
374374
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
375375
case templ: Template =>
376376
Checking.checkPolyFunctionExtension(templ)

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

+13-6
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ 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.source :: sources
50-
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
49+
sources = call.symbol.topLevelClass.source :: sources
50+
if !isMacro(call) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
51+
&& !isBootstrappedPredefWithPatchedMethods(call) // FIXME The patched symbol has a different source as the definition of Predef. Solution: define them directly in `Predef`s TASTy and do not patch (see #19231).
52+
then
5153
traverse(expansion)(using inlineContext(tree).withSource(sources.head))
5254
sources = sources.tail
5355
case _ => traverseChildren(tree)
@@ -59,12 +61,17 @@ class YCheckPositions extends Phase {
5961
case _ =>
6062
}
6163

64+
private def isBootstrappedPredefWithPatchedMethods(call: Tree)(using Context) =
65+
val sym = call.symbol
66+
(sym.is(Inline) && sym.owner == defn.ScalaPredefModuleClass && sym.owner.is(Scala2Tasty))
67+
|| (sym == defn.ScalaPredefModuleClass && sym.is(Scala2Tasty))
68+
6269
private def isMacro(call: Tree)(using Context) =
6370
call.symbol.is(Macro) ||
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])
71+
(call.symbol.isClass && call.tpe.derivesFrom(defn.MacroAnnotationClass)) ||
72+
// The call of a macro after typer is encoded as a Select while other inlines are Ident
73+
// TODO remove this distinction once Inline nodes of expanded macros can be trusted (also in Inliner.inlineCallTrace)
74+
(!(ctx.phase <= postTyperPhase) && call.isInstanceOf[Select])
6875

6976
}
7077

0 commit comments

Comments
 (0)