scala/scala3

Wrong warning emitted during implicit resolution

Closed this issue · 2 comments

Compiler version

current main branch (d3df8ca)

Minimized example

given Int = ???
given Char = ???
val a = summon[Int]

Output Error/Warning message

> scala test.scala
-- Warning: test.scala:3:19 ----------------------------------------------------
3 |val a = summon[Int]
  |                   ^
  |Given search preference for Int between alternatives (given_Int : Int) and (given_Char : Char) will change
  |Current choice           : the second alternative
  |New choice from Scala 3.6: the first alternative
1 warning found

Why this Error/Warning was not helpful

This warning should not be triggered at the first place. When printing the ast after typer, we can see that it resolved to the correct given. We can see that the compiler will emit the following code:

> scalac -Xprint:typer test.scala
-- Warning: test.scala:3:19 ----------------------------------------------------
3 |val a = summon[Int]
  |                   ^
  |Given search preference for Int between alternatives (given_Int : Int) and (given_Char : Char) will change
  |Current choice           : the second alternative
  |New choice from Scala 3.6: the first alternative
[[syntax trees at end of                     typer]] // test.scala
package <empty> {
  final lazy module val test$package: test$package = new test$package()
  final module class test$package() extends Object() {
    this: test$package.type =>
    final lazy given val given_Int: Int = ???
    final lazy given val given_Char: Char = ???
    val a: Int = given_Int
  }
}

We observe the correct behaviour if we set the source version to 3.4 or 3.6

> scalac -source 3.4 test.scala
[[syntax trees at end of                     typer]] // test.scala
package <empty> {
  final lazy module val test$package: test$package = new test$package()
  final module class test$package() extends Object() {
    this: test$package.type =>
    final lazy given val given_Int: Int = ???
    final lazy given val given_Char: Char = ???
    val a: Int = given_Int
  }
}
> scalac -source 3.6 test.scala
[[syntax trees at end of                     typer]] // test.scala
package <empty> {
  final lazy module val test$package: test$package = new test$package()
  final module class test$package() extends Object() {
    this: test$package.type =>
    final lazy given val given_Int: Int = ???
    final lazy given val given_Char: Char = ???
    val a: Int = given_Int
  }
}

Suggested improvement

The warning should not be emitted at the first place.

Swapping the definition of the givens doesn't emit the warning:

given Char = ???
given Int = ???
val a = summon[Int]

Discussion here: #20480