-
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
Pre-expansion gating collects spans from unSuccess
ful macro matchers
#65846
Comments
I suspect this was caused by #65742 (definitely something in #65793) -- presumably, that PR does something wrong, as I suspect that the expression here is not type ascription -- |
Reduced to: macro_rules! mac {
($e:expr) => {}; // Removing this line makes it compile again.
(label: $v:expr, MARKER) => {};
}
mac!(label: 0, MARKER); which results in: error: expected type, found `0`
--> src/lib.rs:6:13
|
6 | mac!(label: 0, MARKER);
| - ^ expected type
| |
| tried to parse a type due to this on stable, and: error: expected type, found `0`
--> src/lib.rs:6:13
|
6 | mac!(label: 0, MARKER);
| - ^ expected type
| |
| tried to parse a type due to this type ascription
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
= note: for more information, see https://github.com/rust-lang/rust/issues/23416 on nightly. |
I'm not sure how this code managed to work before because it is parsing a type ascription (successfully when using let parser_snapshot_before_type = self.clone();
match self.parse_ty_no_plus() {
Ok(rhs) => {
- Ok(mk_expr(self, rhs))
+ let expr = mk_expr(self, rhs);
+ if let ExprKind::Type(..) = expr.kind {
+ panic!("PARSED TYPE ASCRIPTION!");
+ }
+ Ok(expr)
} where the input was: macro_rules! mac {
($e:expr) => {};
(label: $v:expr, MARKER) => {};
}
mac!(label: try!(), MARKER) Somehow this type ascription disappears later before All in all, I believe that at least from the POV of the parser, the behavior is expected and therefore there is no bug. This should be fixed on perf's end, at least in the interim, by switching to a token besides |
This is still a breaking change - and I would expect it to be fixed in the parser, especially as in this case the macro input doesn't even look like type ascription, it's token colon expression, whereas type ascription would be token colon type, right? I'll look into a fix for perf, just to get us unbroken, but I feel pretty strongly so far that this is a breaking change and a bug. |
Well it is parsing a type ascription because it is constructing an macro_rules! m {
($e:expr) => { dbg!(0); };
(lab as $e:expr, foo) => { dbg!(1); };
}
fn main() {
m!(lab as 1, foo);
} Because of the first arm, this will error with "error: expected type, found Another case to consider is (playground): macro_rules! m {
($e:expr) => { dbg!(0); };
(box $e:expr, foo) => { dbg!(1); };
}
fn main() {
m!(box 1, foo);
} This also used to compile and now emits a feature gate error? Why? Because macro expansion will try each arm in a rust/src/libsyntax_expand/mbe/macro_rules.rs Lines 186 to 248 in 46e6c53
In this case, once we have parsed macro_rules! m {
($e:expr) => { dbg!(0); };
(box $e:expr, foo2) => { dbg!(1); };
}
fn main() {
m!(box 1, foo);
} The only way I know of to not do that which might possibly be correct and still perform pre-expansion gating would be to snapshot
#64672 (comment) (crates.io had 5 regressions where 4 of those were from the same project with the same root and then there was another root; github had 2 regressions)
If there is a bug, having done the investigation, I can say with certainty that it is not in #65742 but rather a pre-existing one in Also, we should absolutely continue performing pre-expansion gating. To not do so would mean leaking all new syntax into stable immediately! In the long run, that will make both users and the language team unhappy. Moreover, making things which were accidentally stable unstable is legitimized by rust-lang/rfcs#2405, which you signed off on yourself. |
I would expect pre-expansion gating in this form (i.e., macro input parsing) to either emit a future-incompatibility warning (like we do for methods that might conflict with a future stabilization, I believe) or simply pretend that the gated form does not exist unless the feature gate is enabled. I get that this is likely hard -- and might not even be practical -- but as it is currently, even though I personally do not expect us to stabilize box expressions in their current syntax/form for what is likely on the order of years, if ever, it seems really odd to forbid the
This is basically my point -- as it is implemented today, all Rust users pay the pain of new syntax in macros immediately upon its addition. That gives us no time for experimentation or to decide if that's a good thing; furthermore, Rust users who use stable may experience breakage from unstable features. Maybe that's fine -- and we just need to be really careful when adding/modifying unstable syntax parsing -- but to me it seems like that's probably not quite what we want. I, at least, would expect that an unstable feature, even when it comes to syntax, is invisible, possibly modulo diagnostics, to stable users of the compiler (or those not using the specific feature gate). |
We've fixed perf.rlo so removing high priority label. |
Closing in favor of #65860. |
That's a distinct problem. That one is about cfg-expansion and this is about macro matchers. They will have different solutions. I'll try to look at fixing this one today. |
Success
ful macro matchers
I have a fix in #65974. |
triage: P-high |
Setting high priority as this affects performance collection.
Sample error, likely possible to see more at https://perf.rust-lang.org/status.html
The text was updated successfully, but these errors were encountered: