aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/Compiler.scala3
-rw-r--r--src/dotty/tools/dotc/transform/RestoreScopes.scala36
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--test/dotc/tests.scala2
4 files changed, 40 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index cb70480ce..d4fa7e671 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -56,7 +56,8 @@ class Compiler {
List(new CapturedVars,
new Constructors),
List(new LambdaLift,
- new Flatten)
+ new Flatten,
+ new RestoreScopes)
)
var runId = 1
diff --git a/src/dotty/tools/dotc/transform/RestoreScopes.scala b/src/dotty/tools/dotc/transform/RestoreScopes.scala
new file mode 100644
index 000000000..4a4252326
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/RestoreScopes.scala
@@ -0,0 +1,36 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import DenotTransformers.IdentityDenotTransformer
+import Contexts.Context
+import Symbols._
+import Scopes._
+import collection.mutable
+import TreeTransforms.MiniPhaseTransform
+import ast.Trees._
+import TreeTransforms.TransformerInfo
+
+/** The preceding lambda lift and flatten phases move symbols to different scopes
+ * and rename them. This miniphase cleans up afterwards and makes sure that all
+ * class scopes contain the symbols defined in them.
+ */
+class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+ import ast.tpd._
+ override def phaseName = "restoreScopes"
+
+ override def treeTransformPhase = thisTransform.next
+
+ override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo) = {
+ val TypeDef(_, _, Template(constr, _, _, body)) = tree
+ val restoredDecls = newScope
+ for (stat <- constr :: body)
+ if (stat.isInstanceOf[MemberDef] && stat.symbol.exists)
+ restoredDecls.enter(stat.symbol)
+ val cinfo = tree.symbol.asClass.classInfo
+ tree.symbol.copySymDenotation(
+ info = cinfo.derivedClassInfo( // Dotty deviation: Cannot expand cinfo inline without a type error
+ decls = restoredDecls: Scope)).installAfter(thisTransform)
+ tree
+ }
+}
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 035f19028..a237e7781 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -461,7 +461,7 @@ trait Applications extends Compatibility { self: Typer =>
val result = {
var typedArgs = typedArgBuf.toList
- val app0 = cpy.Apply(app)(normalizedFun, typedArgs)
+ def app0 = cpy.Apply(app)(normalizedFun, typedArgs) // needs to be a `def` because typedArgs can change later
val app1 =
if (!success) app0.withType(ErrorType)
else {
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index ac1fbe735..a52f79abd 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -15,7 +15,7 @@ class tests extends CompilerTest {
implicit val defaultOptions = noCheckOptions ++ List(
"-Yno-deep-subtypes",
- "-Ycheck:patternMatcher,gettersSetters,flatten"
+ "-Ycheck:patternMatcher,gettersSetters,restoreScopes"
)
val twice = List("#runs", "2", "-YnoDoubleBindings")