diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-08-28 10:38:19 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-08-28 10:38:19 +0000 |
| commit | 6303640e856dc3cccea655df104203649b5efd76 (patch) | |
| tree | 7cb01f242a73cfc7c319708e1674b58eb8a7b4f5 /src/libsyntax/feature_gate.rs | |
| parent | 413ecdee30d76eeed574bc9af547b539bc511863 (diff) | |
| parent | 8250a26b5bcea9190ac63e756c35d8a54bf9da0c (diff) | |
Rollup merge of #35850 - SergioBenitez:master, r=nrc
Implement RFC#1559: allow all literals in attributes Implemented rust-lang/rfcs#1559, tracked by #34981.
Diffstat (limited to 'src/libsyntax/feature_gate.rs')
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9114c31d298..1839f7b8a75 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -26,10 +26,8 @@ use self::AttributeType::*; use self::AttributeGate::*; use abi::Abi; -use ast::{NodeId, PatKind}; -use ast; -use attr; -use attr::AttrMetaMethods; +use ast::{self, NodeId, PatKind}; +use attr::{self, AttrMetaMethods, AttrNestedMetaItemMethods}; use codemap::{CodeMap, Spanned}; use syntax_pos::Span; use errors::Handler; @@ -280,7 +278,10 @@ declare_features! ( (active, relaxed_adts, "1.12.0", Some(35626)), // The `!` type - (active, never_type, "1.13.0", Some(35121)) + (active, never_type, "1.13.0", Some(35121)), + + // Allows all literals in attribute lists and values of key-value pairs. + (active, attr_literals, "1.13.0", Some(34981)) ); declare_features! ( @@ -830,11 +831,34 @@ impl<'a> PostExpansionVisitor<'a> { } } +fn contains_novel_literal(item: &ast::MetaItem) -> bool { + use ast::MetaItemKind::*; + use ast::NestedMetaItemKind::*; + + match item.node { + Word(..) => false, + NameValue(_, ref lit) => !lit.node.is_str(), + List(_, ref list) => list.iter().any(|li| { + match li.node { + MetaItem(ref mi) => contains_novel_literal(&**mi), + Literal(_) => true, + } + }), + } +} + impl<'a> Visitor for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { if !self.context.cm.span_allows_unstable(attr.span) { + // check for gated attributes self.context.check_attribute(attr, false); } + + if contains_novel_literal(&*(attr.node.value)) { + gate_feature_post!(&self, attr_literals, attr.span, + "non-string literals in attributes, or string \ + literals in top-level positions, are experimental"); + } } fn visit_name(&mut self, sp: Span, name: ast::Name) { @@ -894,7 +918,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { for attr in &i.attrs { if attr.name() == "repr" { for item in attr.meta_item_list().unwrap_or(&[]) { - if item.name() == "simd" { + if item.check_name("simd") { gate_feature_post!(&self, repr_simd, i.span, "SIMD types are experimental \ and possibly buggy"); @@ -1154,13 +1178,14 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F } Some(list) => { for mi in list { - let name = if mi.is_word() { - mi.name() - } else { - span_err!(span_handler, mi.span, E0556, - "malformed feature, expected just one word"); - continue - }; + let name = if let Some(word) = mi.word() { + word.name() + } else { + span_err!(span_handler, mi.span, E0556, + "malformed feature, expected just one word"); + continue + }; + if let Some(&(_, _, _, setter)) = ACTIVE_FEATURES.iter() .find(|& &(n, _, _, _)| name == n) { *(setter(&mut features)) = true; |
