Closed
Description
Failure found in OpenCB for pismute/classy-optics - build logs
I'm not sure, but it looks like a false-positive. Can we confirm that?
Compiler version
Since 3.3.0
Minimized code
// macros.scala
import scala.compiletime.*
import scala.deriving.*
import scala.quoted.*
trait Getter[S, A]:
def view: S => A
trait Lens[S, A] extends Getter[S, A]:
def set: S => A => S
object Lens {
inline def apply[S, A](_view: S => A)(_set: S => A => S): Lens[S, A] =
new Lens[S, A]:
def view: S => A = _view
def set: S => A => S = _set
inline given derived[T <: Product, A]: Lens[T, A] = ${
ProductMacros.genLens[T, A]
}
}
object ProductMacros {
private def indexOf[T: Type, A: Type](using Quotes): Int =
indexOf0[T, A](0)
private def indexOf0[T: Type, A: Type](acc: Int)(using Quotes): Int =
Type.of[T] match
case '[EmptyTuple] => -1
case '[A *: tpes] => acc
case '[tpe *: tpes] => indexOf0[tpes, A](acc + 1)
def genLens[T <: Product: Type, A: Type](using
q: Quotes
): Expr[Lens[T, A]] = {
import quotes.reflect.*
Expr
.summon[Mirror.ProductOf[T]]
.map {
case '{
$m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }
} =>
val i = indexOf[elementTypes, A]
if i < 0 then
report.errorAndAbort(s"has no the field of ${Type.show[A]}")
else
val ii: Expr[Int] = Expr(i)
val view: Expr[T => A] = '{ t =>
t.productElement($ii).asInstanceOf[A]
}
val set: Expr[T => A => T] = '{ t => a =>
val arr = Tuple.fromProduct(t).toArray
arr($ii) = a.asInstanceOf[Object]
// Check-macros fails here probably
$m.fromTuple(Tuple.fromArray(arr).asInstanceOf[elementTypes])
}
'{ Lens[T, A]($view)($set) }
}
.getOrElse(
report.errorAndAbort(s"${Type.show[T]} is not a product type")
)
}
}
// main.scala
//> using options -Xcheck-macros
@main def Test = {
type TupleConfig = (Int, String)
val tConfig = (1, "string")
val fails = summon[Lens[TupleConfig, Int]].view(tConfig)
}
Output
scala-cli run --server=false macros.scala main.scala -S 3.3.0
Warning: setting /Users/wmazur/projects/sandbox as the project root directory for this run.
-- Error: /Users/wmazur/projects/sandbox/main.scala:8:44 -----------------------
8 | val fails = summon[Lens[TupleConfig, Int]].view(tConfig)
| ^
|Malformed tree was found while expanding macro with -Xcheck-macros.
| |The tree does not conform to the compiler's tree invariants.
| |
| |Macro was:
| |scala.quoted.runtime.Expr.splice[Lens[scala.Tuple2[scala.Int, scala.Predef.String], scala.Int]](((evidence$1: scala.quoted.Quotes) ?=> ProductMacros.genLens[scala.Tuple2[scala.Int, scala.Predef.String], scala.Int](scala.quoted.Type.of[scala.Tuple2[scala.Int, scala.Predef.String]](evidence$1), scala.quoted.Type.of[scala.Int](evidence$1), evidence$1)))
| |
| |The macro returned:
| |Lens.apply[scala.Tuple2[scala.Int, scala.Predef.String], scala.Int](((t: scala.Tuple2[scala.Int, scala.Predef.String]) => t.productElement(0).asInstanceOf[scala.Int]))(((`t₂`: scala.Tuple2[scala.Int, scala.Predef.String]) => ((a: scala.Int) => {
| val arr: scala.Array[java.lang.Object] = scala.Tuple.fromProduct(`t₂`).toArray
| arr.update(0, a.asInstanceOf[java.lang.Object])
| scala.deriving.Mirror.fromTuple[scala.Tuple2[scala.Int, scala.Predef.String]](new scala.runtime.TupleMirror(2).$asInstanceOf$[scala.deriving.Mirror.Product {
| type MirroredMonoType >: scala.Tuple2[scala.Int, scala.Predef.String] <: scala.Tuple2[scala.Int, scala.Predef.String]
| type MirroredType >: scala.Tuple2[scala.Int, scala.Predef.String] <: scala.Tuple2[scala.Int, scala.Predef.String]
| type MirroredLabel >: "Tuple2" <: "Tuple2"
| type MirroredElemTypes >: scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.Tuple$package.EmptyTuple]] <: scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.Tuple$package.EmptyTuple]]
| type MirroredElemLabels >: scala.*:["_1", scala.*:["_2", scala.Tuple$package.EmptyTuple]] <: scala.*:["_1", scala.*:["_2", scala.Tuple$package.EmptyTuple]]
| }])(scala.Tuple.fromArray[java.lang.Object](arr).asInstanceOf[scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.Tuple$package.EmptyTuple]]])
|})))
| |
| |Error:
| |assertion failed: position not set for
| scala.deriving.Mirror.Product{
| type MirroredMonoType = (Int, String); type MirroredType = (Int, String);
| type MirroredLabel = ("Tuple2" : String);
| type MirroredElemTypes = (Int, String);
| type MirroredElemLabels = (("_1" : String), ("_2" : String))
| }
| # -1 of class dotty.tools.dotc.ast.Trees$TypeTree in /Users/wmazur/projects/sandbox/main.scala
| |
| |
|----------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|This location contains code that was inlined from macros.scala:17
17 | inline given derived[T <: Product, A]: Lens[T, A] = ${
| ^
18 | ProductMacros.genLens[T, A]
19 | }
----------------------------------------------------------------------------
1 error found
Expectation
Is it a false-positive? It does not look like one