Skip to content

Commit 52d2e02

Browse files
committed
Fix suggested by Claude
Still has a missing corner case: class E extends D(new D(1))
1 parent 9b6c1d5 commit 52d2e02

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,9 @@ object SymDenotations {
947947
if !cls.exists then
948948
pre.termSymbol.isPackageObject && accessWithin(pre.termSymbol.owner)
949949
else {
950-
val isConstructorAccessOK = isConstructor && ctx.owner.isConstructor
950+
val isConstructorAccessOK =
951+
isConstructor && ctx.owner.isPrimaryConstructor
952+
&& cls.info.parents.exists(_.classSymbol == owner)
951953
// allow accesses to types from arbitrary subclasses fixes #4737
952954
// don't perform this check for static members
953955
isType || pre.derivesFrom(cls) || isConstructorAccessOK || owner.is(ModuleClass)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package protectedCtors
2+
3+
class A protected (x: Int)
4+
5+
// Protected constructor in super call arguments (transitive parent)
6+
class B(a: A) extends A(a.hashCode)
7+
class C extends B(new A(1)) // error
8+
9+
// Mixed visibility constructors
10+
class F protected (x: Int) {
11+
def this() = this(0) // public secondary
12+
}
13+
class G(f: F) extends F(f.hashCode)
14+
class H extends G(new F()) // ok: public secondary in super args
15+
class J extends G(new F(1)) // error: protected primary in super args
16+
17+
// new in primary constructor body
18+
class K extends A(42) {
19+
val k = new A(1) // error
20+
}
21+
22+
// Lambda in super call arguments
23+
class M(f: () => A) extends A(1)
24+
class N extends M(() => new A(2)) // error

tests/neg/i25442/test.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ class I protected (x: Int) {
55
class M protected () extends I(42) {
66
def t1 = new M() // ok
77
def t2 = new I(42) // error
8+
def this(x: Int) = { this(); new I(x) } // error
89
}

tests/pos/i25442.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package protectedCtorsPos
2+
3+
class A protected (x: Int)
4+
5+
// Super calls are allowed
6+
class B extends A(42)
7+
8+
// Inner class extending protected parent
9+
class C extends A(42) {
10+
class Inner extends A(1)
11+
}
12+
13+
// Mixed visibility: public secondary constructor is accessible
14+
class D protected (x: Int) {
15+
def this() = this(0)
16+
}
17+
class E(d: D) extends D(d.hashCode)
18+
class F extends E(new D())

0 commit comments

Comments
 (0)