Closed
Description
Compiler version
3.4.2
Minimized code
CI: https://github.com/typelevel/cats-tagless/actions/runs/9236004309/job/25411405213?pr=547
Here is my change:
body = {
case (method, tpe, body) if tpe =:= B =>
+ given Quotes = method.asQuotes
'{
@tailrec def step(x: A): B =
${ body.replace(a, '{ x }).asExprOf[Either[A, B]] } match
case Left(a) => step(a)
case Right(b) => b
step($a)
- }.asTerm.changeOwner(method)
+ }.asTerm
The test which fails to compile:
trait TestAlgebra[T] derives FlatMap:
def abstractEffect(a: String): T
def concreteEffect(a: String): T = abstractEffect(a + " concreteEffect")
def abstractOther(a: String): String
def concreteOther(a: String): String = a + " concreteOther"
def withoutParams: T
Output
[error] -- Error: /home/runner/work/cats-tagless/cats-tagless/tests/src/test/scala-3/cats/tagless/tests/autoFlatMapTests.scala:39:31
[error] 39 | trait TestAlgebra[T] derives FlatMap:
[error] | ^
[error] |Exception occurred while executing macro expansion.
[error] |java.lang.AssertionError: assertion failed: Tree had an unexpected owner for method step
[error] |Expected: method withoutParams (cats.tagless.tests.autoFlatMapTests$.TestAlgebra$._$_$$anon._$$anon$macro$3.withoutParams)
[error] |But was: method concreteEffect (cats.tagless.tests.autoFlatMapTests$.TestAlgebra$._$_$$anon._$$anon$macro$3.concreteEffect)
[error] |
[error] |The code of the definition of method step is
[error] |@scala.annotation.tailrec def step(x: A): B = f.apply(x).withoutParams match {
[error] | case scala.Left(a) =>
[error] | step(a)
[error] | case scala.Right(b) =>
[error] | (b: B)
[error] |}
[error] |
[error] |which was found in the code
[error] |{
[error] | @scala.annotation.tailrec def step(x: A): B = f.apply(x).withoutParams match {
[error] | case scala.Left(a) =>
[error] | step(a)
[error] | case scala.Right(b) =>
[error] | (b: B)
[error] | }
[error] | step(`a₂`)
[error] |}
[error] |
[error] |which has the AST representation
[error] |Inlined(Some(TypeIdent("MacroFlatMap$")), Nil, Block(List(DefDef("step", List(TermParamClause(List(ValDef("x", Inferred(), None)))), Inferred(), Some(Match(Inlined(None, Nil, Select(Inlined(Some(TypeIdent("MacroFlatMap$")), Nil, Apply(Select(Inlined(None, Nil, Ident("f")), "apply"), List(Inlined(None, Nil, Ident("x"))))), "withoutParams")), List(CaseDef(TypedOrTest(Unapply(TypeApply(Select(Ident("Left"), "unapply"), List(Inferred(), Inferred())), Nil, List(Bind("a", Wildcard()))), Inferred()), None, Block(Nil, Apply(Ident("step"), List(Ident("a"))))), CaseDef(TypedOrTest(Unapply(TypeApply(Select(Ident("Right"), "unapply"), List(Inferred(), Inferred())), Nil, List(Bind("b", Wildcard()))), Inferred()), None, Block(Nil, Typed(Ident("b"), Inferred())))))))), Apply(Ident("step"), List(Inlined(None, Nil, Ident("a"))))))
[error] |
[error] |
[error] |
[error] |Tip: The owner of a tree can be changed using method `Tree.changeOwner`.
[error] |Tip: The default owner of definitions created in quotes can be changed using method `Symbol.asQuotes`.
Expectation
I expect it to compile the same way it does if I use changeOwner
. It's even one of the tips:
Tip: The default owner of definitions created in quotes can be changed using method
Symbol.asQuotes