-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
My code fails to build with „unexpected end of macro invocation“ since nightly 2017-07-02 #43057
Comments
Not sure if it is relevant, but there is already a |
Minimized, side effect of #42938: macro_rules! column { (foo) => { panic!() } }
fn main() {
column!(foo);
} |
Or alternatively with a singularly unhelpful error message ( macro_rules! column { (foo) => {} }
fn main() { panic!(); }
|
Same thing happens with a |
|
So I guess there are three "issues" here:
Edit: Tagging as |
@kennytm: Sadly, that doesn't work: |
An empty implementation, however, does exist at the std/core root (presumably for documentation reasons). I don't know much about the compiler internals, but would it be possible to "fill in" that implementation, instead of creating a "new" builtin macro? |
I see, so there was the Still, I think the error message could be a bit more helpful. |
@vorner Your macro definition shouldn't interfere with the standard library, but yes, that's what's currently happening. I realized that my proposed "filling in" solution also wouldn't work with |
Since There should be a lint which warns about shadowing any of the built-in macros. (Alternatively, would it be possible to rewrite |
Needs to be prioritized. There's probably something we can do better here. |
cc @jseyfried -- this is due to an issue with macros 1.0 hygiene, maybe macros 2.0 can be made to prevent situations like this? |
@est31 Yeah, macros 2.0 already prevents situations like this. // crate A
pub macro n() { println!("Hello world!") }
pub macro m() { n!() }
// crate B
extern crate A;
use A::m;
macro n() {}
macro println() {}
//^ These don't interfere with the expansion of `m!()` below.
fn main() {
m!(); // prints "Hello world!"
} |
One way to fix this issue would be to migrate the That being said, it might be worth assessing migrating with a warning cycle or some other partial mitigation. cc @nrc |
@est31 Caveat: while macros 2.0 prevents this situation, it doesn't help when using macros 1.0 from It might be possible to special-case certain situation so that macros 2.0 do not "override" unhygienic macros 1.0 dependencies. For example, we could say:
However, this would add complexity and probably has other downsides (e.g. breaking invariants preserved by macro expansion). |
Out of curiosity, could we define unstable macros in the compiler like Othrewise, is there perhaps another sort of small patch we could apply to avoid the regression here? Beta's going out in just over a month! |
I see the nominated label, would be great to have a team talk about this. There needs to be a decision on whether this change is expected breakage or a bug? Or, to formulate the question more generally: is it forbidden for any macro of the standard library to change which macros it calls, or is such change allowed? Also similar question: is it allowed for a macro in the standard library to become a wrapper of another macro? If it becomes, it adds 1 to the depth and could cause to code (which uses the recursion depth up to the limit, but doesn't attempt to surpass the limit) to be rejected that was previously accepted. RFC 1105 has no section on macros... |
I think it should be OK to move away from unhygienic "dependency overrides" (e.g. with @alexcrichton's idea) if it doesn't cause breakage in practice.
I doubt this would be an issue in practice, but if it is we could always add a small offset to the global recursion limit when computing the recursion limit for macros (macro expansion is stackless, so this is OK). |
@jseyfried just to confirm, but the "workaround" here would be to add a |
@alexcrichton Right. We could instead define a declarative macros 2.0 |
Why is adding |
|
@est31 out of curiosity, would you be willing to help implement the workaround here? |
@alexcrichton depends on whether such a workaround would actually be helping people. @vorner would it help you? @alexcrichton are there any results of a crater run on the beta available? |
I already worked around the problem by renaming the macro (it is a private one to generate some code, so I don't care about its name). It was just the surprise the code broke. But if you ask if it would have helped me if it was there to begin with, then I think yes ‒ I didn't have a clue what was wrong and only reporting the issue helped shed some light. |
Ah unfortunately we don't have a crater run yet to see the impact of this. |
Discussed in compiler meeting. Awaiting some sort of crater run before assessing priority. |
Libss concluded the same! |
I've looked at the root regressions from a crater run between stable and beta (link), and couldn't find any regression introduced by this issue. They would have shown up there because this PR made it into beta but is not in stable yet. |
@arielb1 oh, right. Missed it :) So dunno then... PR to https://github.com/stefanoc/magnet ? Or should this be fixed in the compiler because it affected diesel? |
I think this should be fixed in the standard library by making |
@arielb1 above @jseyfried [mentioned]:
In that sense, would you be opposed to a compiler-defined It does indeed seem like we should implement this! |
I don't care what fix happens, only that it does. |
@est31 out of curiosity, would you be willing to help implement this? |
@alexcrichton sure! IMO its not really needed, but you seem to insist... |
Avoid calling the column!() macro in panic Closes #43057 This "fix" adds a new macro called `__rust_unstable_column` and to use it instead of the `column` macro inside panic. The new macro can be shadowed as well as `column` can, but its very likely that there is no code that does this in practice. There is no real way to make "unstable" macros that are usable by stable macros, so we do the next best thing and prefix the macro with `__rust_unstable` to make sure people recognize it is unstable. r? @alexcrichton
Hello
I have this code: https://gitlab.labs.nic.cz/turris/pakon-aggregator (unfortunately, I don't have a minimal code example yet). It fails with
rustc 1.20.0-nightly (067971139 2017-07-02)
(for some reason this is the version I get if I runrustup default nightly-2017-07-03
, it seems to be one day off) and newer, but passes with older versions of nighly as well as stable and beta.The error I get is:
This is actually my own macro, so the „originates in a macro outside of the current crate“ part is wrong. Also, renaming the macro makes it compile again. This leads me to think something (the compiler) brought in a colliding macro with the same name.
Is my theory about the colliding macro true? Can this killing of my poor innocent macro be prevented somehow? Should local macros have precedence? Or, at least, should I get a better error message, like complaining when I define the macro, not when I use it? This makes me think that if I had the bad luck of having a same-name macro with the same invocation syntax, it would silently expand the wrong one.
Exact version
The text was updated successfully, but these errors were encountered: