You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
traitFoo[F[_]]:deffoo(id: F[Int]):Unit// multiple times// macroMinimized2.derive creates an instance of Foo with the substituted type param, i.e.:// new Foo[Option] { def foo(id: Option[Int]): Unit = ... } // new Foo[Try] { def foo(id: Try[Int]): Unit = ... }// however more than a single call fails
macroMinimized2.derive[Foo, Option]
macroMinimized2.derive[Foo, Try]
Macro code (I tried to minimize it as much as I could, this code makes use of the #11685
importquoted.*importscala.annotation.experimentalobjectmacroMinimized2:inlinedefderive[Alg[_[_]], G[_]] =${ instanceK[Alg, G] }
// create instance of Alg[F] that has a method foo(i: F[Int]): Unit@experimental definstanceK[Alg[_[_]]:Type, G[_]:Type](usingQuotes):Expr[Alg[G]] =importquotes.reflect.*valname="$anon()"valparents=List(TypeTree.of[Object], TypeTree.of[Alg[G]])
// uncomment to make it work on the second run// val parents = List(TypeTree.of[Object], TypeTree.of[Alg[scala.util.Try]]) valmethod= definedMethodsInType[Alg].head
// this should be used, since it feels like there is a problem in change owner// method arg types are aligned with the first macro call defdecls(cls: Symbol):List[Symbol] =
method.tree.changeOwner(cls) matchcaseDefDef(name, clauses, typedTree, _) =>valtpeRepr=TypeRepr.of(using typedTree.tpe.asType)
val (nms, tpes) = clauses.map(_.params.collect { casev: ValDef=> (v.name, v.tpt.tpe) }.unzip).head
println("---------")
println(tpes)
println("---------")
// tpes is always the same across multiple derive callsvalmethodType=MethodType(nms)(_ => tpes, _ => tpeRepr)
Symbol.newMethod(
cls,
name,
methodType,
flags =Flags.EmptyFlags/*TODO: method.flags */,
privateWithin = method.privateWithin.fold(Symbol.noSymbol)(_.typeSymbol)
) ::Nilcase _ =>
report.errorAndAbort(s"Cannot detect type of method: ${method.name}")
// uncomment this one to make it work// def decls(cls: Symbol): List[Symbol] =// List(Symbol.newMethod(cls, "foo", MethodType(List("id"))(_ => List(TypeRepr.of[G[Int]]), _ => TypeRepr.of[Unit])))valcls=Symbol.newClass(Symbol.spliceOwner, name, parents = parents.map(_.tpe), decls, selfType =None)
valfooSym= cls.declaredMethod("foo").head
valfooDef=DefDef(fooSym, argss =>Some('{println(s"Calling foo")}.asTerm))
valclsDef=ClassDef(cls, parents, body =List(fooDef))
valnewCls=Typed(Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil), TypeTree.of[Alg[G]])
valres=Block(List(clsDef), newCls).asExprOf[Alg[G]]
println("---------")
println(res.show)
println("---------")
res
// function to get methods defined for the typedefdefinedMethodsInType[Alg[_[_]]:Type](usingQuotes):List[quotes.reflect.Symbol] =importquotes.reflect.*valcls=TypeRepr.of[Alg].typeSymbol
for {
member <- cls.methodMembers
// is abstract method, not implementedif member.flags.is(Flags.Deferred)
// TODO: is that public?// TODO? if member.privateWithinif!member.flags.is(Flags.Private)
if!member.flags.is(Flags.Protected)
if!member.flags.is(Flags.PrivateLocal)
if!member.isClassConstructor
if!member.flags.is(Flags.Synthetic)
} yield member
Output
if it's a single call per code base macro works as expected
If there is more than a single call (macroMinimized2.derive[Foo, Option], macroMinimized2.derive[Foo, Try], etc) all the followup calls generate traits with incorrect method signatures:
pomadchin
changed the title
Unexpected macro argument type substitution on the method owner change
Unexpected macro argument type substitution on the method owner change in the Symbol.newClass call
Aug 26, 2022
Compiler version
Minimized code
Note: mb I'm writing a wrong code :/
Usage:
Macro code (I tried to minimize it as much as I could, this code makes use of the #11685
Output
macroMinimized2.derive[Foo, Option]
,macroMinimized2.derive[Foo, Try]
, etc) all the followup calls generate traits with incorrect method signatures:Expectation
Should not fail and generate the correct trait body when called multiple times.
The text was updated successfully, but these errors were encountered: