about summary refs log tree commit diff
path: root/src/libsyntax/feature_gate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/feature_gate.rs')
-rw-r--r--src/libsyntax/feature_gate.rs141
1 files changed, 77 insertions, 64 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index a5a2935d808..43af53aa2d2 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -17,6 +17,10 @@
 //!
 //! Features are enabled in programs via the crate-level attributes of
 //! `#![feature(...)]` with a comma-separated list of features.
+//!
+//! For the purpose of future feature-tracking, once code for detection of feature
+//! gate usage is added, *do not remove it again* even once the feature
+//! becomes stable.
 use self::Status::*;
 
 use abi::RustIntrinsic;
@@ -33,77 +37,82 @@ use parse::token::{self, InternedString};
 use std::slice;
 use std::ascii::AsciiExt;
 
-
-// if you change this list without updating src/doc/reference.md, @cmr will be sad
-static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
-    ("globs", Accepted),
-    ("macro_rules", Accepted),
-    ("struct_variant", Accepted),
-    ("asm", Active),
-    ("managed_boxes", Removed),
-    ("non_ascii_idents", Active),
-    ("thread_local", Active),
-    ("link_args", Active),
-    ("phase", Removed),
-    ("plugin_registrar", Active),
-    ("log_syntax", Active),
-    ("trace_macros", Active),
-    ("concat_idents", Active),
-    ("unsafe_destructor", Active),
-    ("intrinsics", Active),
-    ("lang_items", Active),
-
-    ("simd", Active),
-    ("default_type_params", Accepted),
-    ("quote", Active),
-    ("link_llvm_intrinsics", Active),
-    ("linkage", Active),
-    ("struct_inherit", Removed),
-
-    ("quad_precision_float", Removed),
-
-    ("rustc_diagnostic_macros", Active),
-    ("unboxed_closures", Active),
-    ("import_shadowing", Active),
-    ("advanced_slice_patterns", Active),
-    ("tuple_indexing", Accepted),
-    ("associated_types", Accepted),
-    ("visible_private_types", Active),
-    ("slicing_syntax", Active),
-    ("box_syntax", Active),
-    ("on_unimplemented", Active),
-    ("simd_ffi", Active),
-
-    ("if_let", Accepted),
-    ("while_let", Accepted),
-
-    ("plugin", Active),
-    ("start", Active),
-    ("main", Active),
+// If you change this list without updating src/doc/reference.md, @cmr will be sad
+// Don't ever remove anything from this list; set them to 'Removed'.
+// The version numbers here correspond to the version in which the current status
+// was set. This is most important for knowing when a particular feature became
+// stable (active).
+// NB: The featureck.py script parses this information directly out of the source
+// so take care when modifying it.
+static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
+    ("globs", "1.0.0", Accepted),
+    ("macro_rules", "1.0.0", Accepted),
+    ("struct_variant", "1.0.0", Accepted),
+    ("asm", "1.0.0", Active),
+    ("managed_boxes", "1.0.0", Removed),
+    ("non_ascii_idents", "1.0.0", Active),
+    ("thread_local", "1.0.0", Active),
+    ("link_args", "1.0.0", Active),
+    ("phase", "1.0.0", Removed),
+    ("plugin_registrar", "1.0.0", Active),
+    ("log_syntax", "1.0.0", Active),
+    ("trace_macros", "1.0.0", Active),
+    ("concat_idents", "1.0.0", Active),
+    ("unsafe_destructor", "1.0.0", Active),
+    ("intrinsics", "1.0.0", Active),
+    ("lang_items", "1.0.0", Active),
+
+    ("simd", "1.0.0", Active),
+    ("default_type_params", "1.0.0", Accepted),
+    ("quote", "1.0.0", Active),
+    ("link_llvm_intrinsics", "1.0.0", Active),
+    ("linkage", "1.0.0", Active),
+    ("struct_inherit", "1.0.0", Removed),
+
+    ("quad_precision_float", "1.0.0", Removed),
+
+    ("rustc_diagnostic_macros", "1.0.0", Active),
+    ("unboxed_closures", "1.0.0", Active),
+    ("import_shadowing", "1.0.0", Active),
+    ("advanced_slice_patterns", "1.0.0", Active),
+    ("tuple_indexing", "1.0.0", Accepted),
+    ("associated_types", "1.0.0", Accepted),
+    ("visible_private_types", "1.0.0", Active),
+    ("slicing_syntax", "1.0.0", Active),
+    ("box_syntax", "1.0.0", Active),
+    ("on_unimplemented", "1.0.0", Active),
+    ("simd_ffi", "1.0.0", Active),
+
+    ("if_let", "1.0.0", Accepted),
+    ("while_let", "1.0.0", Accepted),
+
+    ("plugin", "1.0.0", Active),
+    ("start", "1.0.0", Active),
+    ("main", "1.0.0", Active),
 
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
-    ("issue_5723_bootstrap", Accepted),
+    ("issue_5723_bootstrap", "1.0.0", Accepted),
 
     // A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    ("opt_out_copy", Removed),
+    ("opt_out_copy", "1.0.0", Removed),
 
     // A way to temporarily opt out of the new orphan rules. This will *never* be accepted.
-    ("old_orphan_check", Deprecated),
+    ("old_orphan_check", "1.0.0", Deprecated),
 
     // A way to temporarily opt out of the new impl rules. This will *never* be accepted.
-    ("old_impl_check", Deprecated),
+    ("old_impl_check", "1.0.0", Deprecated),
 
     // OIBIT specific features
-    ("optin_builtin_traits", Active),
+    ("optin_builtin_traits", "1.0.0", Active),
 
     // int and uint are now deprecated
-    ("int_uint", Active),
+    ("int_uint", "1.0.0", Active),
 
     // These are used to test this portion of the compiler, they don't actually
     // mean anything
-    ("test_accepted_feature", Accepted),
-    ("test_removed_feature", Removed),
+    ("test_accepted_feature", "1.0.0", Accepted),
+    ("test_removed_feature", "1.0.0", Removed),
 ];
 
 enum Status {
@@ -164,10 +173,7 @@ impl<'a> Context<'a> {
 
     fn warn_feature(&self, feature: &str, span: Span, explain: &str) {
         if !self.has_feature(feature) {
-            self.span_handler.span_warn(span, explain);
-            self.span_handler.span_help(span, &format!("add #![feature({})] to the \
-                                                       crate attributes to silence this warning",
-                                                      feature)[]);
+            emit_feature_warn(self.span_handler, feature, span, explain);
         }
     }
     fn has_feature(&self, feature: &str) -> bool {
@@ -182,6 +188,13 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain:
                                   feature)[]);
 }
 
+pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
+    diag.span_warn(span, explain);
+    diag.span_help(span, &format!("add #![feature({})] to the \
+                                   crate attributes to silence this warning",
+                                   feature)[]);
+}
+
 struct MacroVisitor<'a> {
     context: &'a Context<'a>
 }
@@ -510,21 +523,21 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
                         }
                     };
                     match KNOWN_FEATURES.iter()
-                                        .find(|& &(n, _)| name == n) {
-                        Some(&(name, Active)) => {
+                                        .find(|& &(n, _, _)| name == n) {
+                        Some(&(name, _, Active)) => {
                             cx.features.push(name);
                         }
-                        Some(&(name, Deprecated)) => {
+                        Some(&(name, _, Deprecated)) => {
                             cx.features.push(name);
                             span_handler.span_warn(
                                 mi.span,
                                 "feature is deprecated and will only be available \
                                  for a limited time, please rewrite code that relies on it");
                         }
-                        Some(&(_, Removed)) => {
+                        Some(&(_, _, Removed)) => {
                             span_handler.span_err(mi.span, "feature has been removed");
                         }
-                        Some(&(_, Accepted)) => {
+                        Some(&(_, _, Accepted)) => {
                             span_handler.span_warn(mi.span, "feature has been added to Rust, \
                                                              directive not necessary");
                         }