Skip to content

Commit daffba9

Browse files
committed
Merge pull request #1164 from dotty-staging/fix-#1140
Make sure lazy accessors in traits are not private.
2 parents e68d684 + 6b983e3 commit daffba9

File tree

7 files changed

+38
-17
lines changed

7 files changed

+38
-17
lines changed

src/dotty/tools/dotc/core/Flags.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ object Flags {
448448
final val FromStartFlags =
449449
AccessFlags | Module | Package | Deferred | Final | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon |
450450
InSuperCall | Touched | JavaStatic | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed |
451-
CaseAccessorOrBaseTypeArg | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent |
451+
CaseAccessorOrBaseTypeArg | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent | Synthetic |
452452
LazyOrTrait | SuperAccessorOrScala2x | SelfNameOrImplClass
453453

454454
assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags)

src/dotty/tools/dotc/transform/ExpandPrivate.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t
5757
* static members of the companion class, we should tighten the condition below.
5858
*/
5959
private def ensurePrivateAccessible(d: SymDenotation)(implicit ctx: Context) =
60-
if (d.is(PrivateTerm) && d.owner != ctx.owner.enclosingClass)
60+
if (d.is(PrivateTerm) && d.owner != ctx.owner.enclosingClass) {
61+
assert(d.symbol.sourceFile == ctx.source.file,
62+
i"private ${d.symbol.showLocated} in ${d.symbol.sourceFile} accessed from ${ctx.owner.showLocated} in ${ctx.source.file}")
6163
d.ensureNotPrivate.installAfter(thisTransform)
64+
}
6265

6366
override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
6467
ensurePrivateAccessible(tree.symbol)

src/dotty/tools/dotc/transform/FirstTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
124124

125125
private def newCompanion(name: TermName, forClass: Symbol)(implicit ctx: Context) = {
126126
val modul = ctx.newCompleteModuleSymbol(forClass.owner, name, Synthetic, Synthetic,
127-
defn.ObjectType :: Nil, Scopes.newScope)
127+
defn.ObjectType :: Nil, Scopes.newScope, assocFile = forClass.asClass.assocFile)
128128
val mc = modul.moduleClass
129129

130130
val mcComp = ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, forClass, mc)

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
9898
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure])
9999

100100
override def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation =
101-
if (sym.is(Accessor, butNot = Deferred | Lazy) && sym.owner.is(Trait))
102-
sym.copySymDenotation(initFlags = sym.flags &~ ParamAccessor | Deferred).ensureNotPrivate
101+
if (sym.is(Accessor, butNot = Deferred) && sym.owner.is(Trait)) {
102+
val sym1 =
103+
if (sym is Lazy) sym
104+
else sym.copySymDenotation(initFlags = sym.flags &~ ParamAccessor | Deferred)
105+
sym1.ensureNotPrivate
106+
}
103107
else if (sym.isConstructor && sym.owner.is(Trait))
104108
sym.copySymDenotation(
105109
name = nme.TRAIT_CONSTRUCTOR,
@@ -108,17 +112,19 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
108112
sym
109113

110114
private def initializer(sym: Symbol)(implicit ctx: Context): TermSymbol = {
111-
val initName = if(!sym.is(Lazy)) InitializerName(sym.name.asTermName) else sym.name.asTermName
112-
sym.owner.info.decl(initName).suchThat(_.is(Lazy) == sym.is(Lazy)).symbol
113-
.orElse(
114-
ctx.newSymbol(
115-
sym.owner,
116-
initName,
117-
Protected | Synthetic | Method,
118-
sym.info,
119-
coord = sym.symbol.coord).enteredAfter(thisTransform))
120-
.asTerm
121-
}
115+
if (sym is Lazy) sym
116+
else {
117+
val initName = InitializerName(sym.name.asTermName)
118+
sym.owner.info.decl(initName).symbol
119+
.orElse(
120+
ctx.newSymbol(
121+
sym.owner,
122+
initName,
123+
Protected | Synthetic | Method,
124+
sym.info,
125+
coord = sym.symbol.coord).enteredAfter(thisTransform))
126+
}
127+
}.asTerm
122128

123129
override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
124130
val cls = impl.symbol.owner.asClass

src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,10 @@ class TreeChecker extends Phase with SymTransformer {
282282

283283
val symbolsNotDefined = cls.classInfo.decls.toSet.filter(isNonMagicalMethod) -- impl.body.map(_.symbol) - constr.symbol
284284

285-
assert(symbolsNotDefined.isEmpty, i" $cls tree does not define methods: $symbolsNotDefined")
285+
assert(symbolsNotDefined.isEmpty,
286+
i" $cls tree does not define methods: ${symbolsNotDefined.toList}%, %\n" +
287+
i"expected: ${cls.classInfo.decls.toSet.filter(isNonMagicalMethod).toList}%, %\n" +
288+
i"defined: ${impl.body.map(_.symbol)}%, %")
286289

287290
super.typedClassDef(cdef, cls)
288291
}

tests/run/i1140/A_1.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait A {
2+
val foo = 0 + x
3+
private lazy val x = 1
4+
}

tests/run/i1140/B_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test extends A {
2+
def main(args: Array[String]): Unit = {
3+
assert(foo == 1)
4+
}
5+
}

0 commit comments

Comments
 (0)