simplify gated cfgs logic
This commit is contained in:
parent
8ad4d15f38
commit
6cab02cf14
4 changed files with 32 additions and 51 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue