Skip to content

Commit fd737ea

Browse files
Restrict non-local private fields
Non-local private fields can be accessed by other instances of the class. However, this creates the following issue: ``` inline trait A: private val x = 1 def eq(o: A) = o.x == x class B extends A ``` In the code above, when we inline the code into B, `o.x` accesses a private field of A from B, which is not allowed. To allow this, we'd need to either make x protected, or change the signature of `eq` to take a B instead.
1 parent 7c82e3d commit fd737ea

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -639,11 +639,11 @@ object Inlines:
639639
private def inlinedMemberSym(sym: Symbol, withoutFlags: FlagSet = EmptyFlags)(using Context): Symbol =
640640
var name = sym.name
641641
var flags = sym.flags | Synthetic
642-
if sym.isType || !sym.is(Private) then flags |= Override
643-
if sym.isTermParamAccessor then
644-
flags &~= ParamAccessor
645-
if sym.is(Local) && sym.owner.isInlineTrait then
646-
name = paramAccessorsMapper.registerNewName(sym)
642+
if sym.isTermParamAccessor then flags &~= ParamAccessor
643+
if sym.is(Local) then
644+
name = paramAccessorsMapper.registerNewName(sym)
645+
else
646+
flags |= Override
647647
sym.copy(
648648
owner = ctx.owner,
649649
name = name,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
155155
tree match
156156
case tree: ValOrDefDef if !sym.is(Synthetic) =>
157157
checkInferredWellFormed(tree.tpt)
158+
if tree.symbol.owner.isInlineTrait then checkInlTraitPrivateMemberIsLocal(tree)
158159
if sym.is(Method) then
159160
if sym.isSetter then
160161
sym.keepAnnotationsCarrying(thisPhase, Set(defn.SetterMetaAnnot))
@@ -192,6 +193,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
192193
=> Checking.checkAppliedTypesIn(tree)
193194
case _ =>
194195

196+
private def checkInlTraitPrivateMemberIsLocal(tree: Tree)(using Context): Unit =
197+
if tree.symbol.owner.isInlineTrait && tree.symbol.isAllOf(Private, butNot = Local) then
198+
report.error(em"implementation restriction: inline traits cannot have non-local private members", tree.srcPos)
195199

196200
private def transformSelect(tree: Select, targs: List[Tree])(using Context): Tree = {
197201
val qual = tree.qualifier
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
inline trait A:
2+
private val x: Int = 1 // error
3+
def eq(o: A) = o.x == x

0 commit comments

Comments
 (0)