about summary refs log tree commit diff
path: root/compiler/rustc_expand/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_expand/src/config.rs')
-rw-r--r--compiler/rustc_expand/src/config.rs52
1 files changed, 38 insertions, 14 deletions
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 170ac39d1ec..6922ddfd6bd 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -11,6 +11,9 @@ use rustc_ast::{
     NodeId, NormalAttr,
 };
 use rustc_attr_parsing as attr;
+use rustc_attr_parsing::{
+    AttributeParser, CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg_attr,
+};
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_feature::{
     ACCEPTED_LANG_FEATURES, AttributeSafety, EnabledLangFeature, EnabledLibFeature, Features,
@@ -18,6 +21,7 @@ use rustc_feature::{
 };
 use rustc_lint_defs::BuiltinLintDiag;
 use rustc_parse::validate_attr;
+use rustc_parse::validate_attr::deny_builtin_meta_unsafety;
 use rustc_session::Session;
 use rustc_session::parse::feature_err;
 use rustc_span::{STDLIB_STABLE_CRATES, Span, Symbol, sym};
@@ -161,7 +165,10 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
     attrs
         .iter()
         .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
-        .take_while(|attr| !is_cfg(attr) || strip_unconfigured.cfg_true(attr).0)
+        .take_while(|attr| {
+            !is_cfg(attr)
+                || strip_unconfigured.cfg_true(attr, strip_unconfigured.lint_node_id).as_bool()
+        })
         .collect()
 }
 
@@ -394,26 +401,42 @@ impl<'a> StripUnconfigured<'a> {
 
     /// Determines if a node with the given attributes should be included in this configuration.
     fn in_cfg(&self, attrs: &[Attribute]) -> bool {
-        attrs.iter().all(|attr| !is_cfg(attr) || self.cfg_true(attr).0)
+        attrs.iter().all(|attr| !is_cfg(attr) || self.cfg_true(attr, self.lint_node_id).as_bool())
     }
 
-    pub(crate) fn cfg_true(&self, attr: &Attribute) -> (bool, Option<MetaItem>) {
-        let meta_item = match validate_attr::parse_meta(&self.sess.psess, attr) {
-            Ok(meta_item) => meta_item,
+    pub(crate) fn cfg_true(&self, attr: &Attribute, node: NodeId) -> EvalConfigResult {
+        // We need to run this to do basic validation of the attribute, such as that lits are valid, etc
+        // FIXME(jdonszelmann) this should not be necessary in the future
+        match validate_attr::parse_meta(&self.sess.psess, attr) {
+            Ok(_) => {}
             Err(err) => {
                 err.emit();
-                return (true, None);
+                return EvalConfigResult::True;
             }
-        };
+        }
 
-        validate_attr::deny_builtin_meta_unsafety(&self.sess.psess, &meta_item);
+        // Unsafety check needs to be done explicitly here because this attribute will be removed before the normal check
+        deny_builtin_meta_unsafety(
+            self.sess.dcx(),
+            attr.get_normal_item().unsafety,
+            &rustc_ast::Path::from_ident(attr.ident().unwrap()),
+        );
+
+        let Some(cfg) = AttributeParser::parse_single(
+            self.sess,
+            attr,
+            attr.span,
+            node,
+            self.features,
+            true,
+            parse_cfg_attr,
+            &CFG_TEMPLATE,
+        ) else {
+            // Cfg attribute was not parsable, give up
+            return EvalConfigResult::True;
+        };
 
-        (
-            parse_cfg(&meta_item, self.sess).is_none_or(|meta_item| {
-                attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features)
-            }),
-            Some(meta_item),
-        )
+        eval_config_entry(self.sess, &cfg, self.lint_node_id, self.features)
     }
 
     /// If attributes are not allowed on expressions, emit an error for `attr`
@@ -465,6 +488,7 @@ impl<'a> StripUnconfigured<'a> {
     }
 }
 
+/// FIXME: Still used by Rustdoc, should be removed after
 pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItemInner> {
     let span = meta_item.span;
     match meta_item.meta_item_list() {