scala/scala — pull request #4083 by retronym (2014-10-30 02:09:00+00:00)
Title: SI-8947 Avoid cross talk between tag materializers and reify

After a macro has been expanded, the expandee are expansion are
bidirectionally linked with tree attachments. Reify uses the back
reference to replace the expansion with the expandee in the reified
tree. It also has some special cases to replace calls to macros
defined in scala-compiler.jar with `Predef.implicitly[XxxTag[T]]`.
This logic lives in `Reshape`.

However, the expansion of a macro may be `EmptyTree`. This is the case
when a tag materializer macro fails. User defined macros could do the
also expand to `EmptyTree`. In the enclosed test case, the error
message that the tag materializer issued ("cannot materialize
class tag for unsplicable type") is not displayed as the typechecker
finds another means of making the surrounding expression typecheck.

However, the macro engine attaches a backreference to the materializer
macro on `EmpytyTree`!

Later, when `reify` reshapes a tree, every occurance of `EmptyTree`
will be replaced by a call to `implicitly`.

This commit expands the domain of `CannotHaveAttrs`, which is mixed
in to `EmptyTree`. It silently ignores all attempts to mutate
attachments.

Unlike similar code that discards mutations of its type and position,
I have refrained from issuing a developer warning in this case, as
to silence this I would need to go and add a special case at any
places adding attachments.

Review by @xeno-by @densh