Skip to content

Commit 536778b

Browse files
committed
Allow override protected[C] in companion
When extending C in its companion, allow override protected[C] where C denotes the enclosing companion module of C.
1 parent c94b333 commit 536778b

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,13 @@ object RefChecks {
414414
val ob = other.accessBoundary(member.owner)
415415
val mb = member.accessBoundary(member.owner)
416416
def isOverrideAccessOK =
417-
(member.flags & AccessFlags).isEmpty
418-
&& !member.privateWithin.exists // member is public, or
419-
|| (!other.is(Protected) || member.is(Protected))
420-
// if o is protected, so is m, and
421-
&& (ob.isContainedIn(mb) || other.isAllOf(JavaProtected))
422-
// m relaxes o's access boundary,
423-
// or o is Java defined and protected (see #3946)
417+
val memberIsPublic = (member.flags & AccessFlags).isEmpty && !member.privateWithin.exists
418+
def protectedOK = !other.is(Protected) || member.is(Protected) // if o is protected, so is m
419+
def companionBoundaryOK = ob.isClass && mb.is(Module) && (ob.companionModule eq mb.companionModule)
420+
def accessBoundaryOK = ob.isContainedIn(mb) || companionBoundaryOK // m relaxes o's access boundary,
421+
def otherIsJavaProtected = other.isAllOf(JavaProtected) // or o is Java defined and protected (see #3946)
422+
memberIsPublic || protectedOK && (accessBoundaryOK || otherIsJavaProtected)
423+
end isOverrideAccessOK
424424
if !member.hasTargetName(other.targetName) then
425425
overrideTargetNameError()
426426
else if (!isOverrideAccessOK)

tests/pos/t12494.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
trait Base {
3+
protected[Base] def f: Int
4+
}
5+
object Base {
6+
class Child extends Base {
7+
protected[Base] def f: Int = 42 // ok
8+
def test = f
9+
}
10+
}
11+
12+
/*
13+
object X {
14+
// restriction in Scala 2 for local companions
15+
// restriction in Scala 3 under -from-tasty
16+
def m: Int = {
17+
trait C {
18+
protected[C] def f: Int
19+
}
20+
object C {
21+
class C2 extends C {
22+
protected[C] def f: Int = 42 // ok
23+
def test = f
24+
}
25+
}
26+
C.C2().test
27+
}
28+
}
29+
*/

0 commit comments

Comments
 (0)