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

Implicit whitebox macros (fundep materialization) swallow fatal errors #10552

Closed
joroKr21 opened this issue Oct 15, 2017 · 3 comments
Closed

Comments

@joroKr21
Copy link
Member

Since whitebox macro expansion is forced here, when the typer is an implicit search all exceptions thrown by the macro implementation are caught and swallowed as "implicit not found", including fatal errors like out of memory or stack overflow.

This doesn't happen with blackbox macros, because they are delayed and expanded after the implicit search.

Example:

object Macros {
  trait BlackBox[A]
  object BlackBox {
    implicit def materialize[A]: BlackBox[A] = macro materializeImpl[A]
    def materializeImpl[A](c: blackbox.Context): c.Tree = throw new OutOfMemoryError
  }

  trait WhiteBox[A]
  object WhiteBox {
    implicit def materialize[A]: WhiteBox[A] = macro materializeImpl[A]
    def materializeImpl[A](c: whitebox.Context): c.Tree = throw new OutOfMemoryError
  }
}

object Test {
  import Macros._
  implicitly[BlackBox[Int]] // out of memory
  implicitly[WhiteBox[Int]] // implicit not found
}

This can cause spurious missing implicit errors (see. milessabin/shapeless#776).

@olafurpg
Copy link

olafurpg commented Dec 8, 2017

Thanks for the minimal reproduction @joroKr21

The behavior for both blackbox and whitebox macros is unexpected for me.

java.lang.reflect.InvocationTargetException
so-test.scala:3: error: exception during macro expansion:
java.lang.OutOfMemoryError
	at Macros$BlackBox$.materializeImpl(so.scala:8)

  implicitly[BlackBox[Int]] // out of memory
            ^
java.lang.reflect.InvocationTargetException
so-test.scala:4: error: could not find implicit value for parameter e: Macros.WhiteBox[Int]
  implicitly[WhiteBox[Int]] // implicit not found
            ^
two errors found

The behavior for whitebox macros is arguably worse, but I would expect fatal errors to propagate instead of get reported. Is there a good reason to not use NonFatal where Throwable is caught?

I opened scala/scala#6220 changing the error handling to propagate fatal exceptions.

@joroKr21
Copy link
Member Author

joroKr21 commented Dec 8, 2017

I have no idea how error handling works in the compiler. Does rethrowing the fatal error crash it? Does the stack trace then include the source location where the macro was called? In general it's a good idea to guard against poorly written macros, but "implicit not found" is just plain the incorrect error.

@SethTisue
Copy link
Member

PR: scala/scala#6344

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

5 participants