Skip to content

Commit

Permalink
Merge pull request scala#10855 from lrytz/i20006-privateacc
Browse files Browse the repository at this point in the history
No double def in Scala 2 for private[this] param and matching method
  • Loading branch information
lrytz authored Sep 4, 2024
2 parents 52b2013 + 1e46a0b commit 6e2b765
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 28 deletions.
6 changes: 5 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3429,6 +3429,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
while ((e1 ne null) && e1.owner == scope) {
val sym1 = e1.sym

def allowPrivateLocalAcc: Boolean =
sym.isParamAccessor && sym.isPrivateLocal || sym1.isParamAccessor && sym1.isPrivateLocal
def nullaryNilary: Boolean = {
def nn(m: Symbol): Boolean = m.isParamAccessor || m.hasAccessorFlag || !m.isMethod || {
m.tpe match {
Expand All @@ -3443,7 +3445,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (currentRun.isScala3 && !currentRun.sourceFeatures.doubleDefinitions)
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)

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

// default getters are defined twice when multiple overloads have defaults.
// The error for this is deferred until RefChecks.checkDefaultsInOverloaded
Expand Down
14 changes: 1 addition & 13 deletions test/files/neg/i20006.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,9 @@ i20006.scala:7: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 5:7
override def hasNext: Boolean = first || hasNext(acc) // error
^
i20006.scala:21: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 18:42
override def hasNext: Boolean = first || hasNext(acc) // error
^
i20006.scala:35: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 32:42
def hasNext: Boolean = first || hasNext(acc) // error
^
i20006.scala:47: error: x is already defined as value x
val x: String = "member" // error
^
i20006.scala:50: error: variable x is defined twice;
the conflicting value x was defined at line 49:9
private var x: Int = 42 // error
^
i20006.scala:53: error: x is already defined as value x
private[this] var x: Int = 42 // error
^
Expand All @@ -31,4 +19,4 @@ i20006.scala:67: error: method x is defined twice;
i20006.scala:77: error: x is already defined as variable x
def x(): Int = x // error
^
9 errors
6 errors
27 changes: 15 additions & 12 deletions test/files/neg/i20006b.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,9 @@ i20006b.scala:8: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 6:7
override def hasNext: Boolean = first || hasNext(acc) // error
^
i20006b.scala:22: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 19:42
override def hasNext: Boolean = first || hasNext(acc) // error
^
i20006b.scala:36: error: method hasNext is defined twice;
the conflicting value hasNext was defined at line 33:42
def hasNext: Boolean = first || hasNext(acc) // error
^
i20006b.scala:48: error: x is already defined as value x
val x: String = "member" // error
^
i20006b.scala:51: error: variable x is defined twice;
the conflicting value x was defined at line 50:9
private var x: Int = 42 // error
^
i20006b.scala:54: error: x is already defined as value x
private[this] var x: Int = 42 // error
^
Expand All @@ -36,11 +24,26 @@ Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=YIterateIterator
override def next(): T = { // werror
^
i20006b.scala:22: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 19:42
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=YIterateIterator
override def hasNext: Boolean = first || hasNext(acc) // error
^
i20006b.scala:37: error: Double definition will be detected in Scala 3; the conflicting value next is defined at 33:65
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=ZIterateIterator
def next(): T = { // werror
^
i20006b.scala:36: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 33:42
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=ZIterateIterator
def hasNext: Boolean = first || hasNext(acc) // error
^
i20006b.scala:51: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 50:9
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D
private var x: Int = 42 // error
^
i20006b.scala:57: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 56:9
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=F
Expand Down
62 changes: 62 additions & 0 deletions test/files/neg/i20006d.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
i20006d.scala:12: error: method x is defined twice;
the conflicting value x was defined at line 11:22
def x: Int = 4 // err
^
i20006d.scala:17: error: method x is defined twice;
the conflicting value x was defined at line 16:28
def x: Int = 4 // err
^
i20006d.scala:22: error: method x is defined twice;
the conflicting value x was defined at line 21:24
def x: Int = 4 // err
^
i20006d.scala:27: error: method x is defined twice;
the conflicting value x was defined at line 26:30
def x: Int = 4 // err
^
i20006d.scala:32: error: method x is defined twice;
the conflicting value x was defined at line 31:14
def x: Int = 4 // err
^
i20006d.scala:44: error: method x is defined twice;
the conflicting value x was defined at line 43:22
def x(): Int = 4 // err
^
i20006d.scala:49: error: method x is defined twice;
the conflicting value x was defined at line 48:28
def x(): Int = 4 // err
^
i20006d.scala:54: error: method x is defined twice;
the conflicting value x was defined at line 53:24
def x(): Int = 4 // err
^
i20006d.scala:59: error: method x is defined twice;
the conflicting value x was defined at line 58:30
def x(): Int = 4 // err
^
i20006d.scala:64: error: method x is defined twice;
the conflicting value x was defined at line 63:14
def x(): Int = 4 // err
^
i20006d.scala:68: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:72: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:76: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:81: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:86: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:91: error: x is already defined as value x
val x: Int = 4 // err
^
i20006d.scala:96: error: x is already defined as value x
val x: Int = 4 // err
^
17 errors
97 changes: 97 additions & 0 deletions test/files/neg/i20006d.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//> using options -Werror

class C1(x: String) {
def x: Int = 4 // ok in Scala 2
}

class C2(private[this] val x: String) {
def x: Int = 4 // ok in Scala 2
}

class C3(private val x: String) {
def x: Int = 4 // err
}

object o4 {
class C4(private[o4] val x: String) {
def x: Int = 4 // err
}
}

class C5(protected val x: String) {
def x: Int = 4 // err
}

object o6 {
class C6(protected[o6] val x: String) {
def x: Int = 4 // err
}
}

class C7(val x: String) {
def x: Int = 4 // err
}

class D1(x: String) {
def x(): Int = 4 // ok
}

class D2(private[this] val x: String) {
def x(): Int = 4 // ok
}

class D3(private val x: String) {
def x(): Int = 4 // err
}

object p4 {
class D4(private[p4] val x: String) {
def x(): Int = 4 // err
}
}

class D5(protected val x: String) {
def x(): Int = 4 // err
}

object p6 {
class D6(protected[p6] val x: String) {
def x(): Int = 4 // err
}
}

class D7(val x: String) {
def x(): Int = 4 // err
}

class E1(x: String) {
val x: Int = 4 // err
}

class E2(private[this] val x: String) {
val x: Int = 4 // err
}

class E3(private val x: String) {
val x: Int = 4 // err
}

object q4 {
class E4(private[q4] val x: String) {
val x: Int = 4 // err
}
}

class E5(protected val x: String) {
val x: Int = 4 // err
}

object q6 {
class E6(protected[q6] val x: String) {
val x: Int = 4 // err
}
}

class E7(val x: String) {
val x: Int = 4 // err
}
82 changes: 82 additions & 0 deletions test/files/neg/i20006e.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
i20006e.scala:12: error: method x is defined twice;
the conflicting value x was defined at line 11:22
def x: Int = 4 // err
^
i20006e.scala:17: error: method x is defined twice;
the conflicting value x was defined at line 16:28
def x: Int = 4 // err
^
i20006e.scala:22: error: method x is defined twice;
the conflicting value x was defined at line 21:24
def x: Int = 4 // err
^
i20006e.scala:27: error: method x is defined twice;
the conflicting value x was defined at line 26:30
def x: Int = 4 // err
^
i20006e.scala:32: error: method x is defined twice;
the conflicting value x was defined at line 31:14
def x: Int = 4 // err
^
i20006e.scala:44: error: method x is defined twice;
the conflicting value x was defined at line 43:22
def x(): Int = 4 // err
^
i20006e.scala:49: error: method x is defined twice;
the conflicting value x was defined at line 48:28
def x(): Int = 4 // err
^
i20006e.scala:54: error: method x is defined twice;
the conflicting value x was defined at line 53:24
def x(): Int = 4 // err
^
i20006e.scala:59: error: method x is defined twice;
the conflicting value x was defined at line 58:30
def x(): Int = 4 // err
^
i20006e.scala:64: error: method x is defined twice;
the conflicting value x was defined at line 63:14
def x(): Int = 4 // err
^
i20006e.scala:68: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:72: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:76: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:81: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:86: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:91: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:96: error: x is already defined as value x
val x: Int = 4 // err
^
i20006e.scala:4: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 3:10
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=C1
def x: Int = 4 // warn in Xsource:3
^
i20006e.scala:8: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 7:28
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=C2
def x: Int = 4 // warn in Xsource:3
^
i20006e.scala:36: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 35:10
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D1
def x(): Int = 4 // warn in Xsource:3
^
i20006e.scala:40: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 39:28
Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress.
Applicable -Wconf / @nowarn filters for this fatal warning: msg=<part of the message>, cat=scala3-migration, site=D2
def x(): Int = 4 // warn in Xsource:3
^
21 errors
Loading

0 comments on commit 6e2b765

Please sign in to comment.