-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Types do not expand hygienically in macros that create modules #28072
Comments
I'm unsure about hygiene being broken here, if it leaked imports from the calling context into a generated module, I'd consider that to be really broken. This might help you get what you need done: http://is.gd/Q9tXFx |
As far as I understand it, Rust macros are not hygienic with respect to types at all. Since it would be a breaking change to fix this, it would need an RFC. Propose closing this issue or moving to RFC issues. |
Hi. I've just run across the same issue, and it took me a while to understand. My use is slightly different, although an interesting similarity is that I first wanted to generate multiple functions in a macro expansion using gensym (or ident concatenation, or name mangling), and when I couldn't determine how to do that, I decided to introduce a module within the expansion. Here's the failing minimized example:
The result is:
Here is a "fix" which seems counter-intuitive without realizing that items and/or paths aren't hygienic:
Here's a second fix which is similarly counter-intuitive (for me at least):
Note that this macro defines items which should "leak out" so I think I want hygiene in one case, but not the other. Perhaps I want to eat my cake and have it, too. (See #28335 for an example of someone expecting some kind of "exported item definition hygiene".) One final note to motivate my use case, I have something like:
As I said above, another approach is to remove the intermediate module and then use name mangling to ensure all of the test functions have unique names. I haven't tried that yet, but from #12249 I'm lead to believe that approach won't work. (I find this hierarchical mod approach to be "cleaner" anyway.) Phew, ok... so for the purpose of this ticket, given the current accepted design of "partial hygiene" for macros, maybe the best improvement is to have some of these examples in the chapter on macros in the book. |
Current error
|
cc @jseyfried just seeing if this is interesting to you, or you know how to fix it. |
This is a known limitation of This is fixed in declarative macros 2.0 (it will "just work"), see this test case. |
As a known limitation of macro_rules that we don't plan on fixing, I'm going to close this. |
If I take a macro parameter of type
ty
, and in the macro I create a module and expandty
within that module, the name of the type is parsed within the module, not within the context of the macro, which subtly breaks hygiene. For instance (playpen):The first call works fine because
str
andOption
are in the prelude, but the second call tof!
producesbecause there's no
std::io::Read
from the point of view ofmod bar {...}
, there's just::std::io::Read
orsuper::std::io::Read
or whatever.There's not even a workaround for this, because the type parameter isn't a path. If I try
$v: super::$t
, I getz: super::&std::io::Read
, which isn't really helpful.To be fair, my use case here involves using modules as a workaround for the lack of gensym. I've filed rust-lang/rfcs#1266 requesting the addition of gensym; at that point, my use case would no longer involve expanding types within a module. But I think this would still be a valid bug.
The text was updated successfully, but these errors were encountered: