From 7bf29f00c85a0efe59bbca548767dcd21ec2b14e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 4 May 2015 10:50:33 +0200 Subject: [PATCH 1/3] Treat references to modules and lazy vals as outer references Previously, we considered only methods. #503 shows that this is wrong. --- src/dotty/tools/dotc/transform/ExplicitOuter.scala | 4 +++- tests/pos/i503.scala | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i503.scala diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 20e367e1f382..09f0d695d60c 100644 --- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -213,7 +213,7 @@ object ExplicitOuter { case id: Ident => id.tpe match { case ref @ TermRef(NoPrefix, _) => - ref.symbol.is(Method) && isOuter(id.symbol.owner.enclosingClass) + ref.symbol.is(Hoistable) && isOuter(id.symbol.owner.enclosingClass) // methods will be placed in enclosing class scope by LambdaLift, so they will get // an outer path then. case _ => false @@ -225,6 +225,8 @@ object ExplicitOuter { } } + private final val Hoistable = Method | Lazy | Module + /** The outer prefix implied by type `tpe` */ private def outerPrefix(tpe: Type)(implicit ctx: Context): Type = tpe match { case tpe: TypeRef => diff --git a/tests/pos/i503.scala b/tests/pos/i503.scala new file mode 100644 index 000000000000..93f275c4d619 --- /dev/null +++ b/tests/pos/i503.scala @@ -0,0 +1,9 @@ +class HelloWorld { + def main(args: Array[String]): Unit = { + object TypeBool; + + class Fct { + def g(x : Int) = TypeBool // breaks. + } + } +} From 99b9dbd3246fb2906dc082f6c6175a406259fae7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 4 May 2015 10:51:36 +0200 Subject: [PATCH 2/3] Re-use MethodOrLazy in constructors. A search revealed duplicates, which are eliminated now. --- src/dotty/tools/dotc/transform/Constructors.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dotty/tools/dotc/transform/Constructors.scala b/src/dotty/tools/dotc/transform/Constructors.scala index 6fb67cd22004..8aae3af5ba88 100644 --- a/src/dotty/tools/dotc/transform/Constructors.scala +++ b/src/dotty/tools/dotc/transform/Constructors.scala @@ -37,7 +37,7 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor */ override def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = { def ownerBecomesConstructor(owner: Symbol): Boolean = - (owner.isLocalDummy || owner.isTerm && !owner.is(Method | Lazy)) && + (owner.isLocalDummy || owner.isTerm && !owner.is(MethodOrLazy)) && owner.owner.isClass if (ownerBecomesConstructor(sym.owner)) sym.copySymDenotation(owner = sym.owner.enclosingClass.primaryConstructor) @@ -54,9 +54,8 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor * constructor. */ private def mightBeDropped(sym: Symbol)(implicit ctx: Context) = - sym.is(Private, butNot = KeeperFlags) && !sym.is(MutableParamAccessor) + sym.is(Private, butNot = MethodOrLazy) && !sym.is(MutableParamAccessor) - private final val KeeperFlags = Method | Lazy private final val MutableParamAccessor = allOf(Mutable, ParamAccessor) override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo): Tree = { From 14d506a86f5920ac50777f1bbb7aade0557d6122 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 4 May 2015 10:51:56 +0200 Subject: [PATCH 3/3] New tests Added test for previous PR on super accessors. Updated test for #503 to check both inner classes and inner traits. --- tests/pos/i503.scala | 6 +++++- tests/pos/superacc.scala | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/pos/superacc.scala diff --git a/tests/pos/i503.scala b/tests/pos/i503.scala index 93f275c4d619..fd25dc979af4 100644 --- a/tests/pos/i503.scala +++ b/tests/pos/i503.scala @@ -3,7 +3,11 @@ class HelloWorld { object TypeBool; class Fct { - def g(x : Int) = TypeBool // breaks. + def g(x : Int) = TypeBool + } + + trait Fct2 { + def g(x : Int) = TypeBool } } } diff --git a/tests/pos/superacc.scala b/tests/pos/superacc.scala new file mode 100644 index 000000000000..91397003db70 --- /dev/null +++ b/tests/pos/superacc.scala @@ -0,0 +1,17 @@ +// scenario one: supercalls in traits +abstract class C { + def foo: Int = 2 + def baz: Int = 2 +} + +trait T extends C { + override def foo = super.foo + 1 +} + + +// scenario 2: supercalls in nested classes +class D extends C with T { + class I { + val x= D.super.baz + } +}