Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhelpful "Tree had an unexpected owner" error message #16363

Closed
kubukoz opened this issue Nov 17, 2022 · 5 comments · Fixed by #16733
Closed

Unhelpful "Tree had an unexpected owner" error message #16363

kubukoz opened this issue Nov 17, 2022 · 5 comments · Fixed by #16733
Assignees
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:enhancement

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Nov 17, 2022

Compiler version

3.2.1

Minimized code

//> using scala "3.2.1"
//> using option "-Ycheck:all"
//> using option "-Xcheck-macros"
import scala.annotation.experimental

import scala.quoted.*

object testmacros {
  inline def example = ${ exampleImpl }

  @experimental
  def exampleImpl(using Quotes): Expr[Any] = {
    import quotes.reflect._

    val methodType = MethodType(List("arg"))(_ => List(TypeRepr.of[String]), _ => TypeRepr.of[Unit])
    def method(
      owner: Symbol
    ) = Symbol.newMethod(
      owner,
      "test",
      methodType,
    )

    val clazz = Symbol.newClass(
      Symbol.spliceOwner,
      "$anon",
      List(TypeRepr.of[Object]),
      owner => method(owner) :: Nil,
      None,
    )

    ClassDef(
      clazz,
      Nil,
      List(
        DefDef(
          method(clazz),
          argss =>
            Some(
              Lambda(method(clazz), methodType, (ls, _) => '{ ??? }.asTerm)
            ),
        )
      ),
    ).asExpr
  }

}

//in another file

val f = testmacros.example

Output

...
[error] Expected: method test (demo$._$_$$anon.test)
[error] But was: method test (demo$._$_$$anon.test)
...
Full output
[error] ./main.scala:46:3: Exception occurred while executing macro expansion.
[error] java.lang.AssertionError: assertion failed: Tree had an unexpected owner for method $anonfun
[error] Expected: method test (demo$._$_$$anon.test)
[error] But was: method test (demo$._$_$$anon.test)
[error] 
[error] 
[error] The code of the definition of method $anonfun is
[error] def $anonfun(arg: java.lang.String): scala.Unit = scala.Predef.???
[error] 
[error] which was found in the code
[error] ((arg: java.lang.String) => scala.Predef.???)
[error] 
[error] which has the AST representation
[error] Block(List(DefDef("$anonfun", List(TermParamClause(List(ValDef("arg", Inferred(), None)))), Inferred(), Some(Inlined(Some(TypeIdent("macros$")), Nil, Ident("???"))))), Closure(Ident("$anonfun"), None))
[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`.
[error] 
[error]         at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error]         at scala.quoted.runtime.impl.QuotesImpl$$anon$9.traverse(QuotesImpl.scala:2949)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1657)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1657)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.fold$1(Trees.scala:1529)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.apply(Trees.scala:1531)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1562)
[error]         at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1658)
[error]         at scala.quoted.runtime.impl.QuotesImpl$$anon$9.traverse(QuotesImpl.scala:2956)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$.xCheckMacroOwners(QuotesImpl.scala:2957)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$.scala$quoted$runtime$impl$QuotesImpl$reflect$$$xCheckMacroedOwners(QuotesImpl.scala:2915)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$DefDef$.apply$$anonfun$3$$anonfun$1(QuotesImpl.scala:272)
[error]         at dotty.tools.dotc.ast.tpd$.DefDef(tpd.scala:289)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$DefDef$.apply$$anonfun$3(QuotesImpl.scala:273)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$.scala$quoted$runtime$impl$QuotesImpl$reflect$$$withDefaultPos(QuotesImpl.scala:2906)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$DefDef$.apply(QuotesImpl.scala:273)
[error]         at scala.quoted.runtime.impl.QuotesImpl$reflect$DefDef$.apply(QuotesImpl.scala:269)
[error]         at macros$.exampleImpl(macros.scala:182)
[error] 
[error]   macros.example
[error]   ^^^^^^^^^^^^^^
Error compiling project (Scala 3.2.1, JVM)

Expectation

Something that distinguishes the actual owner from the expected one.

@kubukoz kubukoz added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 17, 2022
@kubukoz
Copy link
Contributor Author

kubukoz commented Nov 17, 2022

Sometimes I'm even seeing this:

Error: Unexpected error when compiling project_15da074c1d: 'assertion failed: bad owner; method $anonfun has owner method hello, expected was method hello

@jchyb jchyb added area:metaprogramming:reflection Issues related to the quotes reflection API and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 17, 2022
@Kordyjan Kordyjan added this to the Future versions milestone Dec 12, 2022
@nicolasstucki
Copy link
Contributor

There is a bug in the maco implementation. The code instantiates 3 times a new symbol for the same methods (method(owner), method(clazz), and method(clazz)). As these 3 new symbols have the same name, the error message shows the same name.

To fix the macro implementation one needs to the method symbol once when creating the class symbol. Then that symbol can be recovered using methodMember.

def method(owner: Symbol) = Symbol.newMethod(..., "test", ...)
val clazz = Symbol.newClass(...)
val testSym = clazz.methodMember("test").head
ClassDef(
  clazz,
  Nil,
  List(
    DefDef(
      testSym,
      argss =>
        Some(
          Lambda(testSym, methodType, (ls, _) => {
            '{ ??? }.asTerm
          })
        )
    )
  ),
)

@kubukoz
Copy link
Contributor Author

kubukoz commented Jan 20, 2023

@nicolasstucki I'm aware the macro may be buggy, the problem I was reporting is just the... reporting :)

@nicolasstucki
Copy link
Contributor

The description of the error was meant as an in depth analysis of the issue that can be compared to the new hint that will be reported when such an error occurs. Anyone else having a look at this issue would not necessarily have this insight.

@kubukoz
Copy link
Contributor Author

kubukoz commented Jan 23, 2023

I see, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants