about summary refs log tree commit diff
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
parent8ad4d15f3888f1339d52632d40e0a47697dd2a24 (diff)
downloadrust-6cab02cf149787db6c9e30ee0ceed97768bbe9aa.tar.gz
rust-6cab02cf149787db6c9e30ee0ceed97768bbe9aa.zip
simplify gated cfgs logic
-rw-r--r--src/librustc_driver/lib.rs21
-rw-r--r--src/libsyntax/attr/builtin.rs24
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs36
-rw-r--r--src/libsyntax/lib.rs2
4 files changed, 32 insertions, 51 deletions
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 13829b842fd..22f130ed3c9 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -62,9 +62,9 @@ use std::time::Instant;
 
 use syntax::ast;
 use syntax::source_map::FileLoader;
-use syntax::feature_gate::{GatedCfg, UnstableFeatures};
-use syntax::symbol::sym;
-use syntax_pos::{DUMMY_SP, FileName};
+use syntax::feature_gate::{find_gated_cfg, UnstableFeatures};
+use syntax_pos::symbol::sym;
+use syntax_pos::FileName;
 
 pub mod pretty;
 mod args;
@@ -677,12 +677,6 @@ impl RustcDefaultCalls {
                         .is_nightly_build();
 
                     let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
-                        let gated_cfg = GatedCfg::gate(&ast::MetaItem {
-                            path: ast::Path::from_ident(ast::Ident::with_dummy_span(name)),
-                            kind: ast::MetaItemKind::Word,
-                            span: DUMMY_SP,
-                        });
-
                         // Note that crt-static is a specially recognized cfg
                         // directive that's printed out here as part of
                         // rust-lang/rust#37406, but in general the
@@ -693,10 +687,11 @@ impl RustcDefaultCalls {
                         // through to build scripts.
                         let value = value.as_ref().map(|s| s.as_str());
                         let value = value.as_ref().map(|s| s.as_ref());
-                        if name != sym::target_feature || value != Some("crt-static") {
-                            if !allow_unstable_cfg && gated_cfg.is_some() {
-                                return None
-                            }
+                        if (name != sym::target_feature || value != Some("crt-static"))
+                            && !allow_unstable_cfg
+                            && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some()
+                        {
+                            return None;
                         }
 
                         if let Some(value) = value {
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() {
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 7435b2e056a..36916de57fc 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -3,19 +3,15 @@
 use AttributeType::*;
 use AttributeGate::*;
 
-use super::check::{emit_feature_err, GateIssue};
 use super::check::{EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE};
 use rustc_feature::{Features, Stability};
 
 use crate::ast;
-use crate::sess::ParseSess;
 
 use syntax_pos::symbol::{Symbol, sym};
-use syntax_pos::Span;
 use rustc_data_structures::fx::FxHashMap;
 use lazy_static::lazy_static;
 
-
 type GateFn = fn(&Features) -> bool;
 
 macro_rules! cfg_fn {
@@ -24,39 +20,19 @@ macro_rules! cfg_fn {
     }
 }
 
+pub type GatedCfg = (Symbol, Symbol, GateFn);
+
 /// `cfg(...)`'s that are feature gated.
-const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[
+const GATED_CFGS: &[GatedCfg] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
     (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
     (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
     (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
 ];
 
-#[derive(Debug)]
-pub struct GatedCfg {
-    span: Span,
-    index: usize,
-}
-
-impl GatedCfg {
-    pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
-        GATED_CFGS.iter()
-                  .position(|info| cfg.check_name(info.0))
-                  .map(|idx| {
-                      GatedCfg {
-                          span: cfg.span,
-                          index: idx
-                      }
-                  })
-    }
-
-    pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
-        let (cfg, feature, has_feature) = GATED_CFGS[self.index];
-        if !has_feature(features) && !self.span.allows_unstable(feature) {
-            let explain = format!("`cfg({})` is experimental and subject to change", cfg);
-            emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
-        }
-    }
+/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
+pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg> {
+    GATED_CFGS.iter().find(|(cfg_sym, ..)| pred(*cfg_sym))
 }
 
 // If you change this, please modify `src/doc/unstable-book` as well. You must
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 8e95fe3c34b..7f28ebb2b2d 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -101,7 +101,7 @@ pub mod feature_gate {
     };
     mod builtin_attrs;
     pub use builtin_attrs::{
-        AttributeGate, AttributeTemplate, AttributeType, GatedCfg,
+        AttributeGate, AttributeTemplate, AttributeType, find_gated_cfg, GatedCfg,
         BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
         deprecated_attributes, is_builtin_attr,  is_builtin_attr_name,
     };