Symbol.tree usage is considered as an anti-pattern, because the tree is not guaranteed to exist.
Right now the only use case, that cannot be resolved without trees, is the annotation of base classes, eg. class X extends Y @MyAnnot.
This change was mostly motivated by the bug in the compiler I was not able to reproduce and minimise yet - under some conditions case class parameters can be generated before inlining (macros expansion) finishes. This leads to creation of param accessors that are not correctly handled in quotes. The call to CollectAnnotations.fromDeclarations with a parameter accessor would not be correctly handled. When execution Symbol.tree compiler would see that symbol has no Method flag so it assumes it as a ValDef, however, actually the tree of the parameter accessor is a DefDef which leads to MatchError when interpreting macros. Stack trace from this kind of errors can be found below
```scala
[error] 43 | val x = summon[sttp.tapir.Schema[GroupsResponse]]
[error] | ^
[error] | Exception occurred while executing macro expansion.
[error] | scala.MatchError: DefDef(groups,List(List()),TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class immutable)),class List)],EmptyTree) (of class dotty.tools.dotc.ast.Trees$DefDef)
[error] | at dotty.tools.dotc.quoted.reflect.FromSymbol$.valDefFromSym(FromSymbol.scala:50)
[error] | at dotty.tools.dotc.quoted.reflect.FromSymbol$.definitionFromSym(FromSymbol.scala:22)
[error] | at scala.quoted.runtime.impl.QuotesImpl$reflect$SymbolMethods$.tree(QuotesImpl.scala:2607)
[error] | at scala.quoted.runtime.impl.QuotesImpl$reflect$SymbolMethods$.tree(QuotesImpl.scala:2607)
[error] | at magnolia1.Macro$CollectAnnotations$$anon$4.applyOrElse(macro.scala:251)
[error] | at scala.collection.immutable.List.collect(List.scala:267)
[error] | at magnolia1.Macro$CollectAnnotations.magnolia1$Macro$CollectAnnotations$$fromDeclarations(macro.scala:254)
[error] | at magnolia1.Macro$CollectAnnotations.paramAnns(macro.scala:220)
[error] | at magnolia1.Macro$.paramAnns(macro.scala:43)
```
Symbol.tree
usage is considered as an anti-pattern, because the tree is not guaranteed to exist.Right now the only use case, that cannot be resolved without trees, is the annotation of base classes, eg.
class X extends Y @MyAnnot
.This change was mostly motivated by the bug in the compiler I was not able to reproduce and minimise yet - under some conditions case class parameters can be generated before inlining (macros expansion) finishes. This leads to creation of param accessors that are not correctly handled in quotes. The call to
CollectAnnotations.fromDeclarations
with a parameter accessor would not be correctly handled. When executionSymbol.tree
compiler would see that symbol has noMethod
flag so it assumes it as aValDef
, however, actually the tree of the parameter accessor is aDefDef
which leads to MatchError when interpreting macros. Stack trace from this kind of errors can be found below