diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeTypeMap.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Decorators.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inliner.scala | 46 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 |
4 files changed, 33 insertions, 27 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala index a35fe2e8f..0593e8159 100644 --- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -97,6 +97,10 @@ final 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 cdef @ CaseDef(pat, guard, rhs) => val tmap = withMappedSyms(patVars(pat)) val pat1 = tmap.transform(pat) diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala index cd4941c72..64f50173c 100644 --- a/src/dotty/tools/dotc/core/Decorators.scala +++ b/src/dotty/tools/dotc/core/Decorators.scala @@ -8,7 +8,7 @@ import util.Positions.Position, util.SourcePosition import collection.mutable.ListBuffer import dotty.tools.dotc.transform.TreeTransforms._ import typer.Inliner -import ast.tpd.Inlined +import ast.tpd.Tree import scala.language.implicitConversions import printing.Formatting._ @@ -151,9 +151,9 @@ object Decorators { } implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = { - def recur(inlineds: List[Inlined], pos: Position): SourcePosition = inlineds match { - case inlined :: rest => - Inliner.sourceFile(inlined).atPos(pos).withOuter(recur(rest, inlined.call.pos)) + def recur(inlinedCalls: List[Tree], pos: Position): SourcePosition = inlinedCalls match { + case inlinedCall :: rest => + Inliner.sourceFile(inlinedCall).atPos(pos).withOuter(recur(rest, inlinedCall.pos)) case empty => ctx.source.atPos(pos) } diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala index 68bc55860..88d8b0de5 100644 --- a/src/dotty/tools/dotc/typer/Inliner.scala +++ b/src/dotty/tools/dotc/typer/Inliner.scala @@ -31,7 +31,7 @@ object Inliner { private val InlinedBody = new Property.Key[InlinedBody] // to be used as attachment - private val InlinedCall = new Property.Key[List[tpd.Inlined]] // to be used in context + private val InlinedCalls = new Property.Key[List[Tree]] // to be used in context def attachBody(inlineAnnot: Annotation, tree: => Tree)(implicit ctx: Context): Unit = inlineAnnot.tree.putAttachment(InlinedBody, new InlinedBody(tree)) @@ -71,16 +71,13 @@ object Inliner { } } - def inlineCall(tree: Tree, pt: Type)(implicit ctx: Context): Tree = { - if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) { - val rhs = inlinedBody(tree.symbol) - val inlined = new Inliner(tree, rhs).inlined - new Typer().typedUnadapted(inlined, pt) - } else errorTree(tree, + def inlineCall(tree: Tree, pt: Type)(implicit ctx: Context): Tree = + if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) + new Inliner(tree, inlinedBody(tree.symbol)).inlined(pt) + else errorTree(tree, i"""Maximal number of successive inlines (${ctx.settings.xmaxInlines.value}) exceeded, | Maybe this is caused by a recursive inline method? | You can use -Xmax:inlines to change the limit.""") - } def dropInlined(inlined: tpd.Inlined)(implicit ctx: Context): Tree = { val reposition = new TreeMap { @@ -90,20 +87,21 @@ object Inliner { tpd.seq(inlined.bindings, reposition.transform(inlined.expansion)) } - def inlineContext(tree: untpd.Inlined)(implicit ctx: Context): Context = - ctx.fresh.setProperty(InlinedCall, tree :: enclosingInlineds) + def inlineContext(call: Tree)(implicit ctx: Context): Context = + ctx.fresh.setProperty(InlinedCalls, call :: enclosingInlineds) - def enclosingInlineds(implicit ctx: Context): List[Inlined] = - ctx.property(InlinedCall).getOrElse(Nil) + def enclosingInlineds(implicit ctx: Context): List[Tree] = + ctx.property(InlinedCalls).getOrElse(Nil) - def sourceFile(inlined: Inlined)(implicit ctx: Context) = { - val file = inlined.call.symbol.sourceFile + def sourceFile(call: Tree)(implicit ctx: Context) = { + val file = call.symbol.sourceFile if (file.exists) new SourceFile(file) else NoSource } } class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { import tpd._ + import Inliner._ private def decomposeCall(tree: Tree): (Tree, List[Tree], List[List[Tree]]) = tree match { case Apply(fn, args) => @@ -154,10 +152,12 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { case argtpe => val (bindingFlags, bindingType) = if (isByName) (Method, ExprType(argtpe.widen)) else (EmptyFlags, argtpe.widen) - val binding = newSym(name, bindingFlags, bindingType).asTerm - bindingsBuf += - (if (isByName) DefDef(binding, arg) else ValDef(binding, arg)) - binding.termRef + val boundSym = newSym(name, bindingFlags, bindingType).asTerm + val binding = + if (isByName) DefDef(boundSym, arg.changeOwner(ctx.owner, boundSym)) + else ValDef(boundSym, arg) + bindingsBuf += binding + boundSym.termRef } } computeParamBindings(tp.resultType, targs, argss.tail) @@ -192,7 +192,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { private def outerLevel(sym: Symbol) = sym.name.drop(nme.SELF.length).toString.toInt - val inlined = { + def inlined(pt: Type) = { rhs.foreachSubTree(registerLeaf) val accessedSelfSyms = @@ -236,9 +236,11 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { } val inliner = new TreeTypeMap(typeMap, treeMap, meth :: Nil, ctx.owner :: Nil) - val Block(bindings: List[MemberDef], expansion) = - inliner(Block(bindingsBuf.toList, rhs)).withPos(call.pos) - val result = tpd.Inlined(call, bindings, expansion) + val bindings = bindingsBuf.toList.map(_.withPos(call.pos)) + val expansion = inliner(rhs.withPos(call.pos)) + + val expansion1 = new Typer().typed(expansion, pt)(inlineContext(call)) + val result = tpd.Inlined(call, bindings, expansion1) inlining.println(i"inlining $call\n --> \n$result") result diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index e809605f4..09259b361 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -947,7 +947,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedInlined(tree: untpd.Inlined, pt: Type)(implicit ctx: Context): Inlined = { val (exprCtx, bindings1) = typedBlockStats(tree.bindings) - val expansion1 = typed(tree.expansion, pt)(Inliner.inlineContext(tree)(exprCtx)) + val expansion1 = typed(tree.expansion, pt)(Inliner.inlineContext(tree.call)(exprCtx)) cpy.Inlined(tree)(tree.call, bindings1.asInstanceOf[List[MemberDef]], expansion1) .withType(expansion1.tpe) } |