]> git.lizzy.rs Git - rust.git/commitdiff
Allow tracking issues for lang features.
authorHuon Wilson <dbau.pp+github@gmail.com>
Fri, 4 Sep 2015 23:37:22 +0000 (16:37 -0700)
committerHuon Wilson <dbau.pp+github@gmail.com>
Tue, 8 Sep 2015 01:01:42 +0000 (11:01 +1000)
This is similar to the libs version, which allow an `issue` field in the
`#[unstable]` attribute.

cc #28244

12 files changed:
src/etc/featureck.py
src/librustc/middle/check_static_recursion.rs
src/librustc/middle/stability.rs
src/librustc_typeck/astconv.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/trace_macros.rs
src/libsyntax/feature_gate.rs
src/test/compile-fail/type-macros-fail.rs

index e82f00f3e7df53b3fd222c67ac7ffa73375fc529..c6f3bcdf9ec0b991a82d4889ba45c2c814ac237c 100644 (file)
@@ -47,20 +47,24 @@ with open(feature_gate_source, 'r') as f:
                 is_feature_line = True
 
         if is_feature_line:
-            line = line.replace("(", "").replace("),", "").replace(")", "")
+            # turn `    ("foo", "1.0.0", Some(10), Active)` into
+            # `"foo", "1.0.0", Some(10), Active`
+            line = line.strip(' ,()')
             parts = line.split(",")
-            if len(parts) != 3:
+            if len(parts) != 4:
                 print("error: unexpected number of components in line: " + original_line)
                 sys.exit(1)
             feature_name = parts[0].strip().replace('"', "")
             since = parts[1].strip().replace('"', "")
-            status = parts[2].strip()
+            issue = parts[2].strip()
+            status = parts[3].strip()
             assert len(feature_name) > 0
             assert len(since) > 0
+            assert len(issue) > 0
             assert len(status) > 0
 
             language_feature_names += [feature_name]
-            language_features += [(feature_name, since, status)]
+            language_features += [(feature_name, since, issue, status)]
 
 assert len(language_features) > 0
 
@@ -158,7 +162,7 @@ for f in language_features:
     status = "unstable"
     stable_since = None
 
-    if f[2] == "Accepted":
+    if f[3] == "Accepted":
         status = "stable"
     if status == "stable":
         stable_since = f[1]
index 84ea6902ca54a7f718e612114a25b745163b09a8..942d8313ec24ee566e289e853802ea97cd4f3823 100644 (file)
@@ -18,7 +18,7 @@
 
 use syntax::{ast};
 use syntax::codemap::Span;
-use syntax::feature_gate::emit_feature_err;
+use syntax::feature_gate::{GateIssue, emit_feature_err};
 use rustc_front::visit::Visitor;
 use rustc_front::visit;
 use rustc_front::hir;
@@ -143,7 +143,7 @@ fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
                 if !self.sess.features.borrow().static_recursion {
                     emit_feature_err(&self.sess.parse_sess.span_diagnostic,
                                      "static_recursion",
-                                     *self.root_span, "recursive static");
+                                     *self.root_span, GateIssue::Language, "recursive static");
                 }
             } else {
                 span_err!(self.sess, *self.root_span, E0265, "recursive constant");
index 08f8eb5685e8267df05d9598b0aa4377e2544da4..9c4697404201eac242c08128b6f458ce7aff2142 100644 (file)
@@ -22,7 +22,7 @@
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::ast;
 use syntax::ast::NodeId;
-use syntax::feature_gate::emit_feature_err;
+use syntax::feature_gate::{GateIssue, emit_feature_err};
 use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
 
 use rustc_front::hir;
@@ -294,18 +294,14 @@ fn check(&mut self, id: DefId, span: Span, stab: &Option<&Stability>) {
                 self.used_features.insert(feature.clone(), attr::Unstable);
 
                 if !self.active_features.contains(feature) {
-                    let mut msg = match *reason {
+                    let msg = match *reason {
                         Some(ref r) => format!("use of unstable library feature '{}': {}",
                                                &feature, &r),
                         None => format!("use of unstable library feature '{}'", &feature)
                     };
-                    if let Some(n) = issue {
-                        use std::fmt::Write;
-                        write!(&mut msg, " (see issue #{})", n).unwrap();
-                    }
 
                     emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
-                                      &feature, span, &msg);
+                                      &feature, span, GateIssue::Library(issue), &msg);
                 }
             }
             Some(&Stability { level, ref feature, .. }) => {
index e4c3926fba18bc3a2f611a61a7c62207e45710d0..6f2d8345142be18291878d469a96ad2e7a56f493 100644 (file)
@@ -70,7 +70,7 @@
 use std::slice;
 use syntax::{abi, ast};
 use syntax::codemap::{Span, Pos};
-use syntax::feature_gate::emit_feature_err;
+use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::parse::token;
 
 use rustc_front::print::pprust;
@@ -797,7 +797,7 @@ fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
                 emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
-                                 "unboxed_closures", span,
+                                 "unboxed_closures", span, GateIssue::Language,
                                  "\
                     the precise format of `Fn`-family traits' type parameters is \
                     subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
@@ -810,7 +810,7 @@ fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
                 emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
-                                 "unboxed_closures", span,
+                                 "unboxed_closures", span, GateIssue::Language,
                                  "\
                     parenthetical notation is only stable when used with `Fn`-family traits");
             }
index c48b740d83ae5b3e4830e6e91725c9d755a3b2a0..f1aa8139ec1df3a8b0abfde52cdc0450297298ae 100644 (file)
@@ -51,7 +51,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'cx> {
     if !cx.ecfg.enable_asm() {
         feature_gate::emit_feature_err(
-            &cx.parse_sess.span_diagnostic, "asm", sp, feature_gate::EXPLAIN_ASM);
+            &cx.parse_sess.span_diagnostic, "asm", sp,
+            feature_gate::GateIssue::Language,
+            feature_gate::EXPLAIN_ASM);
         return DummyResult::expr(sp);
     }
 
index 24436c4520db39518e329496a3735b4c02bfa4c1..c31a767300cf4949b052e3c3a4e0050fff4242ec 100644 (file)
@@ -23,6 +23,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
         feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
                                        "concat_idents",
                                        sp,
+                                       feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CONCAT_IDENTS);
         return base::DummyResult::expr(sp);
     }
index 36deaf488e15e0fda1cd31e01ba65e73593f7b93..c7f582854aeef0dd034fc1be93741fdec39e1967 100644 (file)
@@ -105,6 +105,7 @@ fn expand_derive(cx: &mut ExtCtxt,
                     feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
                                                    "custom_derive",
                                                    titem.span,
+                                                   feature_gate::GateIssue::Language,
                                                    feature_gate::EXPLAIN_CUSTOM_DERIVE);
                     continue;
                 }
index fd70dd175fc48d7c7b183d022e60c64e76a6da85..1991124ae2671bfc72a48be42c2788cbb6afa742 100644 (file)
@@ -778,6 +778,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                             &fld.cx.parse_sess.span_diagnostic,
                             "allow_internal_unstable",
                             it.span,
+                            feature_gate::GateIssue::Language,
                             feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
                     }
 
@@ -1469,7 +1470,8 @@ pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
                     &fld.cx.parse_sess.span_diagnostic,
                     "type_macros",
                     t.span,
-                    "type macros are experimental (see issue: #27336)");
+                    feature_gate::GateIssue::Language,
+                    "type macros are experimental");
 
                 DummyResult::raw_ty(t.span)
             }
index 9869108952c5e019090e0b461658ff63e2fccb46..5f7ce8d994172e0903295a21a5bfdd287f4c09ba 100644 (file)
@@ -22,6 +22,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
         feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
                                        "log_syntax",
                                        sp,
+                                       feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_LOG_SYNTAX);
         return base::DummyResult::any(sp);
     }
index 646e6fec405534de3f62a18ae55dc8f57b6ff83c..ab34f41d932d5027a70cc1ed2839f6d62a206feb 100644 (file)
@@ -24,6 +24,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
         feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
                                        "trace_macros",
                                        sp,
+                                       feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_TRACE_MACROS);
         return base::DummyResult::any(sp);
     }
index 0c0c68c89a10d4601ef9efe6dc363d28a7b803d0..b3004d65f02971e6a6fecd3e60c9dc0a915d79b7 100644 (file)
 // stable (active).
 // NB: The featureck.py script parses this information directly out of the source
 // so take care when modifying it.
-const 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),
-    ("plugin_registrar", "1.0.0", Active),
-    ("log_syntax", "1.0.0", Active),
-    ("trace_macros", "1.0.0", Active),
-    ("concat_idents", "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),
-    ("reflect", "1.0.0", Active),
-    ("import_shadowing", "1.0.0", Removed),
-    ("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", Accepted),
-    ("box_syntax", "1.0.0", Active),
-    ("placement_in_syntax", "1.0.0", Active),
-    ("pushpop_unsafe", "1.2.0", Active),
-    ("on_unimplemented", "1.0.0", Active),
-    ("simd_ffi", "1.0.0", Active),
-    ("allocator", "1.0.0", Active),
-    ("needs_allocator", "1.4.0", Active),
-    ("linked_from", "1.3.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),
-
-    ("fundamental", "1.0.0", Active),
+const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status)] = &[
+    ("globs", "1.0.0", None, Accepted),
+    ("macro_rules", "1.0.0", None, Accepted),
+    ("struct_variant", "1.0.0", None, Accepted),
+    ("asm", "1.0.0", None, Active),
+    ("managed_boxes", "1.0.0", None, Removed),
+    ("non_ascii_idents", "1.0.0", None, Active),
+    ("thread_local", "1.0.0", None, Active),
+    ("link_args", "1.0.0", None, Active),
+    ("plugin_registrar", "1.0.0", None, Active),
+    ("log_syntax", "1.0.0", None, Active),
+    ("trace_macros", "1.0.0", None, Active),
+    ("concat_idents", "1.0.0", None, Active),
+    ("intrinsics", "1.0.0", None, Active),
+    ("lang_items", "1.0.0", None, Active),
+
+    ("simd", "1.0.0", Some(27731), Active),
+    ("default_type_params", "1.0.0", None, Accepted),
+    ("quote", "1.0.0", None, Active),
+    ("link_llvm_intrinsics", "1.0.0", None, Active),
+    ("linkage", "1.0.0", None, Active),
+    ("struct_inherit", "1.0.0", None, Removed),
+
+    ("quad_precision_float", "1.0.0", None, Removed),
+
+    ("rustc_diagnostic_macros", "1.0.0", None, Active),
+    ("unboxed_closures", "1.0.0", None, Active),
+    ("reflect", "1.0.0", None, Active),
+    ("import_shadowing", "1.0.0", None, Removed),
+    ("advanced_slice_patterns", "1.0.0", None, Active),
+    ("tuple_indexing", "1.0.0", None, Accepted),
+    ("associated_types", "1.0.0", None, Accepted),
+    ("visible_private_types", "1.0.0", None, Active),
+    ("slicing_syntax", "1.0.0", None, Accepted),
+    ("box_syntax", "1.0.0", None, Active),
+    ("placement_in_syntax", "1.0.0", None, Active),
+    ("pushpop_unsafe", "1.2.0", None, Active),
+    ("on_unimplemented", "1.0.0", None, Active),
+    ("simd_ffi", "1.0.0", None, Active),
+    ("allocator", "1.0.0", None, Active),
+    ("needs_allocator", "1.4.0", None, Active),
+    ("linked_from", "1.3.0", None, Active),
+
+    ("if_let", "1.0.0", None, Accepted),
+    ("while_let", "1.0.0", None, Accepted),
+
+    ("plugin", "1.0.0", None, Active),
+    ("start", "1.0.0", None, Active),
+    ("main", "1.0.0", None, Active),
+
+    ("fundamental", "1.0.0", None, Active),
 
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
-    ("issue_5723_bootstrap", "1.0.0", Accepted),
+    ("issue_5723_bootstrap", "1.0.0", None, Accepted),
 
     // A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    ("opt_out_copy", "1.0.0", Removed),
+    ("opt_out_copy", "1.0.0", None, Removed),
 
     // OIBIT specific features
-    ("optin_builtin_traits", "1.0.0", Active),
+    ("optin_builtin_traits", "1.0.0", None, Active),
 
     // macro reexport needs more discussion and stabilization
-    ("macro_reexport", "1.0.0", Active),
+    ("macro_reexport", "1.0.0", None, Active),
 
     // These are used to test this portion of the compiler, they don't actually
     // mean anything
-    ("test_accepted_feature", "1.0.0", Accepted),
-    ("test_removed_feature", "1.0.0", Removed),
+    ("test_accepted_feature", "1.0.0", None, Accepted),
+    ("test_removed_feature", "1.0.0", None, Removed),
 
     // Allows use of #[staged_api]
-    ("staged_api", "1.0.0", Active),
+    ("staged_api", "1.0.0", None, Active),
 
     // Allows using items which are missing stability attributes
-    ("unmarked_api", "1.0.0", Active),
+    ("unmarked_api", "1.0.0", None, Active),
 
     // Allows using #![no_std]
-    ("no_std", "1.0.0", Active),
+    ("no_std", "1.0.0", None, Active),
 
     // Allows using #![no_core]
-    ("no_core", "1.3.0", Active),
+    ("no_core", "1.3.0", None, Active),
 
     // Allows using `box` in patterns; RFC 469
-    ("box_patterns", "1.0.0", Active),
+    ("box_patterns", "1.0.0", None, Active),
 
     // Allows using the unsafe_no_drop_flag attribute (unlikely to
     // switch to Accepted; see RFC 320)
-    ("unsafe_no_drop_flag", "1.0.0", Active),
+    ("unsafe_no_drop_flag", "1.0.0", None, Active),
 
     // Allows the use of custom attributes; RFC 572
-    ("custom_attribute", "1.0.0", Active),
+    ("custom_attribute", "1.0.0", None, Active),
 
     // Allows the use of #[derive(Anything)] as sugar for
     // #[derive_Anything].
-    ("custom_derive", "1.0.0", Active),
+    ("custom_derive", "1.0.0", None, Active),
 
     // Allows the use of rustc_* attributes; RFC 572
-    ("rustc_attrs", "1.0.0", Active),
+    ("rustc_attrs", "1.0.0", None, Active),
 
     // Allows the use of #[allow_internal_unstable]. This is an
     // attribute on macro_rules! and can't use the attribute handling
     // below (it has to be checked before expansion possibly makes
     // macros disappear).
-    ("allow_internal_unstable", "1.0.0", Active),
+    ("allow_internal_unstable", "1.0.0", None, Active),
 
     // #23121. Array patterns have some hazards yet.
-    ("slice_patterns", "1.0.0", Active),
+    ("slice_patterns", "1.0.0", None, Active),
 
     // Allows use of unary negate on unsigned integers, e.g. -e for e: u8
-    ("negate_unsigned", "1.0.0", Active),
+    ("negate_unsigned", "1.0.0", None, Active),
 
     // Allows the definition of associated constants in `trait` or `impl`
     // blocks.
-    ("associated_consts", "1.0.0", Active),
+    ("associated_consts", "1.0.0", None, Active),
 
     // Allows the definition of `const fn` functions.
-    ("const_fn", "1.2.0", Active),
+    ("const_fn", "1.2.0", None, Active),
 
     // Allows using #[prelude_import] on glob `use` items.
-    ("prelude_import", "1.2.0", Active),
+    ("prelude_import", "1.2.0", None, Active),
 
     // Allows the definition recursive static items.
-    ("static_recursion", "1.3.0", Active),
+    ("static_recursion", "1.3.0", None, Active),
 
     // Allows default type parameters to influence type inference.
-    ("default_type_parameter_fallback", "1.3.0", Active),
+    ("default_type_parameter_fallback", "1.3.0", None, Active),
 
     // Allows associated type defaults
-    ("associated_type_defaults", "1.2.0", Active),
+    ("associated_type_defaults", "1.2.0", None, Active),
     // Allows macros to appear in the type position.
 
-    ("type_macros", "1.3.0", Active),
+    ("type_macros", "1.3.0", Some(27336), Active),
 
     // allow `repr(simd)`, and importing the various simd intrinsics
-    ("repr_simd", "1.4.0", Active),
+    ("repr_simd", "1.4.0", Some(27731), Active),
 
     // Allows cfg(target_feature = "...").
-    ("cfg_target_feature", "1.4.0", Active),
+    ("cfg_target_feature", "1.4.0", None, Active),
 
     // allow `extern "platform-intrinsic" { ... }`
-    ("platform_intrinsics", "1.4.0", Active),
+    ("platform_intrinsics", "1.4.0", Some(27731), Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -386,7 +386,7 @@ pub fn check_and_emit(&self, diagnostic: &SpanHandler, features: &Features) {
         let (cfg, feature, has_feature) = GATED_CFGS[self.index];
         if !has_feature(features) {
             let explain = format!("`cfg({})` is experimental and subject to change", cfg);
-            emit_feature_err(diagnostic, feature, self.span, &explain);
+            emit_feature_err(diagnostic, feature, self.span, GateIssue::Language, &explain);
         }
     }
 }
@@ -488,21 +488,21 @@ pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span
     if let Some(&Features { allow_box: true, .. }) = f {
         return;
     }
-    emit_feature_err(diag, "box_syntax", span, EXPLAIN_BOX_SYNTAX);
+    emit_feature_err(diag, "box_syntax", span, GateIssue::Language, EXPLAIN_BOX_SYNTAX);
 }
 
 pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Span) {
     if let Some(&Features { allow_placement_in: true, .. }) = f {
         return;
     }
-    emit_feature_err(diag, "placement_in_syntax", span, EXPLAIN_PLACEMENT_IN);
+    emit_feature_err(diag, "placement_in_syntax", span, GateIssue::Language, EXPLAIN_PLACEMENT_IN);
 }
 
 pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
     if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f {
         return;
     }
-    emit_feature_err(diag, "pushpop_unsafe", span, EXPLAIN_PUSHPOP_UNSAFE);
+    emit_feature_err(diag, "pushpop_unsafe", span, GateIssue::Language, EXPLAIN_PUSHPOP_UNSAFE);
 }
 
 struct Context<'a> {
@@ -522,7 +522,7 @@ fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
         let has_feature = self.has_feature(feature);
         debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
         if !has_feature {
-            emit_feature_err(self.span_handler, feature, span, explain);
+            emit_feature_err(self.span_handler, feature, span, GateIssue::Language, explain);
         }
     }
     fn has_feature(&self, feature: &str) -> bool {
@@ -576,8 +576,35 @@ fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
     }
 }
 
-pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
-    diag.span_err(span, explain);
+fn find_lang_feature_issue(feature: &str) -> Option<u32> {
+    let info = KNOWN_FEATURES.iter()
+                              .find(|t| t.0 == feature)
+                              .unwrap();
+    let issue = info.2;
+    if let Active = info.3 {
+        // FIXME (#28244): enforce that active features have issue numbers
+        // assert!(issue.is_some())
+    }
+    issue
+}
+
+pub enum GateIssue {
+    Language,
+    Library(Option<u32>)
+}
+
+pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, issue: GateIssue,
+                        explain: &str) {
+    let issue = match issue {
+        GateIssue::Language => find_lang_feature_issue(feature),
+        GateIssue::Library(lib) => lib,
+    };
+
+    if let Some(n) = issue {
+        diag.span_err(span, &format!("{} (see issue #{})", explain, n));
+    } else {
+        diag.span_err(span, explain);
+    }
 
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
     if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; }
@@ -948,14 +975,14 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
                         }
                     };
                     match KNOWN_FEATURES.iter()
-                                        .find(|& &(n, _, _)| name == n) {
-                        Some(&(name, _, Active)) => {
+                                        .find(|& &(n, _, _, _)| name == n) {
+                        Some(&(name, _, _, Active)) => {
                             cx.enable_feature(name);
                         }
-                        Some(&(_, _, Removed)) => {
+                        Some(&(_, _, _, Removed)) => {
                             span_handler.span_err(mi.span, "feature has been removed");
                         }
-                        Some(&(_, _, Accepted)) => {
+                        Some(&(_, _, _, Accepted)) => {
                             accepted_features.push(mi.span);
                         }
                         None => {
index f854e540ee83de8449c5248786260b1e5ed71f4c..d51176a925d07de6fa96e52543a88263c91aa659 100644 (file)
@@ -14,7 +14,7 @@ macro_rules! Id {
 
 struct Foo<T> {
     x: Id!(T)
-    //~^ ERROR: type macros are experimental (see issue: #27336)
+    //~^ ERROR: type macros are experimental (see issue #27336)
 }
 
 fn main() {