From 6cab02cf149787db6c9e30ee0ceed97768bbe9aa Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 30 Nov 2019 01:57:53 +0100 Subject: [PATCH] simplify gated cfgs logic --- src/librustc_driver/lib.rs | 21 +++++------- src/libsyntax/attr/builtin.rs | 24 ++++++++++---- src/libsyntax/feature_gate/builtin_attrs.rs | 36 ++++----------------- src/libsyntax/lib.rs | 2 +- 4 files changed, 32 insertions(+), 51 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 13829b842fd5..22f130ed3c9e 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 be53d802eec4..4e7738439b27 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 { /// 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(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 7435b2e056a6..36916de57fca 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 { - 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 8e95fe3c34bf..7f28ebb2b2de 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, };