Skip to content

Remove bindings from Inlined tree #6087

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

Closed
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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Positioned.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
* of all children to the right.
*/
def envelope(src: SourceFile, startSpan: Span = NoSpan): Span = this match {
case Trees.Inlined(call, _, _) =>
case Trees.Inlined(call, _) =>
call.span
case _ =>
def include(span: Span, x: Any): Span = x match {
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
exprPurity(expr)
case Block(stats, expr) =>
minOf(exprPurity(expr), stats.map(statPurity))
case Inlined(_, bindings, expr) =>
minOf(exprPurity(expr), bindings.map(statPurity))
case Inlined(_, expr) =>
exprPurity(expr)
case NamedArg(_, expr) =>
exprPurity(expr)
case _ =>
Expand Down Expand Up @@ -599,7 +599,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
Some(meth)
case Block(Nil, expr) =>
unapply(expr)
case Inlined(_, bindings, expr) if bindings.forall(isPureBinding) =>
case Inlined(_, expr) =>
unapply(expr)
case _ =>
None
Expand Down Expand Up @@ -728,7 +728,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
*/
def tupleArgs(tree: Tree)(implicit ctx: Context): List[Tree] = tree match {
case Block(Nil, expr) => tupleArgs(expr)
case Inlined(_, Nil, expr) => tupleArgs(expr)
case Inlined(_, expr) => tupleArgs(expr)
case Apply(fn, args)
if fn.symbol.name == nme.apply &&
fn.symbol.owner.is(Module) &&
Expand Down
7 changes: 3 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,9 @@ class TreeTypeMap(
val (tmap1, stats1) = transformDefs(stats)
val expr1 = tmap1.transform(expr)
cpy.Block(blk)(stats1, expr1)
case inlined @ Inlined(call, bindings, expanded) =>
val (tmap1, bindings1) = transformDefs(bindings)
val expanded1 = tmap1.transform(expanded)
cpy.Inlined(inlined)(call, bindings1, expanded1)
case inlined @ Inlined(call, expanded) =>
val expanded1 = transform(expanded)
cpy.Inlined(inlined)(call, expanded1)
case cdef @ CaseDef(pat, guard, rhs) =>
val tmap = withMappedSyms(patVars(pat))
val pat1 = tmap.transform(pat)
Expand Down
27 changes: 9 additions & 18 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -590,18 +590,9 @@ 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 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.
*
* The full inlined code is equivalent to
*
* { bindings; expansion }
*
* The reason to keep `bindings` separate is because they are typed in a
* different context: `bindings` represent the arguments to the inlined
* call, whereas `expansion` represents the body of the inlined function.
* @param expansion The inlined tree, including bindings.
*/
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, bindings: List[MemberDef[T]], expansion: Tree[T])(implicit @constructorOnly src: SourceFile)
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, expansion: Tree[T])(implicit @constructorOnly src: SourceFile)
extends Tree[T] {
type ThisTree[-T >: Untyped] = Inlined[T]
}
Expand Down Expand Up @@ -1080,9 +1071,9 @@ object Trees {
case tree: SeqLiteral if (elems eq tree.elems) && (elemtpt eq tree.elemtpt) => tree
case _ => finalize(tree, untpd.SeqLiteral(elems, elemtpt)(sourceFile(tree)))
}
def Inlined(tree: Tree)(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit ctx: Context): Inlined = tree match {
case tree: Inlined if (call eq tree.call) && (bindings eq tree.bindings) && (expansion eq tree.expansion) => tree
case _ => finalize(tree, untpd.Inlined(call, bindings, expansion)(sourceFile(tree)))
def Inlined(tree: Tree)(call: tpd.Tree, expansion: Tree)(implicit ctx: Context): Inlined = tree match {
case tree: Inlined if (call eq tree.call) && (expansion eq tree.expansion) => tree
case _ => finalize(tree, untpd.Inlined(call, expansion)(sourceFile(tree)))
}
def SingletonTypeTree(tree: Tree)(ref: Tree)(implicit ctx: Context): SingletonTypeTree = tree match {
case tree: SingletonTypeTree if (ref eq tree.ref) => tree
Expand Down Expand Up @@ -1243,8 +1234,8 @@ object Trees {
cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer))
case SeqLiteral(elems, elemtpt) =>
cpy.SeqLiteral(tree)(transform(elems), transform(elemtpt))
case Inlined(call, bindings, expansion) =>
cpy.Inlined(tree)(call, transformSub(bindings), transform(expansion)(inlineContext(call)))
case Inlined(call, expansion) =>
cpy.Inlined(tree)(call, transform(expansion)(inlineContext(call)))
case TypeTree() =>
tree
case SingletonTypeTree(ref) =>
Expand Down Expand Up @@ -1367,8 +1358,8 @@ object Trees {
this(this(this(x, block), handler), finalizer)
case SeqLiteral(elems, elemtpt) =>
this(this(x, elems), elemtpt)
case Inlined(call, bindings, expansion) =>
this(this(x, bindings), expansion)(inlineContext(call))
case Inlined(call, expansion) =>
this(x, expansion)(inlineContext(call))
case TypeTree() =>
x
case SingletonTypeTree(ref) =>
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): JavaSeqLiteral =
ta.assignType(new untpd.JavaSeqLiteral(elems, elemtpt), elems, elemtpt).asInstanceOf[JavaSeqLiteral]

def Inlined(call: Tree, bindings: List[MemberDef], expansion: Tree)(implicit ctx: Context): Inlined =
ta.assignType(untpd.Inlined(call, bindings, expansion), bindings, expansion)
def Inlined(call: Tree, expansion: Tree)(implicit ctx: Context): Inlined =
ta.assignType(untpd.Inlined(call, expansion), expansion)

def TypeTree(tp: Type)(implicit ctx: Context): TypeTree =
untpd.TypeTree().withType(tp)
Expand Down Expand Up @@ -643,12 +643,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
}

override def Inlined(tree: Tree)(call: Tree, bindings: List[MemberDef], expansion: Tree)(implicit ctx: Context): Inlined = {
val tree1 = untpdCpy.Inlined(tree)(call, bindings, expansion)
override def Inlined(tree: Tree)(call: Tree, expansion: Tree)(implicit ctx: Context): Inlined = {
val tree1 = untpdCpy.Inlined(tree)(call, expansion)
tree match {
case tree: Inlined if sameTypes(bindings, tree.bindings) && (expansion.tpe eq tree.expansion.tpe) =>
case tree: Inlined if expansion.tpe eq tree.expansion.tpe =>
tree1.withTypeUnchecked(tree.tpe)
case _ => ta.assignType(tree1, bindings, expansion)
case _ => ta.assignType(tree1, expansion)
}
}

Expand Down Expand Up @@ -1023,7 +1023,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case defTree: ValOrDefDef => transform(defTree.rhs)
case _ => tree
}
case Inlined(_, _, arg) => transform(arg)
case Inlined(_, arg) => transform(arg)
case Block(Nil, arg) => transform(arg)
case NamedArg(_, arg) => transform(arg)
case tree => super.transform(tree)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit src: SourceFile): Try = new Try(expr, cases, finalizer)
def SeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit src: SourceFile): SeqLiteral = new SeqLiteral(elems, elemtpt)
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit src: SourceFile): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt)
def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, bindings, expansion)
def Inlined(call: tpd.Tree, expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, expansion)
def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree()
def SingletonTypeTree(ref: Tree)(implicit src: SourceFile): SingletonTypeTree = new SingletonTypeTree(ref)
def RefinedTypeTree(tpt: Tree, refinements: List[Tree])(implicit src: SourceFile): RefinedTypeTree = new RefinedTypeTree(tpt, refinements)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ object PickledQuotes {
val argVals = args.map(arg => SyntheticValDef(NameKinds.UniqueName.fresh("x".toTermName), arg).withSpan(arg.span))
def argRefs() = argVals.map(argVal => ref(argVal.symbol))
def rec(fn: Tree): Tree = fn match {
case Inlined(call, bindings, expansion) =>
case Inlined(call, expansion) =>
// this case must go before closureDef to avoid dropping the inline node
cpy.Inlined(fn)(call, bindings, rec(expansion))
cpy.Inlined(fn)(call, rec(expansion))
case closureDef(ddef) =>
val paramSyms = ddef.vparamss.head.map(param => param.symbol)
val paramToVals = paramSyms.zip(argRefs()).toMap
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Standard-Section: "ASTs" TopLevelStat*
TYPED Length expr_Term ascriptionType_Tern
ASSIGN Length lhs_Term rhs_Term
BLOCK Length expr_Term Stat*
INLINED Length expr_Term call_Term? ValOrDefDef*
INLINED Length expr_Term call_Term?
LAMBDA Length meth_Term target_Type?
IF Length [INLINE] cond_Term then_Term else_Term
MATCH Length (IMPLICIT | [INLINE] sel_Term) CaseDef*
Expand Down Expand Up @@ -244,7 +244,7 @@ Standard Section: "Comments" Comment*
object TastyFormat {

final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
val MajorVersion: Int = 13
val MajorVersion: Int = 14
val MinorVersion: Int = 0

/** Tags used to serialize names */
Expand Down
7 changes: 1 addition & 6 deletions compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,11 @@ class TreePickler(pickler: TastyPickler) {
case SeqLiteral(elems, elemtpt) =>
writeByte(REPEATED)
withLength { pickleTree(elemtpt); elems.foreach(pickleTree) }
case Inlined(call, bindings, expansion) =>
case Inlined(call, expansion) =>
writeByte(INLINED)
bindings.foreach(preRegister)
withLength {
pickleTree(expansion)
if (!call.isEmpty) pickleTree(call)
bindings.foreach { b =>
assert(b.isInstanceOf[DefDef] || b.isInstanceOf[ValDef])
pickleTree(b)
}
}
case Bind(name, body) =>
registerDef(tree.symbol)
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1106,9 +1106,8 @@ class TreeUnpickler(reader: TastyReader,
case _ => readTerm()
}
val call = ifBefore(end)(maybeCall, EmptyTree)
val bindings = readStats(ctx.owner, end).asInstanceOf[List[ValOrDefDef]]
val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before
Inlined(call, bindings, expansion)
val expansion = exprReader.readTerm()
Inlined(call, expansion)
case IF =>
if (nextByte == INLINE) {
readByte()
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
case SeqLiteral(elems, elemtpt) =>
"[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]"
case tree @ Inlined(call, bindings, body) =>
case tree @ Inlined(call, body) =>
(("/* inlined from " ~ (if (call.isEmpty) "outside" else toText(call)) ~ " */ ") `provided`
!homogenizedView && !ctx.settings.YshowNoInline.value) ~
blockText(bindings :+ body)
toText(body)
case tpt: untpd.DerivedTypeTree =>
"<derived typetree watching " ~ summarized(toText(tpt.watched)) ~ ">"
case TypeTree() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT
}

tree match {
case Inlined(call, _, _) if !call.isEmpty =>
case Inlined(call, _) if !call.isEmpty =>
// The inlined call is normally ignored by TreeTraverser but we need to
// record it as a dependency
traverse(call)
Expand Down
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,13 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
}

def Inlined_call(self: Inlined)(implicit ctx: Context): Option[Tree /* Term | TypeTree */] = optional(self.call)
def Inlined_bindings(self: Inlined)(implicit ctx: Context): List[Definition] = self.bindings
def Inlined_body(self: Inlined)(implicit ctx: Context): Term = self.expansion

def Inlined_apply(call: Option[Tree /* Term | TypeTree */], bindings: List[Definition], expansion: Term)(implicit ctx: Context): Inlined =
withDefaultPos(ctx => tpd.Inlined(call.getOrElse(tpd.EmptyTree), bindings.map { case b: tpd.MemberDef => b }, expansion)(ctx))
def Inlined_apply(call: Option[Tree /* Term | TypeTree */], expansion: Term)(implicit ctx: Context): Inlined =
withDefaultPos(ctx => tpd.Inlined(call.getOrElse(tpd.EmptyTree), expansion)(ctx))

def Inlined_copy(original: Tree)(call: Option[Tree /* Term | TypeTree */], bindings: List[Definition], expansion: Term)(implicit ctx: Context): Inlined =
tpd.cpy.Inlined(original)(call.getOrElse(tpd.EmptyTree), bindings.asInstanceOf[List[tpd.MemberDef]], expansion)
def Inlined_copy(original: Tree)(call: Option[Tree /* Term | TypeTree */], expansion: Term)(implicit ctx: Context): Inlined =
tpd.cpy.Inlined(original)(call.getOrElse(tpd.EmptyTree), expansion)

type Lambda = tpd.Closure

Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/transform/MegaPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
goTry(cpy.Try(tree)(expr, cases, finalizer), start)
case tree: Inlined =>
implicit val ctx = prepInlined(tree, start)(outerCtx)
val bindings = transformSpecificTrees(tree.bindings, start)
val expansion = transformTree(tree.expansion, start)(inlineContext(tree.call))
goInlined(cpy.Inlined(tree)(tree.call, bindings, expansion), start)
goInlined(cpy.Inlined(tree)(tree.call, expansion), start)
case tree: Return =>
implicit val ctx = prepReturn(tree, start)(outerCtx)
val expr = transformTree(tree.expr, start)
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase

private object dropInlines extends TreeMap {
override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
case Inlined(call, _, _) =>
cpy.Inlined(tree)(call, Nil, Typed(ref(defn.Predef_undefined), TypeTree(tree.tpe)))
case Inlined(call, _) =>
cpy.Inlined(tree)(call, Typed(ref(defn.Predef_undefined), TypeTree(tree.tpe)))
case _ => super.transform(tree)
}
}
Expand Down Expand Up @@ -223,9 +223,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
case _ =>
super.transform(tree1)
}
case Inlined(call, bindings, expansion) if !call.isEmpty =>
case Inlined(call, expansion) if !call.isEmpty =>
val callTrace = Inliner.inlineCallTrace(call.symbol, call.sourcePos)
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(inlineContext(call)))
cpy.Inlined(tree)(callTrace, transform(expansion)(inlineContext(call)))
case tree: Template =>
withNoCheckNews(tree.parents.flatMap(newPart)) {
val templ1 = paramFwd.forwardParamAccessors(tree)
Expand Down
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class ReifyQuotes extends MacroTransform {
if (level == 0 && !ctx.inInlineMethod) {
val body2 =
if (body1.isType) body1
else Inlined(Inliner.inlineCallTrace(ctx.owner, quote.sourcePos), Nil, body1)
else Inlined(Inliner.inlineCallTrace(ctx.owner, quote.sourcePos), body1)
pickledQuote(body2, splices, body.tpe, isType).withSpan(quote.span)
}
else {
Expand Down Expand Up @@ -240,7 +240,7 @@ class ReifyQuotes extends MacroTransform {
// Note that lifted trees are not necessarily expressions and that Inlined nodes are expected to be expressions.
// For example we can have a lifted tree containing the LHS of an assignment (see tests/run-with-compiler/quote-var.scala).
if (splice.isType || outer.embedded.isLiftedSymbol(body.symbol)) hole
else Inlined(EmptyTree, Nil, hole).withSpan(splice.span)
else Inlined(EmptyTree, hole).withSpan(splice.span)
}
}

Expand Down Expand Up @@ -311,7 +311,7 @@ class ReifyQuotes extends MacroTransform {
enclosingInlineds match {
case enclosingInline :: _ =>
// In case a tree was inlined inside of the quote and we this closure corresponds to code within it we need to keep the inlined node.
Inlined(enclosingInline, Nil, closure)(ctx.withSource(lambdaOwner.topLevelClass.source))
Inlined(enclosingInline, closure)(ctx.withSource(lambdaOwner.topLevelClass.source))
case Nil => closure
}
}
Expand Down Expand Up @@ -387,14 +387,13 @@ class ReifyQuotes extends MacroTransform {


object ReifyQuotes {
import tpd._

val name: String = "reifyQuotes"

def toValue(tree: tpd.Tree): Option[Any] = tree match {
case Literal(Constant(c)) => Some(c)
case Block(Nil, e) => toValue(e)
case Inlined(_, Nil, e) => toValue(e)
case Inlined(_, e) => toValue(e)
case _ => None
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object Splicer {
}

protected def interpretQuote(tree: Tree)(implicit env: Env): Object =
new scala.quoted.Exprs.TastyTreeExpr(Inlined(EmptyTree, Nil, tree).withSpan(tree.span))
new scala.quoted.Exprs.TastyTreeExpr(Inlined(EmptyTree, tree).withSpan(tree.span))

protected def interpretTypeQuote(tree: Tree)(implicit env: Env): Object =
new scala.quoted.Types.TreeType(tree)
Expand Down Expand Up @@ -312,7 +312,7 @@ object Splicer {
case quoted: Ident if quoted.symbol.is(InlineByNameProxy) =>
// inline proxy for by-name parameter
quoted.symbol.defTree.asInstanceOf[DefDef].rhs
case Inlined(EmptyTree, _, quoted) => quoted
case Inlined(EmptyTree, quoted) => quoted
case _ => quoted
}
interpretQuote(quoted1)
Expand Down Expand Up @@ -356,7 +356,7 @@ object Splicer {
interpretTree(expr)(newEnv)
case NamedArg(_, arg) => interpretTree(arg)

case Inlined(EmptyTree, Nil, expansion) => interpretTree(expansion)
case Inlined(EmptyTree, expansion) => interpretTree(expansion)

case Typed(expr, _) =>
interpretTree(expr)
Expand Down
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,6 @@ class TreeChecker extends Phase with SymTransformer {
override def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context): Tree =
withDefinedSyms(tree.stats) { super.typedBlock(tree, pt) }

override def typedInlined(tree: untpd.Inlined, pt: Type)(implicit ctx: Context): Tree =
withDefinedSyms(tree.bindings) { super.typedInlined(tree, pt) }

/** Check that all defined symbols have legal owners.
* An owner is legal if it is either the same as the context's owner
* or there's an owner chain of valdefs starting at the context's owner and
Expand Down
Loading