Skip to content

Commit

Permalink
Delay overloading priority changes to 3.8
Browse files Browse the repository at this point in the history
With the warnings about the changes enabled in 3.7 and 3.8-migration
  • Loading branch information
EugeneFlesselle committed Feb 10, 2025
1 parent 6d05485 commit e8b9cee
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 22 deletions.
13 changes: 6 additions & 7 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2226,18 +2226,20 @@ trait Applications extends Compatibility {
record(s"resolveOverloaded1", alts.length)

val sv = Feature.sourceVersion
val isOldPriorityVersion: Boolean = sv.isAtMost(SourceVersion.`3.6`)
val isWarnPriorityChangeVersion = sv == SourceVersion.`3.6` || sv == SourceVersion.`3.7-migration`
val isOldPriorityVersion: Boolean = sv.isAtMost(SourceVersion.`3.7`)
val isWarnPriorityChangeVersion = sv == SourceVersion.`3.7` || sv == SourceVersion.`3.8-migration`

inline def warnOnPriorityChange(oldCands: List[TermRef], newCands: List[TermRef])(f: List[TermRef] => List[TermRef]): List[TermRef] =
def warnOnPriorityChange(oldCands: List[TermRef], newCands: List[TermRef])(f: List[TermRef] => List[TermRef]): List[TermRef] =
lazy val oldRes = f(oldCands)
val newRes = f(newCands)

def doWarn(oldChoice: String, newChoice: String): Unit =
val (change, whichChoice) =
if isOldPriorityVersion
then ("will change", "Current choice ")
else ("has changed", "Previous choice")

val msg = // uses oldCands as the list of alternatives since they should be a superset of newCands
val msg = // using oldCands to list the alternatives as they should be a superset of newCands
em"""Overloading resolution for ${err.expectedTypeStr(pt)} between alternatives
| ${oldCands map (_.info)}%\n %
|$change.
Expand All @@ -2247,9 +2249,6 @@ trait Applications extends Compatibility {
report.warning(msg, srcPos)
end doWarn

lazy val oldRes = f(oldCands)
val newRes = f(newCands)

if isWarnPriorityChangeVersion then (oldRes, newRes) match
case (oldAlt :: Nil, newAlt :: Nil) if oldAlt != newAlt => doWarn(oldAlt.info.show, newAlt.info.show)
case (oldAlt :: Nil, Nil) => doWarn(oldAlt.info.show, "none")
Expand Down
6 changes: 3 additions & 3 deletions tests/neg/multiparamlist-overload-3.6.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
-- [E007] Type Mismatch Error: tests/neg/multiparamlist-overload-3.6.scala:33:21 ---------------------------------------
33 | val r = f(new B)(new A) // error since resolves to R2 in 3.6 (and 3.7) as expected
33 | val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.8) as expected
| ^^^^^
| Found: A
| Required: B
|
| longer explanation available when compiling with `-explain`
-- Warning: tests/neg/multiparamlist-overload-3.6.scala:20:10 ----------------------------------------------------------
20 | val r = f(new B)(new C) // resolves to R1 in 3.6
20 | val r = f(new B)(new C) // resolves to: R1 in 3.7, R3 in 3.8
| ^
| Overloading resolution for arguments (B)(C) between alternatives
| (x: B)(y: B): R3
Expand All @@ -16,7 +16,7 @@
| Current choice : (x: A)(y: C): R1
| New choice from Scala 3.7: (x: B)(y: B): R3
-- Warning: tests/neg/multiparamlist-overload-3.6.scala:40:12 ----------------------------------------------------------
40 | val r = f(new B)(new A) // resolves to R1 in 3.6
40 | val r = f(new B)(new A) // resolves to: R1 in 3.7, R2 in 3.8 as in Part1
| ^
| Overloading resolution for arguments (B)(A) between alternatives
| (x: B)(y: C): R3
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/multiparamlist-overload-3.6.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scala.language.`3.6`
import scala.language.`3.7`

class A
class B extends A
Expand All @@ -17,7 +17,7 @@ object Test1:
def f(x: B)(y: A) = new R2
def f(x: B)(y: B) = new R3

val r = f(new B)(new C) // resolves to R1 in 3.6
val r = f(new B)(new C) // resolves to: R1 in 3.7, R3 in 3.8
val _: R1 = r
end Test1

Expand All @@ -30,14 +30,14 @@ object Test2:
def f(x: A)(y: A) = new R1
def f(x: B)(y: B) = new R2

val r = f(new B)(new A) // error since resolves to R2 in 3.6 (and 3.7) as expected
val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.8) as expected

object Part2:
def f(x: A)(y: A) = new R1
def f(x: B)(y: B) = new R2
def f(x: B)(y: C) = new R3

val r = f(new B)(new A) // resolves to R1 in 3.6
val r = f(new B)(new A) // resolves to: R1 in 3.7, R2 in 3.8 as in Part1
val _: R1 = r

end Test2
6 changes: 3 additions & 3 deletions tests/neg/multiparamlist-overload-3.7.check
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
-- [E007] Type Mismatch Error: tests/neg/multiparamlist-overload-3.7.scala:33:21 ---------------------------------------
33 | val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.6), as expected
33 | val r = f(new B)(new A) // error, since resolves to R2 in both 3.7 and 3.8, as expected
| ^^^^^
| Found: A
| Required: B
|
| longer explanation available when compiling with `-explain`
-- [E134] Type Error: tests/neg/multiparamlist-overload-3.7.scala:40:12 ------------------------------------------------
40 | val r = f(new B)(new A) // error since resolves to R2 in 3.7, as in Part1
40 | val r = f(new B)(new A) // error since resolves to R2 in 3.8 as in Part1 (was R1 in 3.7)
| ^
| None of the overloaded alternatives of method f in object Part2 with types
| (x: B)(y: C): R3
| (x: B)(y: B): R2
| (x: A)(y: A): R1
| match arguments (B)(A)
-- Warning: tests/neg/multiparamlist-overload-3.7.scala:20:10 ----------------------------------------------------------
20 | val r = f(new B)(new C) // resolves to R3 in 3.7
20 | val r = f(new B)(new C) // resolves to: R1 in 3.7, R3 in 3.8
| ^
| Overloading resolution for arguments (B)(C) between alternatives
| (x: B)(y: B): R3
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/multiparamlist-overload-3.7.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scala.language.`3.7-migration`
import scala.language.`3.8-migration`

class A
class B extends A
Expand All @@ -17,7 +17,7 @@ object Test1:
def f(x: B)(y: A) = new R2
def f(x: B)(y: B) = new R3

val r = f(new B)(new C) // resolves to R3 in 3.7
val r = f(new B)(new C) // resolves to: R1 in 3.7, R3 in 3.8
val _: R3 = r
end Test1

Expand All @@ -30,13 +30,13 @@ object Test2:
def f(x: A)(y: A) = new R1
def f(x: B)(y: B) = new R2

val r = f(new B)(new A) // error since resolves to R2 in 3.7 (and 3.6), as expected
val r = f(new B)(new A) // error, since resolves to R2 in both 3.7 and 3.8, as expected

object Part2:
def f(x: A)(y: A) = new R1
def f(x: B)(y: B) = new R2
def f(x: B)(y: C) = new R3

val r = f(new B)(new A) // error since resolves to R2 in 3.7, as in Part1
val r = f(new B)(new A) // error since resolves to R2 in 3.8 as in Part1 (was R1 in 3.7)

end Test2
2 changes: 1 addition & 1 deletion tests/neg/scalatest-overload-3.7.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scala.language.`3.7`
import scala.language.`3.8`

class TestBody1
class TestBody2
Expand Down

0 comments on commit e8b9cee

Please sign in to comment.