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

Internal "Wrong number of arguments" error when reading a Scala 2 annotation in a macro #22200

Open
jchyb opened this issue Dec 12, 2024 · 2 comments

Comments

@jchyb
Copy link
Contributor

jchyb commented Dec 12, 2024

Compiler version

Scala 2: 2.13.14
Scala 3: 3.3.4

Minimized code

Compiled with Scala 2:

class annot(str: List[String]) extends scala.annotation.StaticAnnotation
@annot(List("test", "test2")) class TestClass

Compiled with Scala 3, with results of the above on the classpath:
Macro.scala:

import scala.quoted._

object Macro {
  inline def call: Unit = ${ callImpl }
  def callImpl(using Quotes): Expr[Unit] = {
    import quotes.reflect._
    val sym = TypeRepr.of[TestClass].typeSymbol
    val annot = TypeRepr.of[annot].typeSymbol

    println(sym.getAnnotation(annot)) // causes error

    '{()}
  }
}

Main.scala:

@main def main() = Macro.call

Output

[error] -- Error: /Users/jchyb/workspace/mix-macros-scala-2-and-3/app3/src/main/scala/Main.scala:4:25 
[error] 4 |@main def main() = Macro.call
[error]   |                   ^^^^^^^^^^
[error]   |wrong number of arguments at <no phase> for (elems: String*): CC[String]: (elems: String*): CC[String], expected: 1, found: 2
Some(Apply(Select(New(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class annot)]),<init>),List(Apply(TypeApply(Select(Select(Select(Ident(scala),package),List),apply),List(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String)])),List(Literal(Constant(test)), Literal(Constant(test2)))))))

Expectation

No error.
An interesting observation: this bug does not happen when the annotation argument is not a list. Also we do not return from the macro instantly as we see the error, instead still printing out the tree and ending compilation when we leave the macro.

@jchyb jchyb added itype:bug compat:scala2 stat:needs triage Every issue needs to have an "area" and "itype" label area:metaprogramming:reflection Issues related to the quotes reflection API labels Dec 12, 2024
@jchyb jchyb self-assigned this Dec 12, 2024
@Gedochao Gedochao removed the stat:needs triage Every issue needs to have an "area" and "itype" label label Dec 12, 2024
@jchyb
Copy link
Contributor Author

jchyb commented Dec 12, 2024

The issue seems to lie with how we read the Apply trees in Scala2Unpickler (

Apply(fun, args) // note: can't deal with overloaded syms yet
). Before constructing the Apply List.apply gets typed as:

MethodType(
  List(elems),
  List(AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class <repeated>),List(TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String)))), 
  AppliedType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class collection)),trait IterableFactory)),type CC),List(TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String))))

and the arguments are read as:

List(Literal(Constant(test)), Literal(Constant(test2))

The issue lies with the varargs application to the List, as shown by the presence of scala.<repeated>. In Tasty we also have a Repeated token to tell us about varargs application. Manually checking for scala.<repeated> and wrapping the arguments with SeqLiteral helps here, but we soon run into another issue, shown by another error:

[error] -- [E007] Type Mismatch Error: /Users/jchyb/workspace/mix-macros-scala-2-and-3/app3/src/main/scala/Main.scala:4:25 
[error] 4 |@main def main() = Macro.call
[error]   |                   ^^^^^^^^^^
[error]   |                   Found:    CC[String]
[error]   |                   Required: List[String]
[error]   |
[error]   | longer explanation available when compiling with `-explain`

This one, I do not know how to approach.

@jchyb
Copy link
Contributor Author

jchyb commented Dec 12, 2024

Also, if we skip the List/Seq in the annotation and use varargs directly, it works

@jchyb jchyb removed their assignment Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants