Skip to content

Commit f40c609

Browse files
Test overloading changes and reported warning messages
Note that in tests/neg/multiparamlist-overload-3.7 Test2 we now get an error in both Parts as intended. But they are, however, different ones: Part1 is a TypeMismatch Error, whereas Part2 is a NoMatchingOverload Error. This is due to the fact that `resolveOverloaded` will first find the candidate alternatives by considering only the 1st parameter list and commit early if there is a single one, e.g. Test2.Part1. If not, we recursively continue with the found alternatives and recompute the candidate alternatives based on the 2nd parameter list, which may rule out all of them, and hence lead to a different message.
1 parent 2e0cff0 commit f40c609

8 files changed

+219
-2
lines changed

tests/neg/i10901.check

+36
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
-- [E008] Not Found Error: tests/neg/i10901.scala:45:38 ----------------------------------------------------------------
2+
45 | val pos1: Point2D[Int,Double] = x º y // error
3+
| ^^^
4+
| value º is not a member of object BugExp4Point2D.IntT.
5+
| An extension method was tried, but could not be fully constructed:
6+
|
7+
| º(x)
8+
|
9+
| failed with:
10+
|
11+
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
12+
| [T1, T2]
13+
| (x: BugExp4Point2D.ColumnType[T1])
14+
| (y: BugExp4Point2D.ColumnType[T2])
15+
| (using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
16+
| [T1, T2]
17+
| (x: T1)
18+
| (y: BugExp4Point2D.ColumnType[T2])
19+
| (using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
20+
| both match arguments ((x : BugExp4Point2D.IntT.type))((y : BugExp4Point2D.DoubleT.type))
21+
-- [E008] Not Found Error: tests/neg/i10901.scala:48:38 ----------------------------------------------------------------
22+
48 | val pos4: Point2D[Int,Double] = x º 201.1 // error
23+
| ^^^
24+
|value º is not a member of object BugExp4Point2D.IntT.
25+
|An extension method was tried, but could not be fully constructed:
26+
|
27+
| º(x)
28+
|
29+
| failed with:
30+
|
31+
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
32+
| [T1, T2]
33+
| (x: BugExp4Point2D.ColumnType[T1])
34+
| (y: T2)(using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
35+
| [T1, T2](x: T1)(y: T2)(using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
36+
| both match arguments ((x : BugExp4Point2D.IntT.type))((201.1d : Double))
137
-- [E008] Not Found Error: tests/neg/i10901.scala:62:16 ----------------------------------------------------------------
238
62 | val y = "abc".foo // error
339
| ^^^^^^^^^

tests/neg/i10901.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ object BugExp4Point2D {
4242
val x = IntT
4343
val y = DoubleT
4444

45-
val pos1: Point2D[Int,Double] = x º y // ok
45+
val pos1: Point2D[Int,Double] = x º y // error
4646
val pos2: Point2D[Int,Double] = 100 º 200.1 // ok
4747
val pos3: Point2D[Int,Double] = 101 º y // ok
48-
val pos4: Point2D[Int,Double] = x º 201.1 // ok
48+
val pos4: Point2D[Int,Double] = x º 201.1 // error
4949

5050
}
5151
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-- [E007] Type Mismatch Error: tests/neg/multiparamlist-overload-3.6.scala:33:21 ---------------------------------------
2+
33 | val r = f(new B)(new A) // error since resolves to R2 in 3.6 (and 3.7) as expected
3+
| ^^^^^
4+
| Found: A
5+
| Required: B
6+
|
7+
| longer explanation available when compiling with `-explain`
8+
-- Warning: tests/neg/multiparamlist-overload-3.6.scala:20:10 ----------------------------------------------------------
9+
20 | val r = f(new B)(new C) // resolves to R1 in 3.6
10+
| ^
11+
| Overloading resolution for arguments (B)(C) between alternatives
12+
| (x: B)(y: B): R3
13+
| (x: B)(y: A): R2
14+
| (x: A)(y: C): R1
15+
| will change.
16+
| Current choice : (x: A)(y: C): R1
17+
| New choice from Scala 3.7: (x: B)(y: B): R3
18+
-- Warning: tests/neg/multiparamlist-overload-3.6.scala:40:12 ----------------------------------------------------------
19+
40 | val r = f(new B)(new A) // resolves to R1 in 3.6
20+
| ^
21+
| Overloading resolution for arguments (B)(A) between alternatives
22+
| (x: B)(y: C): R3
23+
| (x: B)(y: B): R2
24+
| (x: A)(y: A): R1
25+
| will change.
26+
| Current choice : (x: A)(y: A): R1
27+
| New choice from Scala 3.7: none
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import scala.language.`3.6`
2+
3+
class A
4+
class B extends A
5+
class C extends B
6+
7+
class R1
8+
class R2
9+
class R3
10+
11+
// The alternatives are ordered from most genereal to most specific in each test,
12+
// with respect to a lexicographic ordering by parameter list.
13+
14+
15+
object Test1:
16+
def f(x: A)(y: C) = new R1
17+
def f(x: B)(y: A) = new R2
18+
def f(x: B)(y: B) = new R3
19+
20+
val r = f(new B)(new C) // resolves to R1 in 3.6
21+
val _: R1 = r
22+
end Test1
23+
24+
25+
object Test2:
26+
// R1 is the only applicable alternative in both parts
27+
// but it is only resolved to in Part2 by adding (an unapplicable) R3
28+
29+
object Part1:
30+
def f(x: A)(y: A) = new R1
31+
def f(x: B)(y: B) = new R2
32+
33+
val r = f(new B)(new A) // error since resolves to R2 in 3.6 (and 3.7) as expected
34+
35+
object Part2:
36+
def f(x: A)(y: A) = new R1
37+
def f(x: B)(y: B) = new R2
38+
def f(x: B)(y: C) = new R3
39+
40+
val r = f(new B)(new A) // resolves to R1 in 3.6
41+
val _: R1 = r
42+
43+
end Test2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- [E007] Type Mismatch Error: tests/neg/multiparamlist-overload-3.7.scala:33:21 ---------------------------------------
2+
33 | val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.6), as expected
3+
| ^^^^^
4+
| Found: A
5+
| Required: B
6+
|
7+
| longer explanation available when compiling with `-explain`
8+
-- [E134] Type Error: tests/neg/multiparamlist-overload-3.7.scala:40:12 ------------------------------------------------
9+
40 | val r = f(new B)(new A) // error since resolves to R2 in 3.7, as in Part1
10+
| ^
11+
| None of the overloaded alternatives of method f in object Part2 with types
12+
| (x: B)(y: C): R3
13+
| (x: B)(y: B): R2
14+
| (x: A)(y: A): R1
15+
| match arguments (B)(A)
16+
-- Warning: tests/neg/multiparamlist-overload-3.7.scala:20:10 ----------------------------------------------------------
17+
20 | val r = f(new B)(new C) // resolves to R3 in 3.7
18+
| ^
19+
| Overloading resolution for arguments (B)(C) between alternatives
20+
| (x: B)(y: B): R3
21+
| (x: B)(y: A): R2
22+
| (x: A)(y: C): R1
23+
| has changed.
24+
| Previous choice : (x: A)(y: C): R1
25+
| New choice from Scala 3.7: (x: B)(y: B): R3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import scala.language.`3.7-migration`
2+
3+
class A
4+
class B extends A
5+
class C extends B
6+
7+
class R1
8+
class R2
9+
class R3
10+
11+
// The alternatives are ordered from most genereal to most specific in each test,
12+
// with respect to a lexicographic ordering by parameter list.
13+
14+
15+
object Test1:
16+
def f(x: A)(y: C) = new R1
17+
def f(x: B)(y: A) = new R2
18+
def f(x: B)(y: B) = new R3
19+
20+
val r = f(new B)(new C) // resolves to R3 in 3.7
21+
val _: R3 = r
22+
end Test1
23+
24+
25+
object Test2:
26+
// R1 is the only applicable alternative in both parts
27+
// but it is never resolved to since R2 has a more specific 1st parameter list
28+
29+
object Part1:
30+
def f(x: A)(y: A) = new R1
31+
def f(x: B)(y: B) = new R2
32+
33+
val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.6), as expected
34+
35+
object Part2:
36+
def f(x: A)(y: A) = new R1
37+
def f(x: B)(y: B) = new R2
38+
def f(x: B)(y: C) = new R3
39+
40+
val r = f(new B)(new A) // error since resolves to R2 in 3.7, as in Part1
41+
42+
end Test2
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import scala.language.`3.7`
2+
3+
class TestBody1
4+
class TestBody2
5+
6+
class StartWithWord
7+
class EndWithWord
8+
9+
class Matchers:
10+
extension (leftSideString: String)
11+
def should(body: TestBody1): Unit = ()
12+
def should(body: TestBody2): Unit = ()
13+
14+
extension [T](leftSideValue: T)
15+
def should(word: StartWithWord)(using T <:< String): Unit = ()
16+
def should(word: EndWithWord)(using T <:< String): Unit = ()
17+
18+
def endWith(rightSideString: String): EndWithWord = new EndWithWord
19+
20+
class Test extends Matchers:
21+
def test(): Unit =
22+
"hello world" should endWith ("world") // error
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import scala.language.`3.6`
2+
3+
class TestBody1
4+
class TestBody2
5+
6+
class StartWithWord
7+
class EndWithWord
8+
9+
class Matchers:
10+
extension (leftSideString: String)
11+
def should(body: TestBody1): Unit = ()
12+
def should(body: TestBody2): Unit = ()
13+
14+
extension [T](leftSideValue: T)
15+
def should(word: StartWithWord)(using T <:< String): Unit = ()
16+
def should(word: EndWithWord)(using T <:< String): Unit = ()
17+
18+
def endWith(rightSideString: String): EndWithWord = new EndWithWord
19+
20+
class Test extends Matchers:
21+
def test(): Unit =
22+
"hello world" should endWith ("world") // ok, error in 3.7

0 commit comments

Comments
 (0)