From 741128ca3aef5594e8faafcd131061b578b568f1 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Fri, 24 Aug 2018 19:53:18 +0200
Subject: [PATCH 1/2] enclosingInlineds: Clarify invariants
---
compiler/src/dotty/tools/dotc/ast/Trees.scala | 7 +++++--
compiler/src/dotty/tools/dotc/ast/tpd.scala | 19 ++++++++++++++-----
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index cf3b1359cfe6..d12a85150f6f 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -574,8 +574,9 @@ object Trees {
/** A tree representing inlined code.
*
- * @param call Info about the original call that was inlined
- * Until PostTyper, this is the full call, afterwards only
+ * @param call Tree representing the original call that was inlined.
+ * If EmptyTree: this represents an argument actual tree.
+ * Otherwise: 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.
@@ -587,6 +588,8 @@ object Trees {
* 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.
+ * Call argument trees (whether kept in `bindings` or inlined in the body)
+ * are typed in the caller's context.
*/
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, bindings: List[MemberDef[T]], expansion: Tree[T])
extends Tree[T] {
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index f4f4535931c4..169d9e67c440 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -1079,15 +1079,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
}
+ //inlineContext, enclosingInlineds, sourceFile and Decorators.sourcePos work closely together.
+
/** A key to be used in a context property that tracks enclosing inlined calls */
private val InlinedCalls = new Property.Key[List[Tree]]
- /** Record an enclosing inlined call.
- * EmptyTree calls (for parameters) cancel the next-enclosing call in the list instead of being added to it.
- * We assume parameters are never nested inside parameters.
+ /** Record an enclosing inlined call in enclosingInlineds, and produces the context for visiting
+ * Inlined(call, ...).
+ *
+ * Invariants:
+ * - enclosingInlineds never contains EmptyTree nodes.
+ * - if enclosingInlineds.nonEmpty, the current tree comes from the file *defining* enclosingInlineds.head.symbol;
+ * this is exploited in e.g. Decorators.sourcePos.
+ *
+ * Arguments of inlined calls (enclosed in Inlined(EmptyTree, ...)) come instead from the call-site, so
+ * inlineContext(EmptyTree) pops the enclosing call.
*/
override def inlineContext(call: Tree)(implicit ctx: Context): Context = {
- // We assume enclosingInlineds is already normalized, and only process the new call with the head.
+ // enclosingInlineds is already normalized, so we only process the new call with the head.
val oldIC = enclosingInlineds
val newIC = (call, oldIC) match {
case (t, t1 :: ts2) if t.isEmpty =>
@@ -1106,7 +1115,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
/** The source file where the symbol of the `inline` method referred to by `call`
* is defined
*/
- def sourceFile(call: Tree)(implicit ctx: Context) = {
+ def sourceFile(call: Tree)(implicit ctx: Context): SourceFile = {
val file = call.symbol.sourceFile
val encoding = ctx.settings.encoding.value
if (file != null && file.exists) new SourceFile(file, Codec(encoding)) else NoSource
From ed3137f20f6f6e60541172ae06de121ba97da244 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Fri, 24 Aug 2018 21:58:37 +0200
Subject: [PATCH 2/2] Highlight inline argument in printed trees
---
compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 7ae4192c7bd6..41f97ab21a6f 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -385,8 +385,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case SeqLiteral(elems, elemtpt) =>
"[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]"
case tree @ Inlined(call, bindings, body) =>
- (("/* inlined from " ~ toText(call) ~ " */ ") `provided`
- !call.isEmpty && !homogenizedView && !ctx.settings.YshowNoInline.value) ~
+ ((if (!call.isEmpty) "/* inlined from " ~ toText(call) ~ " */ " else "/* inline arg */ ": Text) `provided`
+ !homogenizedView && !ctx.settings.YshowNoInline.value) ~
blockText(bindings :+ body)
case tpt: untpd.DerivedTypeTree =>
""