Require passing an AttrWrapper
to collect_tokens_trailing_token
This is a pure refactoring split out from #80689. It represents the most invasive part of that PR, requiring changes in every caller of `parse_outer_attributes` In order to eagerly expand `#[cfg]` attributes while preserving the original `TokenStream`, we need to know the range of tokens that corresponds to every attribute target. This is accomplished by making `parse_outer_attributes` return an opaque `AttrWrapper` struct. An `AttrWrapper` must be converted to a plain `AttrVec` by passing it to `collect_tokens_trailing_token`. This makes it difficult to accidentally construct an AST node with attributes without calling `collect_tokens_trailing_token`, since AST nodes store an `AttrVec`, not an `AttrWrapper`. As a result, we now call `collect_tokens_trailing_token` for attribute targets which only support inert attributes, such as generic arguments and struct fields. Currently, the constructed `LazyTokenStream` is simply discarded. Future PRs will record the token range corresponding to the attribute target, allowing those tokens to be removed from an enclosing `collect_tokens_trailing_token` call if necessary.
This commit is contained in:
parent
7e0241c637
commit
0b411f56e1
9 changed files with 621 additions and 407 deletions
|
@ -1,4 +1,4 @@
|
|||
use super::{Parser, PathStyle};
|
||||
use super::{ForceCollect, Parser, PathStyle, TrailingToken};
|
||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
|
||||
use rustc_ast::ptr::P;
|
||||
|
@ -938,16 +938,24 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fields.push(match self.parse_pat_field(lo, attrs) {
|
||||
Ok(field) => field,
|
||||
Err(err) => {
|
||||
if let Some(mut delayed_err) = delayed_err {
|
||||
delayed_err.emit();
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
});
|
||||
ate_comma = self.eat(&token::Comma);
|
||||
let field =
|
||||
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
|
||||
let field = match this.parse_pat_field(lo, attrs) {
|
||||
Ok(field) => Ok(field),
|
||||
Err(err) => {
|
||||
if let Some(mut delayed_err) = delayed_err.take() {
|
||||
delayed_err.emit();
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
}?;
|
||||
ate_comma = this.eat(&token::Comma);
|
||||
// We just ate a comma, so there's no need to use
|
||||
// `TrailingToken::Comma`
|
||||
Ok((field, TrailingToken::None))
|
||||
})?;
|
||||
|
||||
fields.push(field)
|
||||
}
|
||||
|
||||
if let Some(mut err) = delayed_err {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue