diff options
| author | bors <bors@rust-lang.org> | 2019-12-01 00:39:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-01 00:39:18 +0000 |
| commit | 135ccbaca86ed4b9c0efaf0cd31442eae57ffad7 (patch) | |
| tree | f5d91a593d425871fff9e1b68ac2e9f982d6c8e1 /src/libsyntax/attr | |
| parent | d8bdb3fdcbd88eb16e1a6669236122c41ed2aed3 (diff) | |
| parent | b772b5b19d769e7062b032e6e73f6466b26d78bd (diff) | |
| download | rust-135ccbaca86ed4b9c0efaf0cd31442eae57ffad7.tar.gz rust-135ccbaca86ed4b9c0efaf0cd31442eae57ffad7.zip | |
Auto merge of #66908 - Centril:rollup-26givp6, r=Centril
Rollup of 9 pull requests Successful merges: - #66612 (Initial implementation of or-pattern usefulness checking) - #66705 (Atomic as_mut_ptr) - #66759 (impl TrustedLen for vec::Drain) - #66858 (Use LLVMAddAnalysisPasses instead of Rust's wrapper) - #66870 (SimplifyArmIdentity only for locals with the same type) - #66883 (rustc_typeck: gate AnonConst's generics on feature(const_generics).) - #66889 (Make python-generated source files compatible with rustfmt) - #66894 (Remove unneeded prelude imports in libcore tests) - #66895 (Feature gating *declarations* => new crate `rustc_feature`) Failed merges: - #66905 (rustc_plugin: Remove some remaining plugin features) r? @ghost
Diffstat (limited to 'src/libsyntax/attr')
| -rw-r--r-- | src/libsyntax/attr/builtin.rs | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index c10541c8c7e..3c10f27b60a 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -1,7 +1,8 @@ //! Parsing and validation of builtin attributes +use super::{mark_used, MetaItemKind}; use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; -use crate::feature_gate::{Features, GatedCfg}; +use crate::feature_gate::feature_err; use crate::print::pprust; use crate::sess::ParseSess; @@ -9,12 +10,15 @@ use errors::{Applicability, Handler}; use std::num::NonZeroU32; use syntax_pos::hygiene::Transparency; use syntax_pos::{symbol::Symbol, symbol::sym, Span}; +use rustc_feature::{Features, find_gated_cfg, GatedCfg, is_builtin_attr_name}; use rustc_macros::HashStable_Generic; -use super::{mark_used, MetaItemKind}; - use rustc_error_codes::*; +pub fn is_builtin_attr(attr: &Attribute) -> bool { + attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() +} + enum AttrError { MultipleItem(String), UnknownMetaItem(String, &'static [&'static str]), @@ -24,31 +28,6 @@ enum AttrError { UnsupportedLiteral(&'static str, /* is_bytestr */ bool), } -/// A template that the attribute input must match. -/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. -#[derive(Clone, Copy)] -pub struct AttributeTemplate { - pub word: bool, - pub list: Option<&'static str>, - pub name_value_str: Option<&'static str>, -} - -impl AttributeTemplate { - pub fn only_word() -> Self { - Self { word: true, list: None, name_value_str: None } - } - - /// Checks that the given meta-item is compatible with this template. - pub fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool { - match meta_item_kind { - ast::MetaItemKind::Word => self.word, - ast::MetaItemKind::List(..) => self.list.is_some(), - ast::MetaItemKind::NameValue(lit) if lit.kind.is_str() => self.name_value_str.is_some(), - ast::MetaItemKind::NameValue(..) => false, - } - } -} - fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { let diag = &sess.span_diagnostic; match error { @@ -555,8 +534,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 { @@ -585,12 +565,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); + feature_err(sess, *feature, cfg_span, &explain).emit() + } +} + /// 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() { |
