-
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
In macros, $($x:expr),*
fragments can be used to bypass future-proofing restrictions
#25658
Comments
cc @bluss |
Note that macro_rules! foo {
( $x:expr ... ) => { 1 }
}
fn main() { } is (correctly) prohibited. |
It's not just the type |
Nooooooo! You're going to break my macro article again, aren't you? :( (Note: I realise the following is not a good reason to not fix this problem.) The problem for me, personally, is that the following doesn't work: macro_rules! foo {
( $($x:expr),* , ... ) => { 1 }
}
fn main() {
// error: local ambiguity: multiple parsing options: built-in NTs expr ('x') or 1 other options.
let _ = foo!(1, 2, 3, ...);
// ^~~
} It would be nice if MBE preferred literal matches to captures. |
@DanielKeep Shouldn't that be macro_rules! foo {
(...) => {{
()
}};
($e:expr, $($tok:tt)+) => {{
($e, foo!($($tok)+))
}}
}
fn main() {
let tpl = foo!(1,2,3,4,...);
println!("{:?}", tpl);
} |
triage: I-nominated |
cc @pnkfelix |
So my feeling is that we should probably fix this, but it'd be good to evaluate the impact. It might be a good place to use a more elongated "breaking change procedure", or at least actively reach out to help people rewrite. |
Is this a bug where we need to consider "FOLLOW"? I thought I saw a PR/RFC that added detailed FOLLOW checking but I could be wrong. |
Would it be a middle ground to always warn on this, and then "just let it break" if expression syntax ever changes so that it does -- the macro would suddenly match differently. @DanielKeep and I found out a parsing strategy with |
triage: P-high Assigning high priority as, if we are going to fix this, we need to do it soon. If we're just going to warn, urgency is somewhat lower. I'm not yet sure of best overall strategy here. A crater report might be helpful in making the determination. |
I just found this gem, which is probably related to this issue: macro_rules! e {
($($e:expr)*) => ($($e)*);
}
fn main() {
e!(() "");
e!("" 4);
} The first invocation is accepted, the second leads to a type error:
(this doesn't depend on the return type of the function, it gives the same error when it returns something else than |
@jonas-schievink Hmm, I don't think that is related to this ticket... it is a strange inconsistency though. (I also think that all of those update: spawned off into #29799 |
Fixing the bug here without adding a warning seems simple: just let the checking for delimited-sequences fall, on success, into the code for non-delimited ones. (Wish I had looked at this for a day back in May...) I'm going to double-check that this passes (And in parallel with the crater run, I'll see how hard it would be to instead emit a (hard) warning... it may require more invasive surgery on the code in question.) |
I did a crater run for my simple (error-generating, not a warning cycle) fix for this.
While that was running, I hacked together a warning-cycle version of the change. (As predicted, it is more invasive, but also lays out further changes we can make to simplify this code if we go down the route I'm suggesting.) Once that builds successfully, I'll put it through a crater run as well, since I am not thrilled with 17 root regressions. |
@pnkfelix Ha! I'm responsible for four of those 17. Oh... this breaks trailing commas. That's really going to suck. |
Some of the errors from my crater run above seem like they may be due to our limited approach to having sequences followed by other sequences, which the code in some ways acts like has always been disallowed, but clearly we let it through for delimited sequences. I'm having difficulty interpreting the intent of RFC 550 here; I'll report more later after I've finished writing up an analysis of the results. |
@DanielKeep my initial guess is that my naive approach, while accepted by our internal |
I looked through all of the crater reported root regressions; the analysis writeup is here: https://gist.github.com/pnkfelix/be4b76cd8891230eb065 Of the 17 root regressions
For the "fundamental consequences", I mean the cases:
For "seq rep followed by seq rep", the code as written disallows But there's no fundamental reason that we cannot allow sequences followed by sequences. The reason why I think the current code tried to disallow them is to allow for a simple computation to find the "first" token that immediately follows any given sequence. (This is supported by comments in the code like "This doesn't actually compute the FIRST of the rest of the matcher yet, it only considers single tokens and simple NTs" (emphasis added).) |
My feeling here is that we should not rush to issue a breaking change IF we think there are simple ways to make the code more intelligent that would mitigate the effect of that change. In other words, if being smart about follow sets means we can both fix this bug AND support more macros, seems like we should do that. I'm not entirely clear if that is the case from your write-up (perhaps because I need to read it more carefully :) |
OK, so, this "trailing comma" pattern jumps out: |
@nikomatsakis yes I think that is right. I'm working on a revised version of the code that does a more precise computation of FIRST for the suffix after the cursor (and also tracks LAST for the token sequence prefix before the cursor, since you can have things like |
results of new crater run with a smarter (still in development) changeset: https://gist.github.com/pnkfelix/b351caa523d45f9aa86b I interpret this as a signal that I need to add
(Some of the regressing crates fall into more than one of the buckets above...) |
I don't understand disallowing |
Also, as a matter of policy, could/should crate authors be notified (assuming an email was provided) when their crate is caught regressing in a crater run related to an accepted breaking change? |
Almost certainly an oversight. Good point! |
On Wed, Nov 18, 2015 at 08:53:16AM -0800, Felix S Klock II wrote:
I still feel uncomfortable with this. I would rather than a nt for Perhaps though there is a compromise:
|
yeah, I have come around to seeing this as a better solution (see e.g. rust-lang/rfcs#1384 (comment) ) Just need to think of a good name for the specifier. :) |
now that amendment rust-lang/rfcs#1384 has been accepted, this issue should be fixed once the implementation has landed (i.e. #30450 is resolved). |
I should point out that crater is still massively deficient as it still does not test Windows targets at all, and did not notice that
|
Cc @brson re above crater note (I strongly doubt we would revert the RFC amendment or associated PR. you might find support for adding |
@retep998 Thanks for bringing this up. I assure you the deficiencies of crater are well-known, and it'd be really great if we could improve it -- though even if we got 100% coverage for crates.io, obviously it still wouldn't be 100% coverage of all the Rust code out there. In any case though, this is part of why we try our best to do warning cycles for bug fixes that are likely to have major impact, so that we can find out about other problems before changes become permanent (and also of course to give people time to transition). As @pnkfelix said, I don't think it makes sense to rollback this bug fix completely or anything like that. It might alleviate some short term pain but it'd be guaranteed to cause more breakage in the long-term, since basically every change to Rust's grammar would be a potential breaking change to some macro. However, also as @pnkfelix said, adding |
This issue (as described in the description) is fixed by #30694 |
Remove the old FOLLOW checking (aka `check_matcher_old`). It was supposed to be removed at the next release cycle but is still in the tree since like 6 months. Potential breaking change, since some cases (such as #25658) will change from a warning to an error. But the warning stating that it will be a hard error in the next release has been there for 6 months now. I think it's safe to break this code. ^_^
This should not be accepted, but it is:
cc @pnkfelix @cmr
The text was updated successfully, but these errors were encountered: