Skip to content

Commit 9f5e2b5

Browse files
som-snytttgodzik
authored andcommitted
Constructor proxy or companion is as protected as class
Require the constructor companion to be protected if the class is; or create it protected. Otherwise, create protected proxies.
1 parent 65bc5aa commit 9f5e2b5

File tree

6 files changed

+63
-7
lines changed

6 files changed

+63
-7
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ object NamerOps:
110110
*/
111111
def addConstructorApplies(scope: MutableScope, cls: ClassSymbol, modcls: ClassSymbol)(using Context): scope.type =
112112
def proxy(constr: Symbol): Symbol =
113+
var flags = ApplyProxyFlags | (constr.flagsUNSAFE & AccessFlags)
114+
if cls.is(Protected) && !modcls.is(Protected) then flags |= Protected
113115
newSymbol(
114-
modcls, nme.apply, ApplyProxyFlags | (constr.flagsUNSAFE & AccessFlags),
116+
modcls, nme.apply, flags,
115117
ApplyProxyCompleter(constr), coord = constr.coord)
116118
for dcl <- cls.info.decls do
117119
if dcl.isConstructor then scope.enter(proxy(dcl))
@@ -133,9 +135,11 @@ object NamerOps:
133135

134136
/** A new symbol that is the constructor companion for class `cls` */
135137
def classConstructorCompanion(cls: ClassSymbol)(using Context): TermSymbol =
138+
var flags = ConstructorCompanionFlags
139+
if cls.is(Protected) then flags |= Protected
136140
val companion = newModuleSymbol(
137141
cls.owner, cls.name.toTermName,
138-
ConstructorCompanionFlags, ConstructorCompanionFlags,
142+
flags, flags,
139143
constructorCompanionCompleter(cls),
140144
coord = cls.coord,
141145
assocFile = cls.assocFile)

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,9 +1111,8 @@ trait Applications extends Compatibility {
11111111
//
11121112
// summonFrom {
11131113
// case given A[t] =>
1114-
// summonFrom
1114+
// summonFrom:
11151115
// case given `t` => ...
1116-
// }
11171116
// }
11181117
//
11191118
// the second `summonFrom` should expand only once the first `summonFrom` is

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,9 +3821,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38213821
readapt(tree.appliedToNone) // insert () to primary constructors
38223822
else
38233823
errorTree(tree, em"Missing arguments for $methodStr")
3824-
case _ => tryInsertApplyOrImplicit(tree, pt, locked) {
3825-
errorTree(tree, MethodDoesNotTakeParameters(tree))
3826-
}
3824+
case _ =>
3825+
tryInsertApplyOrImplicit(tree, pt, locked):
3826+
errorTree(tree, MethodDoesNotTakeParameters(tree))
38273827
}
38283828

38293829
def adaptNoArgsImplicitMethod(wtp: MethodType): Tree = {

tests/neg/i22560.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
class A:
3+
protected class B
4+
5+
// This fails to compile, as expected
6+
val x = A().B() // error
7+
8+
object C:
9+
protected val p = "protected"
10+
protected def getString() = "Hello!"
11+
protected class D:
12+
def d = D() // ok
13+
14+
// This fails to compile
15+
// val y = C.p
16+
17+
// And this also fails to compile
18+
// val z = C.getString()
19+
20+
// However, this compiles just fine.
21+
val alpha = C.D() // error
22+
val beta = new C.D() // error

tests/neg/i22560b.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
class Enumeration:
3+
protected class Val(i: Int):
4+
def this() = this(42)
5+
object Val
6+
7+
class Test extends Enumeration:
8+
val Hearts = Val(27) // error
9+
val Diamonds = Val() // error

tests/pos/i22560.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
package companionless:
3+
4+
class Enumeration:
5+
protected class Val(i: Int):
6+
def this() = this(42)
7+
8+
class Test extends Enumeration:
9+
val Hearts = Val(27)
10+
val Diamonds = Val()
11+
12+
13+
package companioned:
14+
15+
class Enumeration:
16+
protected class Val(i: Int):
17+
def this() = this(42)
18+
protected object Val
19+
20+
class Test extends Enumeration:
21+
val Hearts = Val(27)
22+
val Diamonds = Val()

0 commit comments

Comments
 (0)