From 8f63854b423c580557c9c47bd14baeb7d8a2ef09 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 27 Feb 2021 11:26:21 +0100 Subject: [PATCH 1/2] Improve error message in overloading resolution Improve error message when trying to do overloading resolution of alternatives introduces by refinements. As i8736 shows, it's not so simple to identify overloaded members introduced by refinements, since this can arise through intersection and de-aliasing. So our best bet is to make the error message clearer at the point of overloading resolution. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 17 ++++++----------- tests/neg/i11544.scala | 7 +++++++ tests/neg/i8736.check | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 tests/neg/i11544.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index adcf485158c4..2a9814ba19d5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1779,7 +1779,6 @@ class Typer extends Namer tpt1.tpe.typeSymbol == defn.PolyFunctionClass && rsym.name == nme.apply if (!polymorphicRefinementAllowed && rsym.info.isInstanceOf[PolyType] && rsym.allOverriddenSymbols.isEmpty) report.error(PolymorphicMethodMissingTypeInParent(rsym, tpt1.symbol), refinement.srcPos) - val member = refineCls.info.member(rsym.name) if (member.isOverloaded) report.error(OverloadInRefinement(rsym), refinement.srcPos) @@ -3124,20 +3123,16 @@ class Typer extends Namer } } case ambiAlts => - if (tree.tpe.isErroneous || pt.isErroneous) tree.withType(UnspecifiedErrorType) - else { + if tree.tpe.isErroneous || pt.isErroneous then tree.withType(UnspecifiedErrorType) + else val remainingDenots = altDenots.filter(denot => ambiAlts.contains(altRef(denot))) val addendum = - if ambiAlts.toSet.size != ambiAlts.size then - // Several variants have the same signature. This can happen for structural - // type selections. See i8736.scala - """| - | - |Note: this happens because two or more alternatives have the same erasure, - | so they cannot be distinguished by overloading resolution""".stripMargin + if ambiAlts.exists(!_.symbol.exists) then + i"""| + | + |Note: Overloaded definitions introduced by refinements cannot be resolved""" else "" errorTree(tree, AmbiguousOverload(tree, remainingDenots, pt, addendum)) - } } } diff --git a/tests/neg/i11544.scala b/tests/neg/i11544.scala new file mode 100644 index 000000000000..6dd1f4f9166b --- /dev/null +++ b/tests/neg/i11544.scala @@ -0,0 +1,7 @@ +import language.reflectiveCalls + +object Foo { + val m: ({ def foo(str: String, int: Int): Int }){ def foo(arg: Int): Int } = ??? + val m1 = m + val n = m1.foo(23) // error +} \ No newline at end of file diff --git a/tests/neg/i8736.check b/tests/neg/i8736.check index c38b40682838..d99c7ca34c09 100644 --- a/tests/neg/i8736.check +++ b/tests/neg/i8736.check @@ -17,7 +17,6 @@ | (k: ("z" : String)): Boolean | all match arguments (("z" : String)) | - | Note: this happens because two or more alternatives have the same erasure, - | so they cannot be distinguished by overloading resolution + | Note: Overloaded definitions introduced by refinements cannot be resolved longer explanation available when compiling with `-explain` From f1a6bdf6161ee126de87e2e5accffa7223613a1b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 27 Feb 2021 11:44:24 +0100 Subject: [PATCH 2/2] Add check file --- tests/neg/i11544.check | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/neg/i11544.check diff --git a/tests/neg/i11544.check b/tests/neg/i11544.check new file mode 100644 index 000000000000..b4dba8a072c4 --- /dev/null +++ b/tests/neg/i11544.check @@ -0,0 +1,11 @@ +-- [E051] Reference Error: tests/neg/i11544.scala:6:13 ----------------------------------------------------------------- +6 | val n = m1.foo(23) // error + | ^^^^^^ + | Ambiguous overload. The overloaded alternatives of method (str: String, int: Int): Int with types + | (str: String, int: Int): Int + | (arg: Int): Int + | both match arguments ((23 : Int)) + | + | Note: Overloaded definitions introduced by refinements cannot be resolved + +longer explanation available when compiling with `-explain`