Skip to content

Commit 22a6f4e

Browse files
committed
Eliminate outer selections in separate phase
Needs to be done after ExplicitOuter to make sure all needed outer accessors have been installed.
1 parent e3383fb commit 22a6f4e

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class Compiler {
7575
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods
7676
new Getters, // Replace non-private vals and vars with getter defs (fields are added later)
7777
new ElimByName, // Expand by-name parameter references
78+
new ElimOuterSelect, // Expand outer selections
7879
new AugmentScala2Traits, // Expand traits defined in Scala 2.x to simulate old-style rewritings
7980
new ResolveSuper, // Implement super accessors and add forwarders to trait methods
8081
new Simplify, // Perform local optimizations, simplified versions of what linker does.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import TreeTransforms._
6+
import Contexts.Context
7+
import Flags._
8+
import SymUtils._
9+
import Symbols._
10+
import SymDenotations._
11+
import Types._
12+
import Decorators._
13+
import DenotTransformers._
14+
import StdNames._
15+
import NameOps._
16+
import NameKinds.OuterSelectName
17+
import ast.Trees._
18+
import dotty.tools.dotc.ast.tpd
19+
import util.Positions._
20+
import Names._
21+
22+
import collection.mutable
23+
import ResolveSuper._
24+
25+
import scala.collection.immutable.::
26+
27+
/** This phase rewrites outer selects `E.n_<outer>` which were introduced by
28+
* inlining to outer paths.
29+
*/
30+
class ElimOuterSelect extends MiniPhaseTransform { thisTransform =>
31+
import ast.tpd._
32+
33+
override def phaseName: String = "elimOuterSelect"
34+
35+
override def runsAfterGroupsOf = Set(classOf[ExplicitOuter])
36+
// ExplicitOuter needs to have run to completion before so that all classes
37+
// that need an outer accessor have one.
38+
39+
/** Convert a selection of the form `qual.n_<outer>` to an outer path from `qual` of
40+
* length `n`.
41+
*/
42+
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
43+
tree.name match {
44+
case OuterSelectName(_, nhops) =>
45+
val SkolemType(tp) = tree.tpe
46+
ExplicitOuter.outer.path(start = tree.qualifier, count = nhops).ensureConforms(tp)
47+
case _ => tree
48+
}
49+
}

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import core.Decorators._
1111
import core.StdNames.nme
1212
import core.Names._
1313
import core.NameOps._
14-
import core.NameKinds.OuterSelectName
1514
import ast.Trees._
1615
import SymUtils._
1716
import dotty.tools.dotc.ast.tpd
@@ -62,14 +61,6 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
6261

6362
override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isClass
6463

65-
/** Convert a selection of the form `qual.C_<OUTER>` to an outer path from `qual` to `C` */
66-
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
67-
tree.name match {
68-
case OuterSelectName(_, nhops) =>
69-
outer.path(start = tree.qualifier, count = nhops).ensureConforms(tree.tpe)
70-
case _ => tree
71-
}
72-
7364
/** First, add outer accessors if a class does not have them yet and it references an outer this.
7465
* If the class has outer accessors, implement them.
7566
* Furthermore, if a parent trait might have an outer accessor,

tests/pos/i3130a.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object O {
2+
new D(2).DD.apply()
3+
}
4+
5+
class D(val x: Int) {
6+
class DD()
7+
object DD {
8+
inline def apply() = x // new DD()
9+
}
10+
}

tests/pos/i3130c.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
trait Test {
2+
trait Global {
3+
type Tree
4+
def get: Tree
5+
}
6+
7+
trait TreeBuilder {
8+
val global: Global
9+
inline def set(tree: global.Tree) = {}
10+
}
11+
12+
val nsc: Global
13+
14+
trait FileImpl {
15+
object treeBuilder extends TreeBuilder {
16+
val global: nsc.type = nsc
17+
}
18+
treeBuilder.set(nsc.get)
19+
}
20+
def file: FileImpl
21+
22+
file.treeBuilder.set(nsc.get)
23+
}

0 commit comments

Comments
 (0)