diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index dcc4ac09d5ec..ff0d6e7428f4 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -414,13 +414,13 @@ object RefChecks { val ob = other.accessBoundary(member.owner) val mb = member.accessBoundary(member.owner) def isOverrideAccessOK = - (member.flags & AccessFlags).isEmpty - && !member.privateWithin.exists // member is public, or - || (!other.is(Protected) || member.is(Protected)) - // if o is protected, so is m, and - && (ob.isContainedIn(mb) || other.isAllOf(JavaProtected)) - // m relaxes o's access boundary, - // or o is Java defined and protected (see #3946) + val memberIsPublic = (member.flags & AccessFlags).isEmpty && !member.privateWithin.exists + def protectedOK = !other.is(Protected) || member.is(Protected) // if o is protected, so is m + def companionBoundaryOK = ob.isClass && mb.is(Module) && (ob.companionModule eq mb.companionModule) + def accessBoundaryOK = ob.isContainedIn(mb) || companionBoundaryOK // m relaxes o's access boundary, + def otherIsJavaProtected = other.isAllOf(JavaProtected) // or o is Java defined and protected (see #3946) + memberIsPublic || protectedOK && (accessBoundaryOK || otherIsJavaProtected) + end isOverrideAccessOK if !member.hasTargetName(other.targetName) then overrideTargetNameError() else if (!isOverrideAccessOK) diff --git a/tests/pos/t12494.scala b/tests/pos/t12494.scala new file mode 100644 index 000000000000..0bc37ce43b83 --- /dev/null +++ b/tests/pos/t12494.scala @@ -0,0 +1,29 @@ + +trait Base { + protected[Base] def f: Int +} +object Base { + class Child extends Base { + protected[Base] def f: Int = 42 // ok + def test = f + } +} + +/* +object X { + // restriction in Scala 2 for local companions + // restriction in Scala 3 under -from-tasty + def m: Int = { + trait C { + protected[C] def f: Int + } + object C { + class C2 extends C { + protected[C] def f: Int = 42 // ok + def test = f + } + } + C.C2().test + } +} +*/