Skip to content

Commit 81cc7d6

Browse files
committed
Simplify expression per review and add tests
1 parent 056a233 commit 81cc7d6

File tree

3 files changed

+67
-17
lines changed

3 files changed

+67
-17
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -825,28 +825,23 @@ object SymDenotations {
825825

826826
/** Is protected access to target symbol permitted? */
827827
def isProtectedAccessOK: Boolean =
828-
def fail(str: => String): false =
828+
inline def fail(str: String): false =
829829
if whyNot != null then whyNot.append(str)
830830
false
831831
val cls = owner.enclosingSubClass
832832
if !cls.exists then
833-
val encl = if !ctx.owner.isConstructor then ctx else ctx.outersIterator.dropWhile(_.owner.isConstructor).next()
834-
fail(
835-
i"""
836-
| Access to protected $this not permitted because enclosing ${encl.owner.enclosingClass.showLocated}
833+
val encl = if ctx.owner.isConstructor then ctx.owner.enclosingClass.owner.enclosingClass else ctx.owner.enclosingClass
834+
fail(i"""
835+
| Access to protected $this not permitted because enclosing ${encl.showLocated}
837836
| is not a subclass of ${owner.showLocated} where target is defined""")
838-
else if
839-
!( isType // allow accesses to types from arbitrary subclasses fixes #4737
840-
|| pre.derivesFrom(cls)
841-
|| isConstructor
842-
|| owner.is(ModuleClass) // don't perform this check for static members
843-
)
844-
then
845-
fail(
846-
i"""
837+
else if isType || pre.derivesFrom(cls) || isConstructor || owner.is(ModuleClass) then
838+
// allow accesses to types from arbitrary subclasses fixes #4737
839+
// don't perform this check for static members
840+
true
841+
else
842+
fail(i"""
847843
| Access to protected ${symbol.show} not permitted because prefix type ${pre.widen.show}
848844
| does not conform to ${cls.showLocated} where the access takes place""")
849-
else true
850845
end isProtectedAccessOK
851846

852847
if pre eq NoPrefix then true

tests/neg/i7709.check

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,45 @@
44
| class Y in object X cannot be accessed as a member of X.type from class B.
55
| Access to protected class Y not permitted because enclosing object A
66
| is not a subclass of object X where target is defined
7-
-- Error: tests/neg/i7709.scala:10:18 ----------------------------------------------------------------------------------
8-
10 | def y = new xx.Y // error
7+
-- Error: tests/neg/i7709.scala:6:21 -----------------------------------------------------------------------------------
8+
6 | class B2 extends X.Y: // error
9+
| ^^^
10+
| class Y in object X cannot be accessed as a member of X.type from class B2.
11+
| Access to protected class Y not permitted because enclosing object A
12+
| is not a subclass of object X where target is defined
13+
-- Error: tests/neg/i7709.scala:9:28 -----------------------------------------------------------------------------------
14+
9 | class B4 extends B3(new X.Y) // error
15+
| ^^^
16+
| class Y in object X cannot be accessed as a member of X.type from class B4.
17+
| Access to protected class Y not permitted because enclosing object A
18+
| is not a subclass of object X where target is defined
19+
-- Error: tests/neg/i7709.scala:11:34 ----------------------------------------------------------------------------------
20+
11 | def this(n: Int) = this(new X.Y().toString) // error
21+
| ^^^
22+
| class Y in object X cannot be accessed as a member of X.type from class B5.
23+
| Access to protected class Y not permitted because enclosing object A
24+
| is not a subclass of object X where target is defined
25+
-- Error: tests/neg/i7709.scala:13:20 ----------------------------------------------------------------------------------
26+
13 | class B extends X.Y // error
27+
| ^^^
28+
| class Y in object X cannot be accessed as a member of X.type from class B.
29+
| Access to protected class Y not permitted because enclosing trait T
30+
| is not a subclass of object X where target is defined
31+
-- Error: tests/neg/i7709.scala:18:18 ----------------------------------------------------------------------------------
32+
18 | def y = new xx.Y // error
933
| ^^^^
1034
| class Y cannot be accessed as a member of XX from class C.
1135
| Access to protected class Y not permitted because enclosing class C
1236
| is not a subclass of class XX where target is defined
37+
-- Error: tests/neg/i7709.scala:23:20 ----------------------------------------------------------------------------------
38+
23 | def y = new xx.Y // error
39+
| ^^^^
40+
| class Y cannot be accessed as a member of XX from class D.
41+
| Access to protected class Y not permitted because enclosing class D
42+
| is not a subclass of class XX where target is defined
43+
-- Error: tests/neg/i7709.scala:31:20 ----------------------------------------------------------------------------------
44+
31 | class Q extends X.Y // error
45+
| ^^^
46+
| class Y in object X cannot be accessed as a member of p.X.type from class Q.
47+
| Access to protected class Y not permitted because enclosing package p
48+
| is not a subclass of object X in package p where target is defined

tests/neg/i7709.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,29 @@ object X:
33
protected class Y
44
object A:
55
class B extends X.Y // error
6+
class B2 extends X.Y: // error
7+
def this(n: Int) = this()
8+
class B3(x: Any)
9+
class B4 extends B3(new X.Y) // error
10+
class B5(x: String):
11+
def this(n: Int) = this(new X.Y().toString) // error
12+
trait T:
13+
class B extends X.Y // error
614
class XX:
715
protected class Y
816
class C:
917
def xx = new XX
1018
def y = new xx.Y // error
19+
class D:
20+
def this(n: Int) = {
21+
this()
22+
def xx = new XX
23+
def y = new xx.Y // error
24+
}
1125
class YY extends XX:
1226
def y = new Y
27+
28+
package p:
29+
object X:
30+
protected class Y
31+
class Q extends X.Y // error

0 commit comments

Comments
 (0)