about summary refs log tree commit diff
path: root/src/libsyntax/feature_gate.rs
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-10-02 22:41:24 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-10-13 15:19:20 +0300
commit8a12c19171887ea6d7ff708db2e2581ceaf16c14 (patch)
tree2ff02dad84730da28dc96d487d96a442350ee320 /src/libsyntax/feature_gate.rs
parentbeda1f88a7d87cf994fe8e3a5b2fe126e31fcae9 (diff)
downloadrust-8a12c19171887ea6d7ff708db2e2581ceaf16c14.tar.gz
rust-8a12c19171887ea6d7ff708db2e2581ceaf16c14.zip
Test and gate empty structures and variants better
Diffstat (limited to 'src/libsyntax/feature_gate.rs')
-rw-r--r--src/libsyntax/feature_gate.rs38
1 files changed, 20 insertions, 18 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0b3af659a7b..66a422ce664 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -196,7 +196,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
     // allow `#[unwind]`
     ("unwind_attributes", "1.4.0", None, Active),
 
-    // allow empty structs/enum variants with braces
+    // allow empty structs and enum variants with braces
     ("braced_empty_structs", "1.5.0", None, Active),
 
     // allow overloading augmented assignment operations like `a += b`
@@ -486,6 +486,7 @@ pub struct Features {
     pub cfg_target_feature: bool,
     pub cfg_target_vendor: bool,
     pub augmented_assignments: bool,
+    pub braced_empty_structs: bool,
 }
 
 impl Features {
@@ -516,6 +517,7 @@ impl Features {
             cfg_target_feature: false,
             cfg_target_vendor: false,
             augmented_assignments: false,
+            braced_empty_structs: false,
         }
     }
 }
@@ -809,7 +811,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemStruct(ref def, _) => {
+            ast::ItemStruct(..) => {
                 if attr::contains_name(&i.attrs[..], "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
@@ -828,10 +830,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                         }
                     }
                 }
-                if def.fields.is_empty() && def.kind == ast::VariantKind::Dict {
-                    self.gate_feature("braced_empty_structs", i.span,
-                                      "empty structs with braces are unstable");
-                }
             }
 
             ast::ItemDefaultImpl(..) => {
@@ -859,6 +857,21 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
         visit::walk_item(self, i);
     }
 
+    fn visit_struct_def(&mut self, s: &'v ast::StructDef, _: ast::Ident,
+                        _: &'v ast::Generics, _: ast::NodeId, span: Span) {
+        if s.fields.is_empty() {
+            if s.kind == ast::VariantKind::Dict {
+                self.gate_feature("braced_empty_structs", span,
+                                  "empty structs and enum variants with braces are unstable");
+            } else if s.kind == ast::VariantKind::Tuple {
+                self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
+                                                          are not allowed, use unit structs and \
+                                                          enum variants instead");
+            }
+        }
+        visit::walk_struct_def(self, s)
+    }
+
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs,
                                                                      "link_name") {
@@ -881,12 +894,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                   "box expression syntax is experimental; \
                                    you can call `Box::new` instead.");
             }
-            ast::ExprStruct(_, ref fields, ref expr) => {
-                if fields.is_empty() && expr.is_none() {
-                    self.gate_feature("braced_empty_structs", e.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_expr(self, e);
@@ -911,12 +918,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                   pattern.span,
                                   "box pattern syntax is experimental");
             }
-            ast::PatStruct(_, ref fields, dotdot) => {
-                if fields.is_empty() && !dotdot {
-                    self.gate_feature("braced_empty_structs", pattern.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_pat(self, pattern)
@@ -1086,6 +1087,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
         cfg_target_feature: cx.has_feature("cfg_target_feature"),
         cfg_target_vendor: cx.has_feature("cfg_target_vendor"),
         augmented_assignments: cx.has_feature("augmented_assignments"),
+        braced_empty_structs: cx.has_feature("braced_empty_structs"),
     }
 }