Skip to content

Commit 27add32

Browse files
committed
Fix trait encoding for private vars in traits.
1 parent 75e007b commit 27add32

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import dotty.tools.dotc.core.StdNames._
99
import ast._
1010
import Trees._
1111
import Flags._
12+
import NameOps._
1213
import SymUtils._
1314
import Symbols._
1415
import 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)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
175175
ctx.atPhase(thisPhase) { sym.isOneOf(flags) }
176176

177177
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 }
179180
&& !sym.info.resultType.isInstanceOf[ConstantType]
180181

181182
private def makeTraitSetter(getter: TermSymbol)(implicit ctx: Context): Symbol =

0 commit comments

Comments
 (0)