Skip to content

-Xcheck-macros fails in pismute/classy-optics #18353

@WojciechMazur

Description

@WojciechMazur

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions