Skip to content

Commit ef3acdb

Browse files
authored
Merge pull request #9893 from som-snytt/issue/7709
Context for constructor error is outer context
2 parents a5d3ba9 + c7a1a02 commit ef3acdb

File tree

3 files changed

+93
-19
lines changed

3 files changed

+93
-19
lines changed

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

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -824,30 +824,25 @@ object SymDenotations {
824824
}
825825

826826
/** Is protected access to target symbol permitted? */
827-
def isProtectedAccessOK = {
828-
def fail(str: => String): Boolean = {
829-
if (whyNot != null) whyNot append str
827+
def isProtectedAccessOK: Boolean =
828+
inline def fail(str: String): false =
829+
if whyNot != null then whyNot.append(str)
830830
false
831-
}
832831
val cls = owner.enclosingSubClass
833-
if (!cls.exists)
834-
fail(
835-
i"""
836-
| Access to protected $this not permitted because enclosing ${ctx.owner.enclosingClass.showLocated}
832+
if !cls.exists then
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
850-
}
845+
end isProtectedAccessOK
851846

852847
if pre eq NoPrefix then true
853848
else if isAbsent() then false

tests/neg/i7709.check

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
-- Error: tests/neg/i7709.scala:5:20 -----------------------------------------------------------------------------------
2+
5 | class B extends X.Y // error
3+
| ^^^
4+
| class Y cannot be accessed as a member of X.type from class B.
5+
| Access to protected class Y not permitted because enclosing object A
6+
| is not a subclass of object X where target is defined
7+
-- Error: tests/neg/i7709.scala:6:21 -----------------------------------------------------------------------------------
8+
6 | class B2 extends X.Y: // error
9+
| ^^^
10+
| class Y 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 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 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 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
33+
| ^^^^
34+
| class Y cannot be accessed as a member of XX from class C.
35+
| Access to protected class Y not permitted because enclosing class C
36+
| 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 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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
object X:
3+
protected class Y
4+
object A:
5+
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
14+
class XX:
15+
protected class Y
16+
class C:
17+
def xx = new XX
18+
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+
}
25+
class YY extends XX:
26+
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)