]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/front/feature_gate.rs
Doc says to avoid mixing allocator instead of forbiding it
[rust.git] / src / librustc / front / feature_gate.rs
index 2305434726599d0d4968f8c12d14be30a8e1cdde..13a40aba93078321db65640e5d255ffc975e672a 100644 (file)
@@ -33,6 +33,7 @@
 use driver::session::Session;
 
 use std::cell::Cell;
+use std::slice;
 
 /// This is a list of all known features since the beginning of time. This list
 /// can never shrink, it may only be expanded (in order to prevent old programs
@@ -69,6 +70,8 @@
     ("rustc_diagnostic_macros", Active),
     ("unboxed_closures", Active),
     ("import_shadowing", Active),
+    ("advanced_slice_patterns", Active),
+    ("tuple_indexing", Active),
 
     // if you change this list without updating src/doc/rust.md, cmr will be sad
 
@@ -141,15 +144,15 @@ fn has_feature(&self, feature: &str) -> bool {
     }
 }
 
-impl<'a> Visitor<()> for Context<'a> {
-    fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
+impl<'a, 'v> Visitor<'v> for Context<'a> {
+    fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
         if !token::get_ident(id).get().is_ascii() {
             self.gate_feature("non_ascii_idents", sp,
                               "non-ascii idents are not fully supported.");
         }
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
+    fn visit_view_item(&mut self, i: &ast::ViewItem) {
         match i.node {
             ast::ViewItemUse(ref path) => {
                 match path.node {
@@ -171,10 +174,10 @@ fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
                 }
             }
         }
-        visit::walk_view_item(self, i, ())
+        visit::walk_view_item(self, i)
     }
 
-    fn visit_item(&mut self, i: &ast::Item, _:()) {
+    fn visit_item(&mut self, i: &ast::Item) {
         for attr in i.attrs.iter() {
             if attr.name().equiv(&("thread_local")) {
                 self.gate_feature("thread_local", i.span,
@@ -218,7 +221,7 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
                 }
             }
 
-            ast::ItemStruct(struct_definition, _) => {
+            ast::ItemStruct(ref struct_definition, _) => {
                 if attr::contains_name(i.attrs.as_slice(), "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
@@ -250,10 +253,10 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
             _ => {}
         }
 
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 
-    fn visit_mac(&mut self, macro: &ast::Mac, _: ()) {
+    fn visit_mac(&mut self, macro: &ast::Mac) {
         let ast::MacInvocTT(ref path, _, _) = macro.node;
         let id = path.segments.last().unwrap().identifier;
         let quotes = ["quote_tokens", "quote_expr", "quote_ty",
@@ -297,18 +300,18 @@ fn visit_mac(&mut self, macro: &ast::Mac, _: ()) {
         }
     }
 
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         if attr::contains_name(i.attrs.as_slice(), "linkage") {
             self.gate_feature("linkage", i.span,
                               "the `linkage` attribute is experimental \
                                and not portable across platforms")
         }
-        visit::walk_foreign_item(self, i, ())
+        visit::walk_foreign_item(self, i)
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
-            ast::TyClosure(closure) if closure.onceness == ast::Once => {
+            ast::TyClosure(ref closure) if closure.onceness == ast::Once => {
                 self.gate_feature("once_fns", t.span,
                                   "once functions are \
                                    experimental and likely to be removed");
@@ -323,10 +326,10 @@ fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
             _ => {}
         }
 
-        visit::walk_ty(self, t, ());
+        visit::walk_ty(self, t);
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprUnary(ast::UnBox, _) => {
                 self.gate_box(e.span);
@@ -337,15 +340,20 @@ fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
                                   "unboxed closures are a work-in-progress \
                                    feature with known bugs");
             }
+            ast::ExprTupField(..) => {
+                self.gate_feature("tuple_indexing",
+                                  e.span,
+                                  "tuple indexing is experimental");
+            }
             _ => {}
         }
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
+    fn visit_generics(&mut self, generics: &ast::Generics) {
         for type_parameter in generics.ty_params.iter() {
             match type_parameter.default {
-                Some(ty) => {
+                Some(ref ty) => {
                     self.gate_feature("default_type_params", ty.span,
                                       "default type parameters are \
                                        experimental and possibly buggy");
@@ -353,33 +361,46 @@ fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
                 None => {}
             }
         }
-        visit::walk_generics(self, generics, ());
+        visit::walk_generics(self, generics);
     }
 
-    fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
-        if attr::contains_name([*attr], "lang") {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
+        if attr::contains_name(slice::ref_slice(attr), "lang") {
             self.gate_feature("lang_items",
                               attr.span,
                               "language items are subject to change");
         }
     }
 
+    fn visit_pat(&mut self, pattern: &ast::Pat) {
+        match pattern.node {
+            ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
+                self.gate_feature("advanced_slice_patterns",
+                                  pattern.span,
+                                  "multiple-element slice matches anywhere \
+                                   but at the end of a slice (e.g. \
+                                   `[0, ..xs, 0]` are experimental")
+            }
+            _ => {}
+        }
+        visit::walk_pat(self, pattern)
+    }
+
     fn visit_fn(&mut self,
-                fn_kind: &visit::FnKind,
-                fn_decl: &ast::FnDecl,
-                block: &ast::Block,
+                fn_kind: visit::FnKind<'v>,
+                fn_decl: &'v ast::FnDecl,
+                block: &'v ast::Block,
                 span: Span,
-                _: NodeId,
-                (): ()) {
-        match *fn_kind {
-            visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
+                _: NodeId) {
+        match fn_kind {
+            visit::FkItemFn(_, _, _, abi) if abi == RustIntrinsic => {
                 self.gate_feature("intrinsics",
                                   span,
                                   "intrinsics are subject to change")
             }
             _ => {}
         }
-        visit::walk_fn(self, fn_kind, fn_decl, block, span, ());
+        visit::walk_fn(self, fn_kind, fn_decl, block, span);
     }
 }
 
@@ -400,7 +421,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
                                           expected #![feature(...)]");
             }
             Some(list) => {
-                for &mi in list.iter() {
+                for mi in list.iter() {
                     let name = match mi.node {
                         ast::MetaWord(ref word) => (*word).clone(),
                         _ => {
@@ -432,7 +453,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
         }
     }
 
-    visit::walk_crate(&mut cx, krate, ());
+    visit::walk_crate(&mut cx, krate);
 
     sess.abort_if_errors();