-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Parser: Recover from attributes applied to types and generic args #144195
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
Conversation
while self.token != token::CloseBracket && self.token != token::Eof { | ||
self.bump(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here is pretty strange.
Why wouldn't we just go through the normal parsing routine to parse an attr, then go through the normal parsing routine to parse a type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, honestly didn't know about "normal parsing routine" and just go manually parsing, do you mean "parse_outer_attributes"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah probably something like that. Look at how we parse item attrs for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's see if I'm on a right way, firstly implemented it for generic then just copied for regular type, based on tests it seems works fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it now, maybe I could yeet that logic into a helper function and not duplicate code, but first need your opinion on logic itself, but I'm out for now
|
||
let span = lo_attr.to(self.prev_token.span); | ||
|
||
if self.token.is_ident() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically, this only works if the type is an ident. We have lots of other types to handle here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just try parsing an attr eagerly at the beginning of parse_ty_common
, and then there doesn't need to be a special branch in this if chain?
r? compiler-errors |
This comment has been minimized.
This comment has been minimized.
5502794
to
2b4000d
Compare
Well I added a branch to handle this (you can see it in review below) error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
--> src/main.rs:4:12
|
4 | let _: Baz<#[cfg(any())]> = todo!();
| ^^^ expected 1 generic argument
|
note: struct defined here, with 1 generic parameter: `N`
--> src/main.rs:1:8
|
1 | struct Baz<const N: usize>(i32);
| ^^^ --------------
help: add missing generic argument
|
4 | let _: Baz<N#[cfg(any())]> = todo!();
| +
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0107`. |
e267a23
to
516db8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've called out the potentially surprising bits of this implementation with explanations to help reviewers in mine this and above reviews
tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
@fmease, I spent significant time trying to address the secondary error you mentioned. Good news: I solved it for cases where there's something inside the generic. When we have But I hit a wall with empty generics like The problem is Whatever we pick will be wrong sometimes. If I default to I can pick a statistical default (types are most common), but some cases will still get secondary errors. Is that acceptable, or do you see another approach I'm missing? The architectural issue seems fundamental since parsing happens before we know what types expect what kinds of generics. |
@rustbot ready |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final stretch, after that I'll approve.
tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs
Outdated
Show resolved
Hide resolved
@@ -934,6 +941,9 @@ impl<'a> Parser<'a> { | |||
} | |||
} else if self.token.is_keyword(kw::Const) { | |||
return self.recover_const_param_declaration(ty_generics); | |||
} else if let Some(attr_span) = attr_span { | |||
let diag = self.dcx().create_err(AttributeOnEmptyType { span: attr_span }); | |||
return Err(diag); | |||
} else { | |||
// Fall back by trying to parse a const-expr expression. If we successfully do so, | |||
// then we should report an error that it needs to be wrapped in braces. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two lines below, there's a preexisting let attrs = self.parse_outer_attributes()?;
. We should be able to drop it and pass the already parsed attrs to the parse_expr_res
.
It's not a blocking concern tho ig and it would stop us from recovering from ///
and /** */
on gen args. Can be done in a follow-up.
|
Small breakdown what I've changed according to last reviews
What I did not made
|
@rustbot ready |
Thanks a lot! |
Rollup of 15 pull requests Successful merges: - #144195 (Parser: Recover from attributes applied to types and generic args) - #144794 (Port `#[coroutine]` to the new attribute system) - #144835 (Anonymize binders in tail call sig) - #144861 (Stabilize `panic_payload_as_str` feature) - #144917 (Enforce tail call type is related to body return type in borrowck) - #144948 (we only merge candidates for trait and normalizes-to goals) - #144956 (Gate const trait syntax) - #144970 (rustdoc: fix caching of intra-doc links on reexports) - #144972 (add code example showing that file_prefix treats dotfiles as the name of a file, not an extension) - #144975 (`File::set_times`: Update documentation and example to support setting timestamps on directories) - #144977 (Fortify generic param default checks) - #144996 (simplifycfg: Mark as changed when start is modified in collapse goto chain) - #144998 (mir: Do not modify NonUse in `super_projection_elem`) - #145000 (Remove unneeded `stage` parameter when setting up stdlib Cargo) - #145008 (Fix rustdoc scrape examples crash) r? `@ghost` `@rustbot` modify labels: rollup
r? compiler
Add clearer error messages for invalid attribute usage in types or generic types
fixes #135017
fixes #144132