File tree Expand file tree Collapse file tree 2 files changed +18
-2
lines changed
compiler/src/dotty/tools/dotc/transform Expand file tree Collapse file tree 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._
99import ast ._
1010import Trees ._
1111import Flags ._
12+ import NameOps ._
1213import SymUtils ._
1314import Symbols ._
1415import Decorators ._
@@ -211,8 +212,22 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
211212 val sym = stat.symbol
212213 assert(isRetained(sym), sym)
213214 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)
214229 val setter =
215- if (sym.setter. exists) sym.setter
230+ if (symSetter. exists) symSetter
216231 else sym.accessorNamed(Mixin .traitSetterName(sym.asTerm))
217232 constrStats += Apply (ref(setter), intoConstr(stat.rhs, sym).withSpan(stat.span) :: Nil )
218233 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 =>
175175 atPhase(thisPhase) { sym.isOneOf(flags) }
176176
177177 private def needsTraitSetter (sym : Symbol )(using Context ): Boolean =
178- sym.isGetter && ! wasOneOf(sym, DeferredOrLazy | ParamAccessor ) && ! sym.setter.exists
178+ sym.isGetter && ! wasOneOf(sym, DeferredOrLazy | ParamAccessor )
179+ && atPhase(thisPhase) { ! sym.setter.exists }
179180 && ! sym.info.resultType.isInstanceOf [ConstantType ]
180181
181182 private def makeTraitSetter (getter : TermSymbol )(using Context ): Symbol =
You can’t perform that action at this time.
0 commit comments