Skip to content

Commit

Permalink
Improve error message for inaccessible protected members
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Oct 13, 2023
1 parent 1920336 commit 1472b7a
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 28 deletions.
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -915,17 +915,17 @@ object SymDenotations {
true
else
val encl = if ctx.owner.isConstructor then ctx.owner.enclosingClass.owner.enclosingClass else ctx.owner.enclosingClass
val location = if owner.is(Final) then owner.showLocated else owner.showLocated + " or one of its subclasses"
fail(i"""
| Access to protected $this not permitted because enclosing ${encl.showLocated}
| is not a subclass of ${owner.showLocated} where target is defined""")
| Protected $this can only be accessed from $location.""")
else if isType || pre.derivesFrom(cls) || isConstructor || owner.is(ModuleClass) then
// allow accesses to types from arbitrary subclasses fixes #4737
// don't perform this check for static members
true
else
val location = if cls.is(Final) then cls.showLocated else cls.showLocated + " or one of its subclasses"
fail(i"""
| Access to protected ${symbol.show} not permitted because prefix type ${pre.widen.show}
| does not conform to ${cls.showLocated} where the access takes place""")
| Protected $this can only be accessed from $location.""")
end isProtectedAccessOK

if pre eq NoPrefix then true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
nameString(sym)

if sym.is(ModuleClass) && sym.isTopLevelDefinitionsObject then
"top-level definition in package " + nameString(sym.owner.name)
"the top-level definitions in package " + nameString(sym.owner.name)
else (keywordText(kindString(sym)) ~~ {
if (sym.isAnonymousClass)
toTextParents(sym.info.parents) ~~ "{...}"
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/annot-result-owner.check
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- Error: tests/neg-macros/annot-result-owner/Test_2.scala:1:0 ---------------------------------------------------------
1 |@insertVal // error
|^^^^^^^^^^
|macro annotation @insertVal added value definitionWithWrongOwner$macro$1 with an inconsistent owner. Expected it to be owned by top-level definition in package <empty> but was owned by method foo.
|macro annotation @insertVal added value definitionWithWrongOwner$macro$1 with an inconsistent owner. Expected it to be owned by the top-level definitions in package <empty> but was owned by method foo.
-- Error: tests/neg-macros/annot-result-owner/Test_2.scala:5:2 ---------------------------------------------------------
5 | @insertVal // error
| ^^^^^^^^^^
Expand Down
5 changes: 2 additions & 3 deletions tests/neg/i12573.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
|value getDFType is not a member of DFBits[(8 : Int)].
|Extension methods were tried, but the search failed with:
|
| method getDFType cannot be accessed as a member of DFType.type from top-level definition in package <empty>.
| Access to protected method getDFType not permitted because enclosing top-level definition in package <empty>
| is not a subclass of object DFType where target is defined
| method getDFType cannot be accessed as a member of DFType.type from the top-level definitions in package <empty>.
| Protected method getDFType can only be accessed from object DFType.
24 changes: 8 additions & 16 deletions tests/neg/i7709.check
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,39 @@
5 | class B extends X.Y // error
| ^^^
| class Y cannot be accessed as a member of X.type from class B.
| Access to protected class Y not permitted because enclosing object A
| is not a subclass of object X where target is defined
| Protected class Y can only be accessed from object X.
-- [E173] Reference Error: tests/neg/i7709.scala:6:21 ------------------------------------------------------------------
6 | class B2 extends X.Y: // error
| ^^^
| class Y cannot be accessed as a member of X.type from class B2.
| Access to protected class Y not permitted because enclosing object A
| is not a subclass of object X where target is defined
| Protected class Y can only be accessed from object X.
-- [E173] Reference Error: tests/neg/i7709.scala:9:28 ------------------------------------------------------------------
9 | class B4 extends B3(new X.Y) // error
| ^^^
| class Y cannot be accessed as a member of X.type from class B4.
| Access to protected class Y not permitted because enclosing object A
| is not a subclass of object X where target is defined
| Protected class Y can only be accessed from object X.
-- [E173] Reference Error: tests/neg/i7709.scala:11:34 -----------------------------------------------------------------
11 | def this(n: Int) = this(new X.Y().toString) // error
| ^^^
| class Y cannot be accessed as a member of X.type from class B5.
| Access to protected class Y not permitted because enclosing object A
| is not a subclass of object X where target is defined
| Protected class Y can only be accessed from object X.
-- [E173] Reference Error: tests/neg/i7709.scala:13:20 -----------------------------------------------------------------
13 | class B extends X.Y // error
| ^^^
| class Y cannot be accessed as a member of X.type from class B.
| Access to protected class Y not permitted because enclosing trait T
| is not a subclass of object X where target is defined
| Protected class Y can only be accessed from object X.
-- [E173] Reference Error: tests/neg/i7709.scala:18:18 -----------------------------------------------------------------
18 | def y = new xx.Y // error
| ^^^^
| class Y cannot be accessed as a member of XX from class C.
| Access to protected class Y not permitted because enclosing class C
| is not a subclass of class XX where target is defined
| Protected class Y can only be accessed from class XX or one of its subclasses.
-- [E173] Reference Error: tests/neg/i7709.scala:23:20 -----------------------------------------------------------------
23 | def y = new xx.Y // error
| ^^^^
| class Y cannot be accessed as a member of XX from class D.
| Access to protected class Y not permitted because enclosing class D
| is not a subclass of class XX where target is defined
| Protected class Y can only be accessed from class XX or one of its subclasses.
-- [E173] Reference Error: tests/neg/i7709.scala:31:20 -----------------------------------------------------------------
31 | class Q extends X.Y // error
| ^^^
| class Y cannot be accessed as a member of p.X.type from class Q.
| Access to protected class Y not permitted because enclosing package p
| is not a subclass of object X in package p where target is defined
| Protected class Y can only be accessed from object X in package p.
6 changes: 3 additions & 3 deletions tests/neg/not-accessible.check
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
-- [E173] Reference Error: tests/neg/not-accessible.scala:13:23 --------------------------------------------------------
13 | def test(a: A) = a.x // error
| ^^^
| value x cannot be accessed as a member of (a : foo.A) from top-level definition in package bar.
| value x cannot be accessed as a member of (a : foo.A) from the top-level definitions in package bar.
-- [E173] Reference Error: tests/neg/not-accessible.scala:5:21 ---------------------------------------------------------
5 | def test(a: A) = a.x // error
| ^^^
| value x cannot be accessed as a member of (a : foo.A) from top-level definition in package foo.
| value x cannot be accessed as a member of (a : foo.A) from the top-level definitions in package foo.
-- [E173] Reference Error: tests/neg/not-accessible.scala:15:23 --------------------------------------------------------
15 |def test(a: foo.A) = a.x // error
| ^^^
| value x cannot be accessed as a member of (a : foo.A) from top-level definition in package <empty>.
| value x cannot be accessed as a member of (a : foo.A) from the top-level definitions in package <empty>.

0 comments on commit 1472b7a

Please sign in to comment.