Skip to content

Commit d8164b5

Browse files
committed
Add missing double definition checks
In 668a637, `Denotation#matches` was refined to not return true for types that cannot override each other from Scala's point of view, however this method was also used to detect methods that override each other from the JVM point of view, i.e. methods which will end up with the same signature in bytecode. This commit refines `checkNoDoubleDeclaration` to also explicitly check for clashing signatures.
1 parent a3cf20e commit d8164b5

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) {
8282
else NoMatch
8383
else NoMatch
8484

85+
/** Does this signature potentially clash with `that` ? */
86+
def clashes(that: Signature)(implicit ctx: Context): Boolean =
87+
matchDegree(that) == FullMatch
88+
8589
/** name.toString == "" or name.toString == "_" */
8690
private def isWildcard(name: TypeName) = name.isEmpty || name == tpnme.WILDCARD
8791

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ trait Checking {
752752
def javaFieldMethodPair =
753753
decl.is(JavaDefined) && other.is(JavaDefined) &&
754754
decl.is(Method) != other.is(Method)
755-
if (decl.matches(other) && !javaFieldMethodPair) {
755+
if ((decl.signature.clashes(other.signature) || decl.matches(other)) && !javaFieldMethodPair) {
756756
def doubleDefError(decl: Symbol, other: Symbol): Unit =
757757
if (!decl.info.isErroneous && !other.info.isErroneous)
758758
ctx.error(DoubleDefinition(decl, other, cls), decl.sourcePos)

tests/neg/doubleDefinition.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
<2471..2471> in doubleDefinition.scala
2+
Double definition:
3+
def foo: [T <: Int](x: T): T in class Test20 at line 143 and
4+
def foo: [S <: Int, T <: Int](x: S): T in class Test20 at line 144
5+
have the same type after erasure.
6+
<2338..2338> in doubleDefinition.scala
7+
Double definition:
8+
def foo: [T <: Int](x: T): T in class Test19 at line 137 and
9+
def foo(x: Int): Int in class Test19 at line 138
10+
have the same type after erasure.
111
<2016..2016> in doubleDefinition.scala
212
Double definition:
313
var foo: Int in class Test16 at line 115 and

tests/neg/doubleDefinition.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,15 @@ class Test18 {
131131
def foo(a: A) = 1
132132
def foo(b: B) = 1
133133
}
134+
135+
// Error when overloading polymorphic and non-polymorphic methods
136+
class Test19 {
137+
def foo[T <: Int](x: T): T = x
138+
def foo(x: Int): Int = x // error
139+
}
140+
141+
// Error when overloading polymorphic methods
142+
class Test20 {
143+
def foo[T <: Int](x: T): T = x
144+
def foo[S <: Int, T <: Int](x: S): T = ??? // error
145+
}

0 commit comments

Comments
 (0)