File tree 2 files changed +18
-2
lines changed
compiler/src/dotty/tools/dotc/transform 2 files changed +18
-2
lines changed Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ import dotty.tools.dotc.core.StdNames._
9
9
import ast ._
10
10
import Trees ._
11
11
import Flags ._
12
+ import NameOps ._
12
13
import SymUtils ._
13
14
import Symbols ._
14
15
import Decorators ._
@@ -211,8 +212,22 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
211
212
val sym = stat.symbol
212
213
assert(isRetained(sym), sym)
213
214
if (! stat.rhs.isEmpty && ! isWildcardArg(stat.rhs))
215
+ /* !!! This should really just be `sym.setter`. However, if we do that, we'll miss
216
+ * setters for mixed in `private var`s. Even though the scope clearly contains the
217
+ * setter symbol with the correct Name structure (since the `find` finds it),
218
+ * `.decl(setterName)` used by `.setter` through `.accessorNamed` will *not* find it.
219
+ * Could it be that the hash table of the `Scope` is corrupted?
220
+ * We still try `sym.setter` first as an optimization, since it will work for all
221
+ * public vars in traits and all (public or private) vars in classes.
222
+ */
223
+ val symSetter =
224
+ if sym.setter.exists then
225
+ sym.setter
226
+ else
227
+ val setterName = sym.asTerm.name.setterName
228
+ sym.owner.info.decls.find(d => d.is(Accessor ) && d.name == setterName)
214
229
val setter =
215
- if (sym.setter. exists) sym.setter
230
+ if (symSetter. exists) symSetter
216
231
else sym.accessorNamed(Mixin .traitSetterName(sym.asTerm))
217
232
constrStats += Apply (ref(setter), intoConstr(stat.rhs, sym).withSpan(stat.span) :: Nil )
218
233
clsStats += cpy.DefDef (stat)(rhs = EmptyTree )
Original file line number Diff line number Diff line change @@ -175,7 +175,8 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
175
175
ctx.atPhase(thisPhase) { sym.isOneOf(flags) }
176
176
177
177
private def needsTraitSetter (sym : Symbol )(implicit ctx : Context ): Boolean =
178
- sym.isGetter && ! wasOneOf(sym, DeferredOrLazy | ParamAccessor ) && ! sym.setter.exists
178
+ sym.isGetter && ! wasOneOf(sym, DeferredOrLazy | ParamAccessor )
179
+ && ctx.atPhase(thisPhase) { ! sym.setter.exists }
179
180
&& ! sym.info.resultType.isInstanceOf [ConstantType ]
180
181
181
182
private def makeTraitSetter (getter : TermSymbol )(implicit ctx : Context ): Symbol =
You can’t perform that action at this time.
0 commit comments