Search code examples
arraysscalaintellij-ideaassertscalatest

assert in foreach causes too few argument lists for macro invocation


I'm using scala test to check if Array contains Arrays of given size:

result.map(_.length == 2).foreach(assert)

This causes compilation error:

Error:(34, 39) too few argument lists for macro invocation
    result.map(_.length == 2).foreach(assert)

although intellij does not indicate compilation error. How to test it?


Solution

  • This is just a bug in the compiler. You can reproduce it with a much simpler macro you define yourself:

    scala> import scala.language.experimental.macros
    import scala.language.experimental.macros
    
    scala> import scala.reflect.macros.blackbox.Context
    import scala.reflect.macros.blackbox.Context
    
    scala> object IncrementMacro { def inc(c: Context)(i: c.Expr[Int]) = i }
    defined object IncrementMacro
    
    scala> object Increment { def inc(i: Int): Int = macro IncrementMacro.inc }
    defined object Increment
    
    scala> List(1, 2, 3).map(Increment.inc)
    <console>:15: error: too few argument lists for macro invocation
           List(1, 2, 3).map(Increment.inc)
                                       ^
    
    scala> List(1, 2, 3).map(Increment.inc _)
    <console>:15: error: macros cannot be eta-expanded
       List(1, 2, 3).map(Increment.inc _)
                                   ^
    
    scala> List(1, 2, 3).map(Increment.inc(_))
    res1: List[Int] = List(1, 2, 3)
    

    This is on 2.12.8, but I feel like I remember first noticing this back in the 2.10 days. There might be an issue for it, or there might not be, but the moral of the story is that Scala's macros interact with other language features—like eta expansion in this case—in weird ways, and in my view you're best off just memorizing the workarounds, like assert(_) here.