Closed
Description
Compiler version
3.0.0
Minimized code
package repro
object repro:
object opq:
opaque type Lift[T] = Int
extension(v: Int)
def lift[T]: Lift[T] = v
extension[T](l: Lift[T])
def value: Int = l
export opq.Lift as Lift
export opq.lift as lift
final type Two
extension[TL](l: Lift[TL])
def repro[TR](using m: Mul[TL, TR]): Int = l.value + m.value
abstract class Mul[TL, TR]:
val value: Int
transparent inline given mulGivenInt[TL <: Int & Singleton, TR <: Int & Singleton]: Mul[TL, TR] =
val m: Int = scala.compiletime.constValue[TL] * scala.compiletime.constValue[TR]
new Mul[TL, TR] { val value: Int = m }
transparent inline given mulGivenTwo[TR <: Int & Singleton]: Mul[Two, TR] =
val m: Int = 2 * scala.compiletime.constValue[TR]
new Mul[Two, TR] { val value: Int = m }
Output
scala> import repro.repro.{*, given}
// this works, using a type 'Two' that is not an integer literal
scala> val x = 1.lift[Two]
val x: repro.repro.opq.Lift[repro.repro.Two] = 1
scala> x.repro[2]
val res0: Int = 5
// this will fail for some reason
scala> val y = 1.lift[2]
val y: repro.repro.opq.Lift[2] = 1
scala> y.repro[2]
1 |y.repro[2]
| ^
|no implicit argument of type repro.repro.Mul[Int, (2 : Int)] was found for parameter m of method repro in object repro.
|I found:
|
| repro.repro.mulGivenInt[(Int & Singleton), (Int & Singleton)]
|
|But given instance mulGivenInt in object repro does not match type repro.repro.Mul[Int, (2 : Int)].
Expectation
In the second example val y = 1.lift[2]
I would expect that the integer literal type parameter not be widened to Int
in the call to y.repro[2]
- it should succeed and return 5
, the same as with x.repro[2]
Instead the TL
type parameter is being widened to Int
: repro.repro.Mul[Int, (2 : Int)]
It seems to be specifically related to using opaque type
- a more simple repro I attempted worked correctly, when the opaque type was not involved.