@@ -174,27 +174,30 @@ class SuperAccessors(thisPhase: DenotTransformer) {
174174 val sel @ Select (qual, name) = tree : @ unchecked
175175 val sym = sel.symbol
176176
177- /** If an accesses to protected member of a class comes from a trait,
178- * or would need a protected accessor placed in a trait, we cannot
179- * perform the access to the protected member directly since jvm access
180- * restrictions require the call site to be in an actual subclass and
181- * traits don't count as subclasses in this respect. In this case
182- * we generate a super accessor instead. See SI-2296.
183- */
184177 def needsSuperAccessor =
185178 ProtectedAccessors .needsAccessorIfNotInSubclass(sym) &&
186179 AccessProxies .hostForAccessorOf(sym).is(Trait )
187180 qual match {
188181 case _ : This if needsSuperAccessor =>
189- /*
190- * A trait which extends a class and accesses a protected member
191- * of that class cannot implement the necessary accessor method
192- * because jvm access restrictions require the call site to be in
193- * an actual subclass and traits don't count as subclasses in this
194- * respect. We generate a super accessor itself, which will be fixed
195- * by the implementing class. See SI-2296.
196- */
197- superAccessorCall(sel)
182+ /* Given a protected member m defined in class C,
183+ * and a trait T that calls m.
184+ *
185+ * If T extends C, then we can access it by casting
186+ * the qualifier of the select to C.
187+ *
188+ * That's because the protected method is actually public,
189+ * so we can call it. For truly protected methods, like from
190+ * Java, we error instead of emitting the wrong code (i17021.ext-java).
191+ *
192+ * Otherwise, we need to go through an accessor,
193+ * which the implementing class will provide an implementation for.
194+ */
195+ if ctx.owner.enclosingClass.derivesFrom(sym.owner) then
196+ if sym.is(JavaDefined ) then
197+ report.error(em " ${ctx.owner} accesses protected $sym inside a concrete trait method: use super. ${sel.name} instead " , sel.srcPos)
198+ sel
199+ else
200+ superAccessorCall(sel)
198201 case Super (_, mix) =>
199202 transformSuperSelect(sel)
200203 case _ =>
0 commit comments