scala3
scala3 copied to clipboard
Refinements lost in inferred type
Compiler version
3.4.0
Minimized code
import scala.deriving.Mirror
case class A(x: Int, y: String)
trait SomeTrait[T]
object SomeTrait:
given [T]: SomeTrait[T] with {}
def f1[T](using p: Mirror.ProductOf[T]): Tuple.Elem[p.MirroredElemTypes, 0] = ???
def f2[T, R](f: T => R)(using SomeTrait[R]) = ???
// Scala3.3 is fine, 3.4 has compilation errors, p MirroredElemTypes type is missing and has been changed to Nothing
val x = f2(_ => f1[A])
Output
-- [E172] Type Error: ----------------------------------------------------------
13 |val x = f2(_ => f1[A])
| ^
| No given instance of type SomeTrait[
| <error Match type reduction failed since selector Nothing
| matches none of the cases
|
| case x *: xs => (0 : Int) match {
| case (0 : Int) => x
| case scala.compiletime.ops.int.S[n1] => Tuple.Elem[xs, n1]
| }>
| ] was found for parameter x$2 of method f2
1 error found
Expectation
The code is working properly
changing some definitions around, it seems like the refinements to the mirror are not being kept:
scala> case class A(x: Int, y: String)
|
| trait SomeTrait[T]
|
| object SomeTrait:
| given [T]: SomeTrait[T] with {}
|
| def f1[T](using p: Mirror.ProductOf[T]): p.type = p
|
| def f2[T, R](f: T => R)(using SomeTrait[R]): R = ???
|
| def x = f2(_ => f1[A])
// defined case class A
// defined trait SomeTrait
// defined object SomeTrait
def f1[T](using p: scala.deriving.Mirror.ProductOf[T]): p.type
def f2[T, R](f: T => R)(using x$2: SomeTrait[R]): R
def x: scala.deriving.Mirror.ProductOf[A]
more verbosely:
scala -S 3 -Xprint:typer
Welcome to Scala 3.4.0 (21.0.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> import scala.deriving.Mirror
|
| case class A(x: Int, y: String)
|
| trait SomeTrait[T]
|
| object SomeTrait:
| given [T]: SomeTrait[T] with {}
|
| def f1[T](using p: Mirror.ProductOf[T]): p.type = p
|
| def f2[T, R](f: T => R)(using SomeTrait[R]): R = ???
|
| def x = f2(_ => f1[A])
[[syntax trees at end of typer]] // rs$line$1
package <empty> {
final lazy module val rs$line$1: rs$line$1 = new rs$line$1()
final module class rs$line$1() extends Object() { this: rs$line$1.type =>
import scala.deriving.Mirror
case class A(x: Int, y: String) extends Object(), _root_.scala.Product,
_root_.scala.Serializable {
val x: Int
val y: String
def copy(x: Int, y: String): A = new A(x, y)
def copy$default$1: Int @uncheckedVariance = A.this.x
def copy$default$2: String @uncheckedVariance = A.this.y
def _1: Int = this.x
def _2: String = this.y
}
final lazy module val A: A = new A()
final module class A() extends AnyRef() { this: A.type =>
def apply(x: Int, y: String): A = new A(x, y)
def unapply(x$1: A): A = x$1
override def toString: String = "A"
}
trait SomeTrait[T >: Nothing <: Any]() extends Object {
T
}
final lazy module val SomeTrait: SomeTrait = new SomeTrait()
final module class SomeTrait() extends Object() { this: SomeTrait.type =>
given class given_SomeTrait_T[T >: Nothing <: Any]() extends Object(),
SomeTrait[given_SomeTrait_T.this.T] {
T
}
final given def given_SomeTrait_T[T >: Nothing <: Any]:
SomeTrait.given_SomeTrait_T[T] = new SomeTrait.given_SomeTrait_T[T]()
}
def f1[T >: Nothing <: Any](using p: scala.deriving.Mirror.ProductOf[T]):
p.type = p
def f2[T >: Nothing <: Any, R >: Nothing <: Any](f: T => R)(using
x$2: SomeTrait[R]): R = ???
def x: scala.deriving.Mirror.ProductOf[A] =
f2[Any, scala.deriving.Mirror.ProductOf[A]](
{
def $anonfun(_$1: Any): scala.deriving.Mirror.ProductOf[A] =
f1[A](
A.$asInstanceOf[
scala.deriving.Mirror.Product{
type MirroredMonoType = A; type MirroredType = A;
type MirroredLabel = ("A" : String);
type MirroredElemTypes = (Int, String);
type MirroredElemLabels = (("x" : String), ("y" : String))
}
]
)
closure($anonfun)
}
)(
SomeTrait.given_SomeTrait_T[
scala.deriving.Mirror.Product{
type MirroredType = A; type MirroredMonoType = A;
type MirroredElemTypes <: Tuple
}
]
)
}
}
// defined case class A
// defined trait SomeTrait
// defined object SomeTrait
def f1[T](using p: scala.deriving.Mirror.ProductOf[T]): p.type
def f2[T, R](f: T => R)(using x$2: SomeTrait[R]): R
def x: scala.deriving.Mirror.ProductOf[A]