]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_expand/src/config.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / compiler / rustc_expand / src / config.rs
index 5fa7ffd554ef12b4edaa39ebb966e705cd38bb75..fa628cd9ebd0b8ab62355727c1dc2bc9b097e131 100644 (file)
@@ -5,6 +5,7 @@ use rustc_ast::token::{DelimToken, Token, TokenKind};
 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;
@@ -29,6 +30,7 @@ pub struct StripUnconfigured<'a> {
     /// 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(
@@ -79,9 +81,8 @@ 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 {
@@ -112,9 +113,8 @@ 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;
         };
 
         let bad_input = |span| {
@@ -167,6 +167,7 @@ fn get_features(
             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;
             }
 
@@ -187,10 +188,12 @@ fn get_features(
             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);
         }
     }
 
@@ -198,8 +201,13 @@ fn get_features(
 }
 
 // `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;
@@ -340,10 +348,9 @@ impl<'a> StripUnconfigured<'a> {
     /// 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.
@@ -356,7 +363,12 @@ impl<'a> StripUnconfigured<'a> {
             );
         }
 
-        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![];
         }
 
@@ -389,22 +401,20 @@ impl<'a> StripUnconfigured<'a> {
         // 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),
@@ -450,7 +460,7 @@ impl<'a> StripUnconfigured<'a> {
             }
         };
         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)
         })
     }