Skip to content

Commit fdeeb40

Browse files
committed
Fix #4811: Widen private[this]/protected[this] just before Flatten
This fix the crash because we don't need to generate a getter or setter for private[this] field anymore. The original documentation for ElimLocals says: This phase drops the Local flag from all private[this] and protected[this] members. This allows subsequent code motions where code is moved from a class to its companion object. It invalidates variance checking, which is consequently disabled when retyping. I believe this is legacy code and not true anymore. This phase is still required to Ycheck Flatten. Not sure why...
1 parent 0db2b36 commit fdeeb40

File tree

6 files changed

+43
-9
lines changed

6 files changed

+43
-9
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class Compiler {
6363
new ElimPackagePrefixes) :: // Eliminate references to package prefixes in Select nodes
6464
List(new CheckStatic, // Check restrictions that apply to @static members
6565
new ElimRepeated, // Rewrite vararg parameters and arguments
66-
new NormalizeFlags, // Rewrite some definition flags
6766
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
6867
new ProtectedAccessors, // Add accessors for protected members
6968
new ExtensionMethods, // Expand methods of value classes with extension methods
@@ -111,7 +110,8 @@ class Compiler {
111110
new LambdaLift, // Lifts out nested functions to class scope, storing free variables in environments
112111
// Note: in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
113112
new ElimStaticThis) :: // Replace `this` references to static objects by global identifiers
114-
List(new Flatten, // Lift all inner classes to package scope
113+
List(new ElimLocals, // Widens private[this] and protected[this] modifiers to just private/protected
114+
new Flatten, // Lift all inner classes to package scope
115115
new RenameLifted, // Renames lifted classes to local numbering scheme
116116
new TransformWildcards, // Replace wildcards with default values
117117
new MoveStatics, // Move static methods to companion classes

compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala renamed to compiler/src/dotty/tools/dotc/transform/ElimLocals.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ import SymDenotations.SymDenotation
99
import MegaPhase.MiniPhase
1010
import Flags._, Symbols._
1111

12-
/** 1. Widens all private[this] and protected[this] qualifiers to just private/protected
13-
* 2. Sets PureInterface flag for traits that only have pure interface members and that
14-
* do not have initialization code. A pure interface member is either an abstract
15-
* or alias type definition or a deferred val or def.
12+
/** Widens private[this] and protected[this] modifiers to just private/protected
1613
*/
17-
class NormalizeFlags extends MiniPhase with SymTransformer {
18-
override def phaseName = "normalizeFlags"
14+
class ElimLocals extends MiniPhase with SymTransformer {
15+
override def phaseName = ElimLocals.name
1916

2017
def transformSym(ref: SymDenotation)(implicit ctx: Context) = {
2118
var newFlags = ref.flags &~ Local
2219
if (newFlags != ref.flags) ref.copySymDenotation(initFlags = newFlags)
2320
else ref
2421
}
2522
}
23+
24+
object ElimLocals {
25+
def name = "elimlocals"
26+
}

compiler/src/dotty/tools/dotc/transform/Flatten.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ class Flatten extends MiniPhase with SymTransformer {
1717

1818
override def phaseName = "flatten"
1919

20+
// private[this] modifiers on classes need be widened before lifting the class
21+
override def runsAfter = Set(ElimLocals.name)
22+
2023
override def changesMembers = true // the phase removes inner classes
2124

2225
private var LiftedDefs: Store.Location[mutable.ListBuffer[Tree]] = _

compiler/src/dotty/tools/dotc/transform/Getters.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Getters extends MiniPhase with SymTransformer {
5454
override def transformSym(d: SymDenotation)(implicit ctx: Context): SymDenotation = {
5555
def noGetterNeeded =
5656
d.is(NoGetterNeeded) ||
57-
d.initial.asInstanceOf[SymDenotation].is(PrivateLocal) && !d.owner.is(Trait) && !isDerivedValueClass(d.owner) && !d.is(Flags.Lazy) ||
57+
d.is(PrivateLocal) && !d.owner.is(Trait) && !isDerivedValueClass(d.owner) && !d.is(Flags.Lazy) ||
5858
d.is(Module) && d.isStatic ||
5959
d.hasAnnotation(defn.ScalaStaticAnnot) ||
6060
d.isSelfSym

tests/pos/flatten.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object A1 {
2+
private[this] class B
3+
4+
private[this] class C {
5+
def cons: B = new B
6+
}
7+
}
8+
9+
class A2 {
10+
private[this] class B
11+
12+
private[this] class C {
13+
def cons: B = new B
14+
}
15+
}

tests/pos/i4811.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class StringOps(val s: String) extends AnyVal {
2+
def lines: Iterator[String] = new collection.AbstractIterator[String] {
3+
private[this] var index = 0
4+
def hasNext: Boolean = false
5+
def next(): String = {
6+
index = 1
7+
""
8+
}
9+
}
10+
}
11+
12+
class FooOps(val s: String) extends AnyVal {
13+
private[this] def bar = 2
14+
def foo = bar
15+
}

0 commit comments

Comments
 (0)