aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-09-11 13:48:02 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-02 16:11:21 +0200
commit975d297cc42dd170fe8869474038a4204771a7a1 (patch)
treed80e5c9c741f0094b6d22723e85ec1c7413943be
parentb743a9b3b98c67fd4e86c7700bf24e3c1d19e2b2 (diff)
downloaddotty-975d297cc42dd170fe8869474038a4204771a7a1.tar.gz
dotty-975d297cc42dd170fe8869474038a4204771a7a1.tar.bz2
dotty-975d297cc42dd170fe8869474038a4204771a7a1.zip
Fix problem related to accessor generation under separate compilation
Accessors were multiply generated under separate compilation. To fix this, the resident body of an inlined function is now the same as the inlined body. Both use accessors where necessary. Previously, only the inlined body used accessors.
-rw-r--r--src/dotty/tools/dotc/typer/Inliner.scala8
-rw-r--r--src/dotty/tools/dotc/typer/ReTyper.scala1
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala18
-rw-r--r--tests/neg/inlineAccess/C_1.scala12
-rw-r--r--tests/run/inlineAccess/C_1.scala7
-rw-r--r--tests/run/inlineAccess/Test_2.scala7
6 files changed, 43 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala
index cd042c476..acf506327 100644
--- a/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/src/dotty/tools/dotc/typer/Inliner.scala
@@ -175,13 +175,19 @@ object Inliner {
def isEvaluated = evaluated
private def ensureEvaluated()(implicit ctx: Context) =
- if (!evaluated) {
+ try if (!evaluated) {
evaluated = true // important to set early to prevent overwrites by attachInlineInfo in typedDefDef
myBody = treeExpr(inlineCtx)
myBody = prepareForInline.transform(myBody)(inlineCtx)
inlining.println(i"inlinable body of ${inlineCtx.owner} = $myBody")
inlineCtx = null // null out to avoid space leaks
}
+ else assert(myBody != null)
+ catch {
+ case ex: AssertionError =>
+ println(i"failure while expanding $inlineMethod")
+ throw ex
+ }
/** The body to inline */
def body(implicit ctx: Context): Tree = {
diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala
index 1db6b54af..2413c0c22 100644
--- a/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -104,4 +104,5 @@ class ReTyper extends Typer {
override def inferView(from: Tree, to: Type)(implicit ctx: Context): Implicits.SearchResult =
Implicits.NoImplicitMatches
override def checkCanEqual(ltp: Type, rtp: Type, pos: Position)(implicit ctx: Context): Unit = ()
+ override def inlineExpansion(mdef: DefDef)(implicit ctx: Context): List[Tree] = mdef :: Nil
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index dde2c866b..60f04b268 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1495,10 +1495,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Some(xtree) =>
traverse(xtree :: rest)
case none =>
- val mdef1 = typed(mdef)
- buf += mdef1
- if (Inliner.hasBodyToInline(mdef1.symbol))
- buf ++= Inliner.removeInlineAccessors(mdef1.symbol)
+ typed(mdef) match {
+ case mdef1: DefDef if Inliner.hasBodyToInline(mdef1.symbol) =>
+ buf ++= inlineExpansion(mdef1)
+ case mdef1 =>
+ buf += mdef1
+ }
traverse(rest)
}
case Thicket(stats) :: rest =>
@@ -1512,6 +1514,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
traverse(stats)
}
+ /** Given an inline method `mdef`, the method rewritten so that its body
+ * uses accessors to access non-public members, followed by the accessor definitions.
+ * Overwritten in Retyper to return `mdef` unchanged.
+ */
+ protected def inlineExpansion(mdef: DefDef)(implicit ctx: Context): List[Tree] =
+ tpd.cpy.DefDef(mdef)(rhs = Inliner.bodyToInline(mdef.symbol)) ::
+ Inliner.removeInlineAccessors(mdef.symbol)
+
def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree =
typed(tree, pt)(ctx retractMode Mode.PatternOrType)
def typedType(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = // todo: retract mode between Type and Pattern?
diff --git a/tests/neg/inlineAccess/C_1.scala b/tests/neg/inlineAccess/C_1.scala
index 349f5b150..841222cf4 100644
--- a/tests/neg/inlineAccess/C_1.scala
+++ b/tests/neg/inlineAccess/C_1.scala
@@ -1,7 +1,9 @@
-package p {
+// error not yet recognized (independent of inlining)
+package p
+private class D
class C {
- protected def f(): Unit = ()
-
- inline def inl() = f() // error (when inlined): not accessible
-}
+ inline def inl(): Unit = {
+ val d = new D() // error (when inlined): not accessible
+ }
}
+
diff --git a/tests/run/inlineAccess/C_1.scala b/tests/run/inlineAccess/C_1.scala
new file mode 100644
index 000000000..349f5b150
--- /dev/null
+++ b/tests/run/inlineAccess/C_1.scala
@@ -0,0 +1,7 @@
+package p {
+class C {
+ protected def f(): Unit = ()
+
+ inline def inl() = f() // error (when inlined): not accessible
+}
+}
diff --git a/tests/run/inlineAccess/Test_2.scala b/tests/run/inlineAccess/Test_2.scala
new file mode 100644
index 000000000..98ea7693a
--- /dev/null
+++ b/tests/run/inlineAccess/Test_2.scala
@@ -0,0 +1,7 @@
+
+object Test {
+ def main(args: Array[String]) = {
+ val c = new p.C()
+ c.inl()
+ }
+}