about summary refs log tree commit diff
path: root/src/libsyntax/attr
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-11-30 01:57:53 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-11-30 01:57:53 +0100
commit6cab02cf149787db6c9e30ee0ceed97768bbe9aa (patch)
tree69ca7363f283a7a6be0251062f76956dfd2bc4e5 /src/libsyntax/attr
parent8ad4d15f3888f1339d52632d40e0a47697dd2a24 (diff)
downloadrust-6cab02cf149787db6c9e30ee0ceed97768bbe9aa.tar.gz
rust-6cab02cf149787db6c9e30ee0ceed97768bbe9aa.zip
simplify gated cfgs logic
Diffstat (limited to 'src/libsyntax/attr')
-rw-r--r--src/libsyntax/attr/builtin.rs24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index be53d802eec..4e7738439b2 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -1,8 +1,8 @@
 //! Parsing and validation of builtin attributes
 
 use crate::ast::{self, Attribute, MetaItem, NestedMetaItem};
+use crate::feature_gate::{find_gated_cfg, emit_feature_err, GatedCfg, GateIssue};
 use crate::print::pprust;
-use crate::feature_gate::GatedCfg;
 use crate::sess::ParseSess;
 
 use errors::{Applicability, Handler};
@@ -531,8 +531,9 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
 /// Tests if a cfg-pattern matches the cfg set
 pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
     eval_condition(cfg, sess, &mut |cfg| {
-        if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
-            gated_cfg.check_and_emit(sess, feats);
+        let gate = find_gated_cfg(|sym| cfg.check_name(sym));
+        if let (Some(feats), Some(gated_cfg)) = (features, gate) {
+            gate_cfg(&gated_cfg, cfg.span, sess, feats);
         }
         let error = |span, msg| { sess.span_diagnostic.span_err(span, msg); true };
         if cfg.path.segments.len() != 1 {
@@ -561,12 +562,21 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
     })
 }
 
+fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) {
+    let (cfg, feature, has_feature) = gated_cfg;
+    if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
+        let explain = format!("`cfg({})` is experimental and subject to change", cfg);
+        emit_feature_err(sess, *feature, cfg_span, GateIssue::Language, &explain);
+    }
+}
+
 /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
 /// evaluate individual items.
-pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
-                         -> bool
-    where F: FnMut(&ast::MetaItem) -> bool
-{
+pub fn eval_condition(
+    cfg: &ast::MetaItem,
+    sess: &ParseSess,
+    eval: &mut impl FnMut(&ast::MetaItem) -> bool,
+) -> bool {
     match cfg.kind {
         ast::MetaItemKind::List(ref mis) => {
             for mi in mis.iter() {