diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index b9f9175e938c..4404ae0abf31 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -976,8 +976,22 @@ object Denotations { case FullMatch => true case MethodNotAMethodMatch => - // Java allows defining both a field and a zero-parameter method with the same name - !ctx.erasedTypes && !(symbol.is(JavaDefined) && other.symbol.is(JavaDefined)) + !ctx.erasedTypes && { + val isJava = symbol.is(JavaDefined) + val otherIsJava = other.symbol.is(JavaDefined) + // A Scala zero-parameter method and a Scala non-method always match. + if !isJava && !otherIsJava then + true + // Java allows defining both a field and a zero-parameter method with the same name, + // so they must not match. + else if isJava && otherIsJava then + false + // A Java field never matches a Scala method. + else if isJava then + symbol.is(Method) + else // otherIsJava + other.symbol.is(Method) + } case ParamMatch => // The signatures do not tell us enough to be sure about matching !ctx.erasedTypes && info.matches(other.info) diff --git a/tests/neg/i9115/B.scala b/tests/neg/i9115/B.scala index a82c8e10a198..546379b31d71 100644 --- a/tests/neg/i9115/B.scala +++ b/tests/neg/i9115/B.scala @@ -1,3 +1,3 @@ class B extends A { override val foo: String = "B" // error -} \ No newline at end of file +} diff --git a/tests/pos/i9392/J.java b/tests/pos/i9392/J.java new file mode 100644 index 000000000000..d2ad42cfc3c7 --- /dev/null +++ b/tests/pos/i9392/J.java @@ -0,0 +1,6 @@ +package pkg; + +public class J { + int i = 0; + public int i() { return 1; } +} diff --git a/tests/pos/i9392/S.scala b/tests/pos/i9392/S.scala new file mode 100644 index 000000000000..170fab266bb0 --- /dev/null +++ b/tests/pos/i9392/S.scala @@ -0,0 +1,20 @@ +class S1 extends pkg.J { + override def i(): Int = 2 +} + +// Unlike Scala 2 this doesn't compile, because this override of `i()` +// also matches the non-overridable field `i`. +// class S2 extends pkg.J { +// override def i: Int = 2 +// } + +object Test { + val s1 = new S1 + + val i1 = s1.i + val i2 = s1.i() + + // val s2 = new S2 + + // val i3 = s2.i +}