@@ -30,7 +30,20 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
30
30
import tpd ._
31
31
32
32
override def phaseName : String = " constructors"
33
- override def runsAfter : Set [Class [_ <: Phase ]] = Set (classOf [Memoize ], classOf [HoistSuperArgs ])
33
+ override def runsAfter : Set [Class [_ <: Phase ]] = Set (classOf [HoistSuperArgs ])
34
+ override def runsAfterGroupsOf : Set [Class [_ <: Phase ]] = Set (classOf [Memoize ])
35
+ // Memoized needs to be finished because we depend on the ownerchain after Memoize
36
+ // when checking whether an ident is an access in a constructor or outside it.
37
+ // This test is done in the right-hand side of a value definition. If Memoize
38
+ // was in the same group as Constructors, the test on the rhs ident would be
39
+ // performed before the rhs undergoes the owner change. This would lead
40
+ // to more symbols being retained as parameters. Test case in run/capturing.scala.
41
+
42
+ /** The private vals that are known to be retained as class fields */
43
+ private val retainedPrivateVals = mutable.Set [Symbol ]()
44
+
45
+ /** The private vals whose definition comes before the current focus */
46
+ private val seenPrivateVals = mutable.Set [Symbol ]()
34
47
35
48
// Collect all private parameter accessors and value definitions that need
36
49
// to be retained. There are several reasons why a parameter accessor or
@@ -40,14 +53,10 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
40
53
// 3. It is accessed on an object other than `this`
41
54
// 4. It is a mutable parameter accessor
42
55
// 5. It is has a wildcard initializer `_`
43
- private val retainedPrivateVals = mutable.Set [Symbol ]()
44
- private val seenPrivateVals = mutable.Set [Symbol ]()
45
-
46
56
private def markUsedPrivateSymbols (tree : RefTree )(implicit ctx : Context ): Unit = {
47
57
48
58
val sym = tree.symbol
49
- def retain () =
50
- retainedPrivateVals.add(sym)
59
+ def retain () = retainedPrivateVals.add(sym)
51
60
52
61
if (sym.exists && sym.owner.isClass && mightBeDropped(sym)) {
53
62
val owner = sym.owner.asClass
@@ -58,7 +67,8 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
58
67
val method = ctx.owner.enclosingMethod
59
68
method.isPrimaryConstructor && ctx.owner.enclosingClass == owner
60
69
}
61
- if (inConstructor && (sym.is(ParamAccessor ) || seenPrivateVals.contains(sym))) {
70
+ if (inConstructor &&
71
+ (sym.is(ParamAccessor ) || seenPrivateVals.contains(sym))) {
62
72
// used inside constructor, accessed on this,
63
73
// could use constructor argument instead, no need to retain field
64
74
}
@@ -79,8 +89,7 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
79
89
}
80
90
81
91
override def transformValDef (tree : tpd.ValDef )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
82
- if (mightBeDropped(tree.symbol))
83
- (if (isWildcardStarArg(tree.rhs)) retainedPrivateVals else seenPrivateVals) += tree.symbol
92
+ if (mightBeDropped(tree.symbol)) seenPrivateVals += tree.symbol
84
93
tree
85
94
}
86
95
0 commit comments