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

Unexpected New (...) reached GenBCode #16357

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

Unexpected New (...) reached GenBCode #16357

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

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Nov 17, 2022

Compiler version

3.2.1

Minimized code

macros.scala

//> using scala "3.2.1"
import scala.quoted._
import scala.annotation.experimental

object macros {

  trait Suspend[A[_[_]]] {
    def sus[F[_]](fa: F[A[F]]): A[F]
  }

  inline def mkSuspend[Alg[_[_]]]: Suspend[Alg] = ${ mkSuspendImpl[Alg] }

  @experimental
  def mkSuspendImpl[Alg[_[_]]: Type](using Quotes): Expr[Suspend[Alg]] = {
    import quotes.reflect._
    def instance[F[_]: Type](fExpr: Expr[F[Alg[F]]]): Expr[Alg[F]] = {
      val cl = Symbol.newClass(
        Symbol.spliceOwner,
        "$anon",
        parents = List(
          TypeRepr.of[Object],
          TypeRepr.of[Alg].appliedTo(TypeRepr.of[F]),
        ),
        decls = _ => Nil,
        selfType = None,
      )

      val tree = New(
        TypeTree.of[Alg]
      )

      Block(
        List(
          ClassDef(cl, Nil, Nil)
        ),
        New(
          TypeTree.ref(cl)
        ),
      ).asExprOf[Alg[F]]
    }

    '{
      new Suspend[Alg] {
        def sus[F[_]](fa: F[Alg[F]]): Alg[F] = ${ instance('fa) }
      }
    }
  }

}

main.scala

//> using scala "3.2.1"
import macros.Suspend

object demo extends App {

  trait MyAlg[F[_]] {
    def hello(s: String): F[Int] = ???
  }

  macros.mkSuspend[MyAlg]
}

Output (click arrow to expand)

Error: Unexpected New(... with ... {...}/TypeTree[TypeRef(NoPrefix,class demo$$anon$2)]) reached GenBCode.
  Call was genLoad(New(TypeTree[TypeRef(NoPrefix,class demo$$anon$2)]),Ldemo$MyAlg;)
Error compiling project (Scala 3.2.1, JVM)
Error: Unexpected error when compiling project_f0e8bc45bf: 'Unexpected New(... with ... {...}/TypeTree[TypeRef(NoPrefix,class demo$$anon$2)]) reached GenBCode.
  Call was genLoad(New(TypeTree[TypeRef(NoPrefix,class demo$$anon$2)]),Ldemo$MyAlg;)'
Compilation failed
@kubukoz kubukoz added itype:bug itype:crash 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

I think this one is related to the default implementation of hello...

@nicolasstucki nicolasstucki 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
@bishabosha
Copy link
Member

bishabosha commented Nov 17, 2022

The problem is (I tested) that you should be wrapping new in a call to the constructor,

Apply(
  Select(
    New(TypeTree.ref(cl)), cl.primaryConstructor
  ),
  Nil
)

since this is always needed, perhaps we should deprecate the old New.apply and only have a factory that has all the required pieces

@kubukoz
Copy link
Contributor Author

kubukoz commented Nov 17, 2022

perhaps :) I know I'm very likely doing something wrong but it seemed like a message I shouldn't be seeing!

@Kordyjan Kordyjan added this to the Future versions milestone Dec 12, 2022
@nicolasstucki
Copy link
Contributor

By compiling this code with -Ycheck:all we get the following error:

checking t/Test_2.scala after phase inlining
java.lang.AssertionError: assertion failed: `New` node must be wrapped in a `Select`:
  parent = new Object with demo.MyAlg[F] {...}:demo.MyAlg[F]
  child = new Object with demo.MyAlg[F] {...} while running Ycheck on t/Test_2.scala
exception occurred while compiling t/Test_2.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: `New` node must be wrapped in a `Select`:
  parent = new Object with demo.MyAlg[F] {...}:demo.MyAlg[F]
  child = new Object with demo.MyAlg[F] {...} while compiling t/Test_2.scala
java.lang.AssertionError: assertion failed: `New` node must be wrapped in a `Select`:
  parent = new Object with demo.MyAlg[F] {...}:demo.MyAlg[F]
  child = new Object with demo.MyAlg[F] {...}

@nicolasstucki
Copy link
Contributor

This is not something we could we could do in the New.apply. It is also something that might be out of scope for -Xcheck-macros.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jan 23, 2023
We mention that the constructor must be selected. This should be all the
information needed in case someone writes a buggy macro that does not
include the `Select` around the `New`.

Closed scala#16357
nicolasstucki added a commit that referenced this issue Feb 16, 2023
We mention that the constructor must be selected. This should be all the
information needed in case someone writes a buggy macro that does not
include the `Select` around the `New`.

Closed #16357
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:bug itype:crash
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants