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
@ -2912,84 +2912,3 @@ fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
|
||||
}
|
||||
|
||||
pub type ForeignItem = Item<ForeignItemKind>;
|
||||
|
||||
pub trait HasTokens {
|
||||
/// Called by `Parser::collect_tokens` to store the collected
|
||||
/// tokens inside an AST node
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream);
|
||||
}
|
||||
|
||||
impl<T: HasTokens + 'static> HasTokens for P<T> {
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
(**self).finalize_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HasTokens> HasTokens for Option<T> {
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
if let Some(inner) = self {
|
||||
inner.finalize_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTokens for Attribute {
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
match &mut self.kind {
|
||||
AttrKind::Normal(_, attr_tokens) => {
|
||||
if attr_tokens.is_none() {
|
||||
*attr_tokens = Some(tokens);
|
||||
}
|
||||
}
|
||||
AttrKind::DocComment(..) => {
|
||||
panic!("Called finalize_tokens on doc comment attr {:?}", self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTokens for Stmt {
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
let stmt_tokens = match self.kind {
|
||||
StmtKind::Local(ref mut local) => &mut local.tokens,
|
||||
StmtKind::Item(ref mut item) => &mut item.tokens,
|
||||
StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => &mut expr.tokens,
|
||||
StmtKind::Empty => return,
|
||||
StmtKind::MacCall(ref mut mac) => &mut mac.tokens,
|
||||
};
|
||||
if stmt_tokens.is_none() {
|
||||
*stmt_tokens = Some(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! derive_has_tokens {
|
||||
($($ty:path),*) => { $(
|
||||
impl HasTokens for $ty {
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
if self.tokens.is_none() {
|
||||
self.tokens = Some(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
derive_has_tokens! {
|
||||
Item, Expr, Ty, AttrItem, Visibility, Path, Block, Pat
|
||||
}
|
||||
|
||||
macro_rules! derive_has_attrs_no_tokens {
|
||||
($($ty:path),*) => { $(
|
||||
impl HasTokens for $ty {
|
||||
fn finalize_tokens(&mut self, _tokens: LazyTokenStream) {}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
// These ast nodes only support inert attributes, so they don't
|
||||
// store tokens (since nothing can observe them)
|
||||
derive_has_attrs_no_tokens! {
|
||||
StructField, Arm,
|
||||
Field, FieldPat, Variant, Param, GenericParam
|
||||
}
|
||||
|
219
compiler/rustc_ast/src/ast_like.rs
Normal file
219
compiler/rustc_ast/src/ast_like.rs
Normal file
@ -0,0 +1,219 @@
|
||||
use super::ptr::P;
|
||||
use super::tokenstream::LazyTokenStream;
|
||||
use super::{Arm, Field, FieldPat, GenericParam, Param, StructField, Variant};
|
||||
use super::{AssocItem, Expr, ForeignItem, Item, Local};
|
||||
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
|
||||
use super::{AttrVec, Attribute, Stmt, StmtKind};
|
||||
|
||||
/// An `AstLike` represents an AST node (or some wrapper around
|
||||
/// and AST node) which stores some combination of attributes
|
||||
/// and tokens.
|
||||
pub trait AstLike: Sized {
|
||||
fn attrs(&self) -> &[Attribute];
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
|
||||
/// Called by `Parser::collect_tokens` to store the collected
|
||||
/// tokens inside an AST node
|
||||
fn finalize_tokens(&mut self, _tokens: LazyTokenStream) {
|
||||
// This default impl makes this trait easier to implement
|
||||
// in tools like `rust-analyzer`
|
||||
panic!("`finalize_tokens` is not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AstLike + 'static> AstLike for P<T> {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
(**self).attrs()
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
(**self).visit_attrs(f);
|
||||
}
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
(**self).finalize_tokens(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
crate::mut_visit::visit_clobber(attrs, |attrs| {
|
||||
let mut vec = attrs.into();
|
||||
f(&mut vec);
|
||||
vec.into()
|
||||
});
|
||||
}
|
||||
|
||||
impl AstLike for StmtKind {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
match *self {
|
||||
StmtKind::Local(ref local) => local.attrs(),
|
||||
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
|
||||
StmtKind::Item(ref item) => item.attrs(),
|
||||
StmtKind::Empty => &[],
|
||||
StmtKind::MacCall(ref mac) => &*mac.attrs,
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
match self {
|
||||
StmtKind::Local(local) => local.visit_attrs(f),
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
|
||||
StmtKind::Item(item) => item.visit_attrs(f),
|
||||
StmtKind::Empty => {}
|
||||
StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f),
|
||||
}
|
||||
}
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
let stmt_tokens = match self {
|
||||
StmtKind::Local(ref mut local) => &mut local.tokens,
|
||||
StmtKind::Item(ref mut item) => &mut item.tokens,
|
||||
StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => &mut expr.tokens,
|
||||
StmtKind::Empty => return,
|
||||
StmtKind::MacCall(ref mut mac) => &mut mac.tokens,
|
||||
};
|
||||
if stmt_tokens.is_none() {
|
||||
*stmt_tokens = Some(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AstLike for Stmt {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
self.kind.attrs()
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
self.kind.visit_attrs(f);
|
||||
}
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
self.kind.finalize_tokens(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl AstLike for Attribute {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
&[]
|
||||
}
|
||||
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {}
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
match &mut self.kind {
|
||||
AttrKind::Normal(_, attr_tokens) => {
|
||||
if attr_tokens.is_none() {
|
||||
*attr_tokens = Some(tokens);
|
||||
}
|
||||
}
|
||||
AttrKind::DocComment(..) => {
|
||||
panic!("Called finalize_tokens on doc comment attr {:?}", self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AstLike> AstLike for Option<T> {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[])
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
if let Some(inner) = self.as_mut() {
|
||||
inner.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
if let Some(inner) = self {
|
||||
inner.finalize_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait for the macros below. Abstracts over
|
||||
/// the two types of attribute fields that AST nodes
|
||||
/// may have (`Vec<Attribute>` or `AttrVec`)
|
||||
trait VecOrAttrVec {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
|
||||
}
|
||||
|
||||
impl VecOrAttrVec for Vec<Attribute> {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl VecOrAttrVec for AttrVec {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
visit_attrvec(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! derive_has_tokens_and_attrs {
|
||||
($($ty:path),*) => { $(
|
||||
impl AstLike for $ty {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
&self.attrs
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
VecOrAttrVec::visit(&mut self.attrs, f)
|
||||
}
|
||||
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
if self.tokens.is_none() {
|
||||
self.tokens = Some(tokens);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
macro_rules! derive_has_attrs_no_tokens {
|
||||
($($ty:path),*) => { $(
|
||||
impl AstLike for $ty {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
&self.attrs
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
VecOrAttrVec::visit(&mut self.attrs, f)
|
||||
}
|
||||
|
||||
fn finalize_tokens(&mut self, _tokens: LazyTokenStream) {}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
macro_rules! derive_has_tokens_no_attrs {
|
||||
($($ty:path),*) => { $(
|
||||
impl AstLike for $ty {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
}
|
||||
|
||||
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
|
||||
if self.tokens.is_none() {
|
||||
self.tokens = Some(tokens);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
// These AST nodes support both inert and active
|
||||
// attributes, so they also have tokens.
|
||||
derive_has_tokens_and_attrs! {
|
||||
Item, Expr, Local, AssocItem, ForeignItem
|
||||
}
|
||||
|
||||
// These ast nodes only support inert attributes, so they don't
|
||||
// store tokens (since nothing can observe them)
|
||||
derive_has_attrs_no_tokens! {
|
||||
StructField, Arm,
|
||||
Field, FieldPat, Variant, Param, GenericParam
|
||||
}
|
||||
|
||||
// These AST nodes don't support attributes, but can
|
||||
// be captured by a `macro_rules!` matcher. Therefore,
|
||||
// they need to store tokens.
|
||||
derive_has_tokens_no_attrs! {
|
||||
Ty, Block, AttrItem, Pat, Path, Visibility
|
||||
}
|
@ -1,17 +1,15 @@
|
||||
//! Functions dealing with attributes and meta items.
|
||||
|
||||
use crate::ast;
|
||||
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
|
||||
use crate::ast::{Expr, GenericParam, Item, Lit, LitKind, Local, Stmt, StmtKind};
|
||||
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
||||
use crate::ast::{Lit, LitKind};
|
||||
use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
||||
use crate::ast::{Path, PathSegment};
|
||||
use crate::mut_visit::visit_clobber;
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Token};
|
||||
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree, TreeAndSpacing};
|
||||
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_span::source_map::{BytePos, Spanned};
|
||||
use rustc_span::source_map::BytePos;
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
@ -617,101 +615,3 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem>
|
||||
MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasAttrs: Sized {
|
||||
fn attrs(&self) -> &[Attribute];
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
|
||||
}
|
||||
|
||||
impl<T: HasAttrs> HasAttrs for Spanned<T> {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
self.node.attrs()
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
self.node.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
|
||||
impl HasAttrs for Vec<Attribute> {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
self
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasAttrs for AttrVec {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
self
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
visit_clobber(self, |this| {
|
||||
let mut vec = this.into();
|
||||
f(&mut vec);
|
||||
vec.into()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HasAttrs + 'static> HasAttrs for P<T> {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
(**self).attrs()
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
(**self).visit_attrs(f);
|
||||
}
|
||||
}
|
||||
|
||||
impl HasAttrs for StmtKind {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
match *self {
|
||||
StmtKind::Local(ref local) => local.attrs(),
|
||||
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
|
||||
StmtKind::Item(ref item) => item.attrs(),
|
||||
StmtKind::Empty => &[],
|
||||
StmtKind::MacCall(ref mac) => mac.attrs.attrs(),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
match self {
|
||||
StmtKind::Local(local) => local.visit_attrs(f),
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
|
||||
StmtKind::Item(item) => item.visit_attrs(f),
|
||||
StmtKind::Empty => {}
|
||||
StmtKind::MacCall(mac) => {
|
||||
mac.attrs.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasAttrs for Stmt {
|
||||
fn attrs(&self) -> &[ast::Attribute] {
|
||||
self.kind.attrs()
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
self.kind.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! derive_has_attrs {
|
||||
($($ty:path),*) => { $(
|
||||
impl HasAttrs for $ty {
|
||||
fn attrs(&self) -> &[Attribute] {
|
||||
&self.attrs
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
self.attrs.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
|
||||
derive_has_attrs! {
|
||||
Item, Expr, Local, ast::AssocItem, ast::ForeignItem, ast::StructField, ast::Arm,
|
||||
ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ pub mod util {
|
||||
}
|
||||
|
||||
pub mod ast;
|
||||
pub mod ast_like;
|
||||
pub mod attr;
|
||||
pub mod crate_disambiguator;
|
||||
pub mod entry;
|
||||
@ -52,6 +53,7 @@ pub mod util {
|
||||
pub mod visit;
|
||||
|
||||
pub use self::ast::*;
|
||||
pub use self::ast_like::AstLike;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
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 @@ fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
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 @@ macro_rules! configure {
|
||||
#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 @@ pub fn configure<T: HasAttrs>(&mut self, mut node: T) -> Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
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::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 @@ fn collect_attr(
|
||||
/// 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 @@ fn take_first_attr(
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
types::{transparent_newtype_field, CItemKind},
|
||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
|
||||
};
|
||||
use rustc_ast::attr::{self, HasAttrs};
|
||||
use rustc_ast::attr;
|
||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||
use rustc_ast::visit::{FnCtxt, FnKind};
|
||||
use rustc_ast::{self as ast, *};
|
||||
|
@ -18,7 +18,7 @@
|
||||
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::visit as ast_visit;
|
||||
use rustc_attr::HasAttrs;
|
||||
use rustc_ast::AstLike;
|
||||
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
|
@ -8,9 +8,9 @@
|
||||
#![feature(box_patterns)]
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::attr::HasAttrs;
|
||||
use rustc_ast::token::{self, Nonterminal};
|
||||
use rustc_ast::tokenstream::{self, CanSynthesizeMissingTokens, LazyTokenStream, TokenStream};
|
||||
use rustc_ast::AstLike;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Diagnostic, FatalError, Level, PResult};
|
||||
|
@ -3,7 +3,7 @@
|
||||
use rustc_ast::token::{self, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{CreateTokenStream, TokenStream, TokenTree, TreeAndSpacing};
|
||||
use rustc_ast::tokenstream::{DelimSpan, LazyTokenStream, Spacing};
|
||||
use rustc_ast::HasTokens;
|
||||
use rustc_ast::AstLike;
|
||||
use rustc_ast::{self as ast};
|
||||
use rustc_errors::PResult;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -59,7 +59,7 @@ impl<'a> Parser<'a> {
|
||||
/// This restriction shouldn't be an issue in practice,
|
||||
/// since this function is used to record the tokens for
|
||||
/// a parsed AST item, which always has matching delimiters.
|
||||
pub fn collect_tokens_trailing_token<R: HasTokens>(
|
||||
pub fn collect_tokens_trailing_token<R: AstLike>(
|
||||
&mut self,
|
||||
attrs: AttrWrapper,
|
||||
force_collect: ForceCollect,
|
||||
|
@ -22,7 +22,7 @@
|
||||
use rustc_ast::tokenstream::{self, DelimSpan, Spacing};
|
||||
use rustc_ast::tokenstream::{TokenStream, TokenTree, TreeAndSpacing};
|
||||
use rustc_ast::DUMMY_NODE_ID;
|
||||
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, CrateSugar, Extern, HasTokens};
|
||||
use rustc_ast::{self as ast, AnonConst, AstLike, AttrStyle, AttrVec, Const, CrateSugar, Extern};
|
||||
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit, Unsafe};
|
||||
use rustc_ast::{Visibility, VisibilityKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
@ -1228,7 +1228,7 @@ fn parse_abi(&mut self) -> Option<StrLit> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_tokens_no_attrs<R: HasTokens>(
|
||||
pub fn collect_tokens_no_attrs<R: AstLike>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut Self) -> PResult<'a, R>,
|
||||
) -> PResult<'a, R> {
|
||||
|
@ -8,10 +8,10 @@
|
||||
use crate::maybe_whole;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::attr::HasAttrs;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, TokenKind};
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::AstLike;
|
||||
use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
|
||||
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
|
Loading…
Reference in New Issue
Block a user