aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorNicolas Stucki <nicolas.stucki@gmail.com>2017-01-10 14:45:02 +0100
committerNicolas Stucki <nicolas.stucki@gmail.com>2017-01-10 14:48:34 +0100
commit1cb50ca13640e3e181d8e7d9b47029a6099a81d6 (patch)
tree1265d785be8e303273ad947c16a5512a8ae7dd4a /compiler/src/dotty/tools/dotc/typer/Typer.scala
parent4d7b2479e85e9f674056e8a243c07675fc9fa51f (diff)
downloaddotty-1cb50ca13640e3e181d8e7d9b47029a6099a81d6.tar.gz
dotty-1cb50ca13640e3e181d8e7d9b47029a6099a81d6.tar.bz2
dotty-1cb50ca13640e3e181d8e7d9b47029a6099a81d6.zip
Fix #1878: Use Inline on final vals.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala22
1 files changed, 22 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index b70a51d1e..a053a0b0d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1173,6 +1173,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (sym.is(Inline, butNot = DeferredOrParamAccessor))
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
patchIfLazy(vdef1)
+ patchFinalVals(vdef1)
vdef1
}
@@ -1185,6 +1186,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
patch(Position(toUntyped(vdef).pos.start), "@volatile ")
}
+ /** Adds inline to final vals with idempotent rhs
+ *
+ * duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
+ * and instead return the value. This seemingly minor optimization has huge effect on initialization
+ * order and the values that can be observed during superconstructor call
+ *
+ * see remark about idempotency in PostTyper#normalizeTree
+ */
+ private def patchFinalVals(vdef: ValDef)(implicit ctx: Context): Unit = {
+ def isFinalInlinableVal(sym: Symbol): Boolean = {
+ sym.is(Final, butNot = Mutable) &&
+ isIdempotentExpr(vdef.rhs) /* &&
+ ctx.scala2Mode (stay compatible with Scala2 for now) */
+ }
+ val sym = vdef.symbol
+ sym.info match {
+ case info: ConstantType if isFinalInlinableVal(sym) && !ctx.settings.YnoInline.value => sym.setFlag(Inline)
+ case _ =>
+ }
+ }
+
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
val DefDef(name, tparams, vparamss, tpt, _) = ddef
completeAnnotations(ddef, sym)