diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 6e5c80e4d7d2..c84313ccae0e 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -490,7 +490,9 @@ object Denotations { * 4. The access boundary of sym2 is properly contained in the access * boundary of sym1. For protected access, we count the enclosing * package as access boundary. - * 5. sym1 a method but sym2 is not. + * 5. sym1 is a method but sym2 is not. + * 6. sym1 is a non-polymorphic method but sym2 is a polymorphic method. + * (to be consistent with infoMeet, see #4819) * The aim of these criteria is to give some disambiguation on access which * - does not depend on textual order or other arbitrary choices * - minimizes raising of doubleDef errors @@ -505,6 +507,7 @@ object Denotations { accessBoundary(sym2).isProperlyContainedIn(accessBoundary(sym1)) || sym2.is(Bridge) && !sym1.is(Bridge) || sym1.is(Method) && !sym2.is(Method)) || + sym1.info.isInstanceOf[MethodType] && sym2.info.isInstanceOf[PolyType] || sym1.info.isErroneous) /** Sym preference provided types also override */ diff --git a/tests/neg/i4819.scala b/tests/neg/i4819.scala new file mode 100644 index 000000000000..224682fc000c --- /dev/null +++ b/tests/neg/i4819.scala @@ -0,0 +1,16 @@ +trait One[X] { + def concat(suffix: Int): X = ??? +} + +trait Two[Y <: Foo] { + def concat[Dummy](suffix: Int): Y = ??? +} + +class Foo extends One[Foo] with Two[Foo] { + concat(0) // OK + + // TODO: This does not typecheck because the polymorphic overload is masked + // (we merge the denotations for both overloads into one and always prefer + // MethodType to PolyType, instead we should return a MultiDenotation). See #4819. + concat[Int](0) // error (that should actually not be an error) +} diff --git a/tests/pos/i4819.scala b/tests/pos/i4819.scala new file mode 100644 index 000000000000..508c579a8753 --- /dev/null +++ b/tests/pos/i4819.scala @@ -0,0 +1,12 @@ +trait One[X] { + def concat(suffix: Int): X = ??? +} + +trait Two[Y <: Foo] { + def concat[Dummy](suffix: Int): Y = ??? +} + +class Foo extends One[Foo] with Two[Foo] { + concat(0) // OK + // See also tests/neg/i4819.scala +}