aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala9
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala4
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreePickler.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Inliner.scala47
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala5
-rw-r--r--tests/run/inlineForeach.scala12
6 files changed, 52 insertions, 27 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
index 0593e8159..6d0c7d8e3 100644
--- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala
+++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
@@ -6,6 +6,8 @@ import core._
import Types._, Contexts._, Constants._, Names._, Flags._
import SymDenotations._, Symbols._, Annotations._, Trees._, Symbols._
import Denotations._, Decorators._
+import typer.Inliner
+import config.Printers.inlining
import dotty.tools.dotc.transform.SymUtils._
/** A map that applies three functions and a substitution together to a tree and
@@ -92,7 +94,12 @@ final class TreeTypeMap(
case ddef @ DefDef(name, tparams, vparamss, tpt, _) =>
val (tmap1, tparams1) = transformDefs(ddef.tparams)
val (tmap2, vparamss1) = tmap1.transformVParamss(vparamss)
- cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(ddef.rhs))
+ val res = cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(ddef.rhs))
+ if (Inliner.hasBodyToInline(res.symbol)) {
+ inlining.println(i"update inline body ${res.symbol}")
+ Inliner.updateInlineBody(res.symbol, res.rhs)
+ }
+ res
case blk @ Block(stats, expr) =>
val (tmap1, stats1) = transformDefs(stats)
val expr1 = tmap1.transform(expr)
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index a0a353c13..cc7cefbac 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -20,7 +20,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
override def isType = op.isTypeName
}
- /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */
+ /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice
+ * @param owner The current owner at the time the tree was defined
+ */
abstract case class TypedSplice(tree: tpd.Tree)(val owner: Symbol) extends ProxyTree {
def forwardTo = tree
}
diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 12ab050f6..99a3ff85c 100644
--- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -572,7 +572,7 @@ class TreePickler(pickler: TastyPickler) {
def pickle(trees: List[Tree])(implicit ctx: Context) = {
trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree))
- assert(forwardSymRefs.isEmpty, i"unresolved symbols: ${forwardSymRefs.keySet.toList}%, % when pickling $trees%\n %")
+ assert(forwardSymRefs.isEmpty, i"unresolved symbols: ${forwardSymRefs.keySet.toList}%, % when pickling ${ctx.source}")
}
def compactify() = {
diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala
index e9c054ff2..ef67384ff 100644
--- a/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/src/dotty/tools/dotc/typer/Inliner.scala
@@ -214,17 +214,18 @@ object Inliner {
/** The accessor defs to non-public members which need to be defined
* together with the inline method
*/
- def removeAccessors(implicit ctx: Context): List[MemberDef] = {
+ def accessors(implicit ctx: Context): List[MemberDef] = {
ensureEvaluated()
- val res = myAccessors.toList
- myAccessors.clear()
- res
+ myAccessors.toList
}
}
/** A key to be used in an attachment for `@inline` annotations */
private val InlineInfo = new Property.Key[InlineInfo]
+ /** A key to be used in an attachment for `@inline` annotations */
+ private val InlineBody = new Property.Key[Tree]
+
/** A key to be used in a context property that tracks enclosing inlined calls */
private val InlinedCalls = new Property.Key[List[Tree]] // to be used in context
@@ -239,37 +240,51 @@ object Inliner {
*/
def registerInlineInfo(
sym: SymDenotation, treeExpr: Context => Tree, inlineCtxFn: Context => Context)(implicit ctx: Context): Unit = {
+ val inlineAnnotTree = sym.unforcedAnnotation(defn.InlineAnnot).get.tree
+ if (inlineAnnotTree.getAttachment(InlineBody).isEmpty)
+ inlineAnnotTree.getAttachment(InlineInfo) match {
+ case Some(inlineInfo) if inlineInfo.isEvaluated => // keep existing attachment
+ case _ =>
+ if (!ctx.isAfterTyper)
+ inlineAnnotTree.putAttachment(InlineInfo, new InlineInfo(treeExpr, inlineCtxFn))
+ }
+ }
+
+ /** Register an evaluated inline body for `sym` */
+ def updateInlineBody(sym: SymDenotation, body: Tree)(implicit ctx: Context): Unit = {
val inlineAnnot = sym.unforcedAnnotation(defn.InlineAnnot).get
- inlineAnnot.tree.getAttachment(InlineInfo) match {
- case Some(inlineInfo) if inlineInfo.isEvaluated => // keep existing attachment
- case _ =>
- if (!ctx.isAfterTyper)
- inlineAnnot.tree.putAttachment(InlineInfo, new InlineInfo(treeExpr, inlineCtxFn))
- }
+ assert(inlineAnnot.tree.putAttachment(InlineBody, body).isDefined)
}
/** Optionally, the inline info attached to the `@inline` annotation of `sym`. */
private def inlineInfo(sym: SymDenotation)(implicit ctx: Context): Option[InlineInfo] =
sym.getAnnotation(defn.InlineAnnot).get.tree.getAttachment(InlineInfo)
- /** Definition is an inline method with a known body to inline (note: definitions coming
+ /** Optionally, the inline body attached to the `@inline` annotation of `sym`. */
+ private def inlineBody(sym: SymDenotation)(implicit ctx: Context): Option[Tree] =
+ sym.getAnnotation(defn.InlineAnnot).get.tree.getAttachment(InlineBody)
+
+ /** Definition is an inline method with a known body to inline (note: definitions coming
* from Scala2x class files might be `@inline`, but still lack that body.
*/
def hasBodyToInline(sym: SymDenotation)(implicit ctx: Context): Boolean =
- sym.isInlineMethod && inlineInfo(sym).isDefined
+ sym.isInlineMethod && (inlineInfo(sym).isDefined || inlineBody(sym).isDefined)
/** The body to inline for method `sym`.
* @pre hasBodyToInline(sym)
*/
def bodyToInline(sym: SymDenotation)(implicit ctx: Context): Tree =
- inlineInfo(sym).get.body
+ inlineInfo(sym).map(_.body).getOrElse(inlineBody(sym).get)
/** The accessors to non-public members needed by the inlinable body of `sym`.
* @pre hasBodyToInline(sym)
*/
-
- def removeInlineAccessors(sym: SymDenotation)(implicit ctx: Context): List[MemberDef] =
- inlineInfo(sym).get.removeAccessors
+ def removeInlineAccessors(sym: SymDenotation)(implicit ctx: Context): List[MemberDef] = {
+ val inlineAnnotTree = sym.getAnnotation(defn.InlineAnnot).get.tree
+ val inlineInfo = inlineAnnotTree.removeAttachment(InlineInfo).get
+ inlineAnnotTree.putAttachment(InlineBody, inlineInfo.body)
+ inlineInfo.accessors
+ }
/** Try to inline a call to a `@inline` method. Fail with error if the maximal
* inline depth is exceeded.
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 4c7d1c50d..885bc56d6 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1359,10 +1359,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tree1: TypeTree => tree1 // no change owner necessary here ...
case tree1: Ident => tree1 // ... or here
case tree1 =>
- if (ctx.owner ne tree.owner) {
- println(i"changing owner of $tree1 from ${tree.owner} to ${ctx.owner}")
- tree1.changeOwner(tree.owner, ctx.owner)
- }
+ if (ctx.owner ne tree.owner) tree1.changeOwner(tree.owner, ctx.owner)
else tree1
}
diff --git a/tests/run/inlineForeach.scala b/tests/run/inlineForeach.scala
index 0c6135c6d..1389ad6c4 100644
--- a/tests/run/inlineForeach.scala
+++ b/tests/run/inlineForeach.scala
@@ -17,7 +17,7 @@ object Test {
implicit class intWrapper(private val start: Int) extends AnyVal {
def until(end: Int) = new Range(start, end)
def to(limit: Int) = new Range(start, limit + 1)
- }/*
+ }
def matmul(xs: Array[Array[Double]], ys: Array[Array[Double]]): Array[Array[Double]] = {
def nrows = xs.length
@@ -34,11 +34,15 @@ object Test {
}
zs
}
-*/
+
def main(args: Array[String]) = {
- /* 1.until(10).foreach(i => println(i))
- 1.until(10).foreach(println(_))*/
+ 1.until(10).foreach(i => println(i))
+ 1.until(10).foreach(println(_))
1.until(10).foreach(println)
for (i <- 1 to 10) println(i)
+
+ for (k1 <- 1 to 10)
+ for (k2 <- 1 to 10)
+ println(s"$k1")
}
}