use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
use rustc_ast::tokenstream::{DelimSpan, Spacing};
use rustc_ast::tokenstream::{LazyTokenStream, TokenTree};
+use rustc_ast::NodeId;
use rustc_ast::{self as ast, AstLike, AttrStyle, Attribute, MetaItem};
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashMap;
/// This is only used for the input to derive macros,
/// which needs eager expansion of `cfg` and `cfg_attr`
pub config_tokens: bool,
+ pub lint_node_id: NodeId,
}
fn get_features(
continue;
}
- let list = match attr.meta_item_list() {
- Some(list) => list,
- None => continue,
+ let Some(list) = attr.meta_item_list() else {
+ continue;
};
for mi in list {
continue;
}
- let list = match attr.meta_item_list() {
- Some(list) => list,
- None => continue,
+ let Some(list) = attr.meta_item_list() else {
+ continue;
};
let bad_input = |span| {
if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
let since = Some(Symbol::intern(since));
features.declared_lang_features.push((name, mi.span(), since));
+ features.active_features.insert(name);
continue;
}
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
f.set(&mut features, mi.span());
features.declared_lang_features.push((name, mi.span(), None));
+ features.active_features.insert(name);
continue;
}
features.declared_lib_features.push((name, mi.span()));
+ features.active_features.insert(name);
}
}
}
// `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features) {
- let mut strip_unconfigured = StripUnconfigured { sess, features: None, config_tokens: false };
+pub fn features(
+ sess: &Session,
+ mut krate: ast::Crate,
+ lint_node_id: NodeId,
+) -> (ast::Crate, Features) {
+ let mut strip_unconfigured =
+ StripUnconfigured { sess, features: None, config_tokens: false, lint_node_id };
let unconfigured_attrs = krate.attrs.clone();
let diag = &sess.parse_sess.span_diagnostic;
/// is in the original source file. Gives a compiler error if the syntax of
/// the attribute is incorrect.
crate fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
- let (cfg_predicate, expanded_attrs) =
- match rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) {
- None => return vec![],
- Some(r) => r,
+ let Some((cfg_predicate, expanded_attrs)) =
+ rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
+ return vec![];
};
// Lint on zero attributes in source.
);
}
- if !attr::cfg_matches(&cfg_predicate, &self.sess.parse_sess, self.features) {
+ if !attr::cfg_matches(
+ &cfg_predicate,
+ &self.sess.parse_sess,
+ self.lint_node_id,
+ self.features,
+ ) {
return vec![];
}
// Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
// for `attr` when we expand it to `#[attr]`
let mut orig_trees = orig_tokens.trees();
- let pound_token = match orig_trees.next().unwrap() {
- TokenTree::Token(token @ Token { kind: TokenKind::Pound, .. }) => token,
- _ => panic!("Bad tokens for attribute {:?}", attr),
+ let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }) = orig_trees.next().unwrap() else {
+ panic!("Bad tokens for attribute {:?}", attr);
};
let pound_span = pound_token.span;
let mut trees = vec![(AttrAnnotatedTokenTree::Token(pound_token), Spacing::Alone)];
if attr.style == AttrStyle::Inner {
// For inner attributes, we do the same thing for the `!` in `#![some_attr]`
- let bang_token = match orig_trees.next().unwrap() {
- TokenTree::Token(token @ Token { kind: TokenKind::Not, .. }) => token,
- _ => panic!("Bad tokens for attribute {:?}", attr),
+ let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }) = orig_trees.next().unwrap() else {
+ panic!("Bad tokens for attribute {:?}", attr);
};
trees.push((AttrAnnotatedTokenTree::Token(bang_token), Spacing::Alone));
}
- // We don't really have a good span to use for the syntheized `[]`
+ // We don't really have a good span to use for the synthesized `[]`
// in `#[attr]`, so just use the span of the `#` token.
let bracket_group = AttrAnnotatedTokenTree::Delimited(
DelimSpan::from_single(pound_span),
}
};
parse_cfg(&meta_item, &self.sess).map_or(true, |meta_item| {
- attr::cfg_matches(&meta_item, &self.sess.parse_sess, self.features)
+ attr::cfg_matches(&meta_item, &self.sess.parse_sess, self.lint_node_id, self.features)
})
}