Combine HasAttrs and HasTokens into AstLike
When token-based attribute handling is implemeneted in #80689, we will need to access tokens from `HasAttrs` (to perform cfg-stripping), and we will to access attributes from `HasTokens` (to construct a `PreexpTokenStream`). This PR merges the `HasAttrs` and `HasTokens` traits into a new `AstLike` trait. The previous `HasAttrs` impls from `Vec<Attribute>` and `AttrVec` are removed - they aren't attribute targets, so the impls never really made sense.
This commit is contained in:
parent
9fa580b117
commit
fb5fec017b
13 changed files with 264 additions and 206 deletions
|
@ -3,10 +3,10 @@ use crate::module::DirectoryOwnership;
|
|||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Nonterminal};
|
||||
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
|
||||
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, LazyTokenStream, TokenStream};
|
||||
use rustc_ast::visit::{AssocCtxt, Visitor};
|
||||
use rustc_ast::{self as ast, Attribute, NodeId, PatKind};
|
||||
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
|
||||
use rustc_ast::{self as ast, AstLike, Attribute, NodeId, PatKind};
|
||||
use rustc_attr::{self as attr, Deprecation, Stability};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::{self, Lrc};
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorReported};
|
||||
|
@ -44,7 +44,7 @@ pub enum Annotatable {
|
|||
Variant(ast::Variant),
|
||||
}
|
||||
|
||||
impl HasAttrs for Annotatable {
|
||||
impl AstLike for Annotatable {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
match *self {
|
||||
Annotatable::Item(ref item) => &item.attrs,
|
||||
|
@ -80,6 +80,10 @@ impl HasAttrs for Annotatable {
|
|||
Annotatable::Variant(v) => v.visit_attrs(f),
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
panic!("Called finalize_tokens on an Annotatable: {:?}", tokens);
|
||||
}
|
||||
}
|
||||
|
||||
impl Annotatable {
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
use crate::base::Annotatable;
|
||||
|
||||
use rustc_ast::attr::HasAttrs;
|
||||
use rustc_ast::mut_visit::*;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{DelimToken, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{DelimSpan, LazyTokenStream, Spacing, TokenStream, TokenTree};
|
||||
use rustc_ast::{self as ast, AttrItem, Attribute, MetaItem};
|
||||
use rustc_ast::{self as ast, AstLike, AttrItem, Attribute, MetaItem};
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::map_in_place::MapInPlace;
|
||||
|
@ -205,7 +204,7 @@ pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features)
|
|||
let unconfigured_attrs = krate.attrs.clone();
|
||||
let diag = &sess.parse_sess.span_diagnostic;
|
||||
let err_count = diag.err_count();
|
||||
let features = match strip_unconfigured.configure(krate.attrs) {
|
||||
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
|
||||
None => {
|
||||
// The entire crate is unconfigured.
|
||||
krate.attrs = Vec::new();
|
||||
|
@ -218,7 +217,9 @@ pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features)
|
|||
if err_count == diag.err_count() {
|
||||
// Avoid reconfiguring malformed `cfg_attr`s.
|
||||
strip_unconfigured.features = Some(&features);
|
||||
strip_unconfigured.configure(unconfigured_attrs);
|
||||
// Run configuration again, this time with features available
|
||||
// so that we can perform feature-gating.
|
||||
strip_unconfigured.configure_krate_attrs(unconfigured_attrs);
|
||||
}
|
||||
features
|
||||
}
|
||||
|
@ -242,7 +243,7 @@ const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
|
|||
#the-cfg_attr-attribute>";
|
||||
|
||||
impl<'a> StripUnconfigured<'a> {
|
||||
pub fn configure<T: HasAttrs>(&mut self, mut node: T) -> Option<T> {
|
||||
pub fn configure<T: AstLike>(&mut self, mut node: T) -> Option<T> {
|
||||
self.process_cfg_attrs(&mut node);
|
||||
if self.in_cfg(node.attrs()) {
|
||||
Some(node)
|
||||
|
@ -252,13 +253,26 @@ impl<'a> StripUnconfigured<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn configure_krate_attrs(
|
||||
&mut self,
|
||||
mut attrs: Vec<ast::Attribute>,
|
||||
) -> Option<Vec<ast::Attribute>> {
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
if self.in_cfg(&attrs) {
|
||||
Some(attrs)
|
||||
} else {
|
||||
self.modified = true;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse and expand all `cfg_attr` attributes into a list of attributes
|
||||
/// that are within each `cfg_attr` that has a true configuration predicate.
|
||||
///
|
||||
/// Gives compiler warnings if any `cfg_attr` does not contain any
|
||||
/// attributes and is in the original source code. Gives compiler errors if
|
||||
/// the syntax of any `cfg_attr` is incorrect.
|
||||
pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: &mut T) {
|
||||
pub fn process_cfg_attrs<T: AstLike>(&mut self, node: &mut T) {
|
||||
node.visit_attrs(|attrs| {
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
});
|
||||
|
|
|
@ -12,11 +12,11 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
||||
use rustc_ast::{AttrItem, AttrStyle, Block, Inline, ItemKind, LitKind, MacArgs};
|
||||
use rustc_ast::{AstLike, AttrItem, AttrStyle, Block, Inline, ItemKind, LitKind, MacArgs};
|
||||
use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem};
|
||||
use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
|
||||
use rustc_attr::{self as attr, is_builtin_attr};
|
||||
use rustc_data_structures::map_in_place::MapInPlace;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -1014,7 +1014,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
/// legacy derive helpers (helpers written before derives that introduce them).
|
||||
fn take_first_attr(
|
||||
&mut self,
|
||||
item: &mut impl HasAttrs,
|
||||
item: &mut impl AstLike,
|
||||
) -> Option<(ast::Attribute, usize, Vec<Path>)> {
|
||||
let mut attr = None;
|
||||
|
||||
|
@ -1045,7 +1045,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
attr
|
||||
}
|
||||
|
||||
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
||||
fn configure<T: AstLike>(&mut self, node: T) -> Option<T> {
|
||||
self.cfg.configure(node)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue