about summary refs log tree commit diff
path: root/src/libsyntax/feature_gate.rs
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-08-28 10:38:19 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-08-28 10:38:19 +0000
commit6303640e856dc3cccea655df104203649b5efd76 (patch)
tree7cb01f242a73cfc7c319708e1674b58eb8a7b4f5 /src/libsyntax/feature_gate.rs
parent413ecdee30d76eeed574bc9af547b539bc511863 (diff)
parent8250a26b5bcea9190ac63e756c35d8a54bf9da0c (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.rs51
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;