diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 3462e8455394..28b05ecd5001 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -4274,16 +4274,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer typr.println(i"adapt overloaded $ref with alternatives ${altDenots map (_.info)}%\n\n %") /** Search for an alternative that does not take parameters. - * If there is one, return it, otherwise emit an error. + * If there is one, return it, otherwise return the error tree. */ def tryParameterless(alts: List[TermRef])(error: => tpd.Tree): Tree = alts.filter(_.info.isParameterless) match - case alt :: Nil => readaptSimplified(tree.withType(alt)) - case _ => - if altDenots.exists(_.info.paramInfoss == ListOfNil) then - typed(untpd.Apply(untpd.TypedSplice(tree), Nil), pt, locked) - else - error + case alt :: Nil => readaptSimplified(tree.withType(alt)) + case _ => + altDenots.find(_.info.paramInfoss == ListOfNil) match + case Some(alt) => readaptSimplified(tree.withType(alt.symbol.denot.termRef)) + case _ => error def altRef(alt: SingleDenotation) = TermRef(ref.prefix, ref.name, alt) val alts = altDenots.map(altRef) @@ -4976,6 +4975,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case _ => NoType case _ => NoType + // begin adapt1 tree match { case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[?] | _: Closure => tree case _ => tree.tpe.widen match { diff --git a/tests/neg/i21207.scala b/tests/neg/i21207.scala new file mode 100644 index 000000000000..3a257fe08139 --- /dev/null +++ b/tests/neg/i21207.scala @@ -0,0 +1,32 @@ + +abstract class P { + def foo1(): Int = 1 + def foo2(x: Int): Int = 22 + def g4(s: String): String = s * 4 +} + +class C extends P { + def foo1(x: Int): Int = 11 + def foo2(): Int = 2 + + def foo3(): Int = 3 + def foo3(x: Int): Int = 33 + + def g4(): Int = 4 +} + +object Test extends App { + val c = new C + println(c.foo1) // error was omitted because of nullary fallback during ambiguous overload resolution + println(c.foo2) // error, add parens + println(c.foo3) // error + println(c.g4) // error + val s: String = c.g4 // error missing arg, expected type picks method + println(s) +} + +/* Scala 2 warns for all three selections: +warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method foo1, +or remove the empty argument list from its definition (Java-defined methods are exempt). +In Scala 3, an unapplied method like this will be eta-expanded into a function. [quickfixable] +*/ diff --git a/tests/warn/i21207/Over.java b/tests/warn/i21207/Over.java new file mode 100644 index 000000000000..16e18d8def79 --- /dev/null +++ b/tests/warn/i21207/Over.java @@ -0,0 +1,8 @@ + +interface I { + default int f() { return 42; } +} + +public class Over implements I { + public int f(int i) { return 42 + i; } +} diff --git a/tests/warn/i21207/usage.scala b/tests/warn/i21207/usage.scala new file mode 100644 index 000000000000..a5b6b6904cc1 --- /dev/null +++ b/tests/warn/i21207/usage.scala @@ -0,0 +1,17 @@ +//> using options -source:3.0-migration + +// Hope to see a migration warning! with quickfix. + +class P { + def g(): Int = 42 +} +class C extends P { + def g(i: Int): Int = 42 + i +} + +object Test extends App { + val over = Over() + println(over.f) // nowarn Java + val c = C() + println(c.g) // warn migration +}