Skip to content

Commit 6e2b765

Browse files
authored
Merge pull request scala#10855 from lrytz/i20006-privateacc
No double def in Scala 2 for private[this] param and matching method
2 parents 52b2013 + 1e46a0b commit 6e2b765

File tree

9 files changed

+363
-28
lines changed

9 files changed

+363
-28
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3429,6 +3429,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
34293429
while ((e1 ne null) && e1.owner == scope) {
34303430
val sym1 = e1.sym
34313431

3432+
def allowPrivateLocalAcc: Boolean =
3433+
sym.isParamAccessor && sym.isPrivateLocal || sym1.isParamAccessor && sym1.isPrivateLocal
34323434
def nullaryNilary: Boolean = {
34333435
def nn(m: Symbol): Boolean = m.isParamAccessor || m.hasAccessorFlag || !m.isMethod || {
34343436
m.tpe match {
@@ -3443,7 +3445,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
34433445
if (currentRun.isScala3 && !currentRun.sourceFeatures.doubleDefinitions)
34443446
context.warning(sym.pos, s"Double definition will be detected in Scala 3; the conflicting $sym1 is defined at ${sym1.pos.line}:${sym1.pos.column}", Scala3Migration)
34453447

3446-
val conflicted = inBlock || (!sym.isMethod && !sym1.isMethod) || sym.tpe.matches(sym1.tpe) || correctly
3448+
val conflicted = inBlock || (!sym.isMethod && !sym1.isMethod) ||
3449+
sym.tpe.matches(sym1.tpe) && !allowPrivateLocalAcc || // Scala 2: allow `class C(x: A) { def x: B }`
3450+
correctly // Scala 3: warn / err for `class C(x: A) { def x: B }`, and with nilary `def x(): B`
34473451

34483452
// default getters are defined twice when multiple overloads have defaults.
34493453
// The error for this is deferred until RefChecks.checkDefaultsInOverloaded

test/files/neg/i20006.check

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,9 @@ i20006.scala:7: error: method hasNext is defined twice;
66
the conflicting value hasNext was defined at line 5:7
77
override def hasNext: Boolean = first || hasNext(acc) // error
88
^
9-
i20006.scala:21: error: method hasNext is defined twice;
10-
the conflicting value hasNext was defined at line 18:42
11-
override def hasNext: Boolean = first || hasNext(acc) // error
12-
^
13-
i20006.scala:35: error: method hasNext is defined twice;
14-
the conflicting value hasNext was defined at line 32:42
15-
def hasNext: Boolean = first || hasNext(acc) // error
16-
^
179
i20006.scala:47: error: x is already defined as value x
1810
val x: String = "member" // error
1911
^
20-
i20006.scala:50: error: variable x is defined twice;
21-
the conflicting value x was defined at line 49:9
22-
private var x: Int = 42 // error
23-
^
2412
i20006.scala:53: error: x is already defined as value x
2513
private[this] var x: Int = 42 // error
2614
^
@@ -31,4 +19,4 @@ i20006.scala:67: error: method x is defined twice;
3119
i20006.scala:77: error: x is already defined as variable x
3220
def x(): Int = x // error
3321
^
34-
9 errors
22+
6 errors

test/files/neg/i20006b.check

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,9 @@ i20006b.scala:8: error: method hasNext is defined twice;
66
the conflicting value hasNext was defined at line 6:7
77
override def hasNext: Boolean = first || hasNext(acc) // error
88
^
9-
i20006b.scala:22: error: method hasNext is defined twice;
10-
the conflicting value hasNext was defined at line 19:42
11-
override def hasNext: Boolean = first || hasNext(acc) // error
12-
^
13-
i20006b.scala:36: error: method hasNext is defined twice;
14-
the conflicting value hasNext was defined at line 33:42
15-
def hasNext: Boolean = first || hasNext(acc) // error
16-
^
179
i20006b.scala:48: error: x is already defined as value x
1810
val x: String = "member" // error
1911
^
20-
i20006b.scala:51: error: variable x is defined twice;
21-
the conflicting value x was defined at line 50:9
22-
private var x: Int = 42 // error
23-
^
2412
i20006b.scala:54: error: x is already defined as value x
2513
private[this] var x: Int = 42 // error
2614
^
@@ -36,11 +24,26 @@ Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or
3624
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=YIterateIterator
3725
override def next(): T = { // werror
3826
^
27+
i20006b.scala:22: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 19:42
28+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
29+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=YIterateIterator
30+
override def hasNext: Boolean = first || hasNext(acc) // error
31+
^
3932
i20006b.scala:37: error: Double definition will be detected in Scala 3; the conflicting value next is defined at 33:65
4033
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
4134
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=ZIterateIterator
4235
def next(): T = { // werror
4336
^
37+
i20006b.scala:36: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 33:42
38+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
39+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=ZIterateIterator
40+
def hasNext: Boolean = first || hasNext(acc) // error
41+
^
42+
i20006b.scala:51: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 50:9
43+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
44+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D
45+
private var x: Int = 42 // error
46+
^
4447
i20006b.scala:57: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 56:9
4548
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
4649
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=F

test/files/neg/i20006d.check

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
i20006d.scala:12: error: method x is defined twice;
2+
the conflicting value x was defined at line 11:22
3+
def x: Int = 4 // err
4+
^
5+
i20006d.scala:17: error: method x is defined twice;
6+
the conflicting value x was defined at line 16:28
7+
def x: Int = 4 // err
8+
^
9+
i20006d.scala:22: error: method x is defined twice;
10+
the conflicting value x was defined at line 21:24
11+
def x: Int = 4 // err
12+
^
13+
i20006d.scala:27: error: method x is defined twice;
14+
the conflicting value x was defined at line 26:30
15+
def x: Int = 4 // err
16+
^
17+
i20006d.scala:32: error: method x is defined twice;
18+
the conflicting value x was defined at line 31:14
19+
def x: Int = 4 // err
20+
^
21+
i20006d.scala:44: error: method x is defined twice;
22+
the conflicting value x was defined at line 43:22
23+
def x(): Int = 4 // err
24+
^
25+
i20006d.scala:49: error: method x is defined twice;
26+
the conflicting value x was defined at line 48:28
27+
def x(): Int = 4 // err
28+
^
29+
i20006d.scala:54: error: method x is defined twice;
30+
the conflicting value x was defined at line 53:24
31+
def x(): Int = 4 // err
32+
^
33+
i20006d.scala:59: error: method x is defined twice;
34+
the conflicting value x was defined at line 58:30
35+
def x(): Int = 4 // err
36+
^
37+
i20006d.scala:64: error: method x is defined twice;
38+
the conflicting value x was defined at line 63:14
39+
def x(): Int = 4 // err
40+
^
41+
i20006d.scala:68: error: x is already defined as value x
42+
val x: Int = 4 // err
43+
^
44+
i20006d.scala:72: error: x is already defined as value x
45+
val x: Int = 4 // err
46+
^
47+
i20006d.scala:76: error: x is already defined as value x
48+
val x: Int = 4 // err
49+
^
50+
i20006d.scala:81: error: x is already defined as value x
51+
val x: Int = 4 // err
52+
^
53+
i20006d.scala:86: error: x is already defined as value x
54+
val x: Int = 4 // err
55+
^
56+
i20006d.scala:91: error: x is already defined as value x
57+
val x: Int = 4 // err
58+
^
59+
i20006d.scala:96: error: x is already defined as value x
60+
val x: Int = 4 // err
61+
^
62+
17 errors

test/files/neg/i20006d.scala

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//> using options -Werror
2+
3+
class C1(x: String) {
4+
def x: Int = 4 // ok in Scala 2
5+
}
6+
7+
class C2(private[this] val x: String) {
8+
def x: Int = 4 // ok in Scala 2
9+
}
10+
11+
class C3(private val x: String) {
12+
def x: Int = 4 // err
13+
}
14+
15+
object o4 {
16+
class C4(private[o4] val x: String) {
17+
def x: Int = 4 // err
18+
}
19+
}
20+
21+
class C5(protected val x: String) {
22+
def x: Int = 4 // err
23+
}
24+
25+
object o6 {
26+
class C6(protected[o6] val x: String) {
27+
def x: Int = 4 // err
28+
}
29+
}
30+
31+
class C7(val x: String) {
32+
def x: Int = 4 // err
33+
}
34+
35+
class D1(x: String) {
36+
def x(): Int = 4 // ok
37+
}
38+
39+
class D2(private[this] val x: String) {
40+
def x(): Int = 4 // ok
41+
}
42+
43+
class D3(private val x: String) {
44+
def x(): Int = 4 // err
45+
}
46+
47+
object p4 {
48+
class D4(private[p4] val x: String) {
49+
def x(): Int = 4 // err
50+
}
51+
}
52+
53+
class D5(protected val x: String) {
54+
def x(): Int = 4 // err
55+
}
56+
57+
object p6 {
58+
class D6(protected[p6] val x: String) {
59+
def x(): Int = 4 // err
60+
}
61+
}
62+
63+
class D7(val x: String) {
64+
def x(): Int = 4 // err
65+
}
66+
67+
class E1(x: String) {
68+
val x: Int = 4 // err
69+
}
70+
71+
class E2(private[this] val x: String) {
72+
val x: Int = 4 // err
73+
}
74+
75+
class E3(private val x: String) {
76+
val x: Int = 4 // err
77+
}
78+
79+
object q4 {
80+
class E4(private[q4] val x: String) {
81+
val x: Int = 4 // err
82+
}
83+
}
84+
85+
class E5(protected val x: String) {
86+
val x: Int = 4 // err
87+
}
88+
89+
object q6 {
90+
class E6(protected[q6] val x: String) {
91+
val x: Int = 4 // err
92+
}
93+
}
94+
95+
class E7(val x: String) {
96+
val x: Int = 4 // err
97+
}

test/files/neg/i20006e.check

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
i20006e.scala:12: error: method x is defined twice;
2+
the conflicting value x was defined at line 11:22
3+
def x: Int = 4 // err
4+
^
5+
i20006e.scala:17: error: method x is defined twice;
6+
the conflicting value x was defined at line 16:28
7+
def x: Int = 4 // err
8+
^
9+
i20006e.scala:22: error: method x is defined twice;
10+
the conflicting value x was defined at line 21:24
11+
def x: Int = 4 // err
12+
^
13+
i20006e.scala:27: error: method x is defined twice;
14+
the conflicting value x was defined at line 26:30
15+
def x: Int = 4 // err
16+
^
17+
i20006e.scala:32: error: method x is defined twice;
18+
the conflicting value x was defined at line 31:14
19+
def x: Int = 4 // err
20+
^
21+
i20006e.scala:44: error: method x is defined twice;
22+
the conflicting value x was defined at line 43:22
23+
def x(): Int = 4 // err
24+
^
25+
i20006e.scala:49: error: method x is defined twice;
26+
the conflicting value x was defined at line 48:28
27+
def x(): Int = 4 // err
28+
^
29+
i20006e.scala:54: error: method x is defined twice;
30+
the conflicting value x was defined at line 53:24
31+
def x(): Int = 4 // err
32+
^
33+
i20006e.scala:59: error: method x is defined twice;
34+
the conflicting value x was defined at line 58:30
35+
def x(): Int = 4 // err
36+
^
37+
i20006e.scala:64: error: method x is defined twice;
38+
the conflicting value x was defined at line 63:14
39+
def x(): Int = 4 // err
40+
^
41+
i20006e.scala:68: error: x is already defined as value x
42+
val x: Int = 4 // err
43+
^
44+
i20006e.scala:72: error: x is already defined as value x
45+
val x: Int = 4 // err
46+
^
47+
i20006e.scala:76: error: x is already defined as value x
48+
val x: Int = 4 // err
49+
^
50+
i20006e.scala:81: error: x is already defined as value x
51+
val x: Int = 4 // err
52+
^
53+
i20006e.scala:86: error: x is already defined as value x
54+
val x: Int = 4 // err
55+
^
56+
i20006e.scala:91: error: x is already defined as value x
57+
val x: Int = 4 // err
58+
^
59+
i20006e.scala:96: error: x is already defined as value x
60+
val x: Int = 4 // err
61+
^
62+
i20006e.scala:4: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 3:10
63+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
64+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=C1
65+
def x: Int = 4 // warn in Xsource:3
66+
^
67+
i20006e.scala:8: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 7:28
68+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
69+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=C2
70+
def x: Int = 4 // warn in Xsource:3
71+
^
72+
i20006e.scala:36: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 35:10
73+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
74+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D1
75+
def x(): Int = 4 // warn in Xsource:3
76+
^
77+
i20006e.scala:40: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 39:28
78+
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
79+
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D2
80+
def x(): Int = 4 // warn in Xsource:3
81+
^
82+
21 errors

0 commit comments

Comments
 (0)