Skip to content

Revert "Fix callTrace if inlined methods" #19273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,7 @@ object Trees {
*
* @param call Info about the original call that was inlined
* Until PostTyper, this is the full call, afterwards only
* a reference to the method or the top-level class from
* which the call was inlined.
* a reference to the toplevel class from which the call was inlined.
* @param bindings Bindings for proxies to be used in the inlined code
* @param expansion The inlined tree, minus bindings.
*
Expand Down
14 changes: 14 additions & 0 deletions compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,20 @@ object Inlines:
(new Reposition).transform(tree)
end reposition

/** Leave only a call trace consisting of
* - a reference to the top-level class from which the call was inlined,
* - the call's position
* in the call field of an Inlined node.
* The trace has enough info to completely reconstruct positions.
* 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)
*/
def inlineCallTrace(callSym: Symbol, pos: SourcePosition)(using Context): Tree = {
assert(ctx.source == pos.source)
val topLevelCls = callSym.topLevelClass
if (callSym.is(Macro)) ref(topLevelCls.owner).select(topLevelCls.name)(using ctx.withOwner(topLevelCls.owner)).withSpan(pos.span)
else Ident(topLevelCls.typeRef).withSpan(pos.span)
}

private object Intrinsics:
import dotty.tools.dotc.reporting.Diagnostic.Error
private enum ErrorKind:
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ object PickleQuotes {
def pickleAsTasty() = {
val body1 =
if body.isType then body
else Inlined(ref(ctx.owner.topLevelClass.typeRef).withSpan(quote.span), Nil, body)
else Inlined(Inlines.inlineCallTrace(ctx.owner, quote.sourcePos), Nil, body)
val pickleQuote = PickledQuotes.pickleQuote(body1)
val pickledQuoteStrings = pickleQuote match
case x :: Nil => Literal(Constant(x))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
val pos = call.sourcePos
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
withMode(Mode.NoInline)(transform(call))
val callTrace = ref(call.symbol)(using ctx.withSource(pos.source)).withSpan(pos.span)
val callTrace = Inlines.inlineCallTrace(call.symbol, pos)(using ctx.withSource(pos.source))
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
case templ: Template =>
Checking.checkPolyFunctionExtension(templ)
Expand Down
19 changes: 13 additions & 6 deletions compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ class YCheckPositions extends Phase {
sources = old
case tree @ Inlined(call, bindings, expansion) =>
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
sources = call.symbol.source :: sources
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
sources = call.symbol.topLevelClass.source :: sources
if !isMacro(call) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
&& !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).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to add this new guard because now we execute tests for the Scala 2 library TASTy in the CI.

then
traverse(expansion)(using inlineContext(tree).withSource(sources.head))
sources = sources.tail
case _ => traverseChildren(tree)
Expand All @@ -59,12 +61,17 @@ class YCheckPositions extends Phase {
case _ =>
}

private def isBootstrappedPredefWithPatchedMethods(call: Tree)(using Context) =
val sym = call.symbol
(sym.is(Inline) && sym.owner == defn.ScalaPredefModuleClass && sym.owner.is(Scala2Tasty))
|| (sym == defn.ScalaPredefModuleClass && sym.is(Scala2Tasty))

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

}

Expand Down