]> git.lizzy.rs Git - rust.git/commitdiff
Add an error when declaring features that are stable in the current Rust edition
authorvarkor <github@varkor.com>
Thu, 2 Aug 2018 16:31:54 +0000 (17:31 +0100)
committervarkor <github@varkor.com>
Sun, 5 Aug 2018 14:54:49 +0000 (15:54 +0100)
src/libsyntax/diagnostic_list.rs
src/libsyntax/feature_gate.rs
src/test/ui/E0705.rs [new file with mode: 0644]
src/test/ui/E0705.stderr [new file with mode: 0644]

index 8534969c623bc5c906c0c40625b6a7435b33d7c2..bfbe9ef1fee46256ad562a30d28e972f7ef56102 100644 (file)
@@ -374,6 +374,20 @@ fn main() {}
 
 "##,
 
+E0705: r##"
+A `#![feature]` attribute was declared for a feature that is stable in
+the current edition.
+
+Erroneous code example:
+
+```compile_fail,E0705
+#![allow(rust_2018_preview)]
+#![feature(raw_identifiers)] // error: the feature `raw_identifiers` is
+                             // included in the Rust 2018 edition
+```
+
+"##,
+
 }
 
 register_diagnostics! {
index 833b6953dcd3c12e7a15ff3c88a34010261afce7..0014fd5ae48b304db39f6d3502102746d469ec04 100644 (file)
@@ -25,6 +25,7 @@
 use self::AttributeType::*;
 use self::AttributeGate::*;
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
 use ast::{self, NodeId, PatKind, RangeEnd};
 use attr;
@@ -1900,10 +1901,13 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
 
     let mut feature_checker = FeatureChecker::default();
 
-    for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
+    let mut edition_enabled_features = FxHashMap();
+
+    for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
         if let Some(f_edition) = f_edition {
             if f_edition <= crate_edition {
                 set(&mut features, DUMMY_SP);
+                edition_enabled_features.insert(Symbol::intern(name), crate_edition);
             }
         }
     }
@@ -1931,10 +1935,40 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
                 continue
             };
 
+            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
+                if *edition <= crate_edition {
+                    continue
+                }
+
+                for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
+                    if let Some(f_edition) = f_edition {
+                        if f_edition <= *edition {
+                            // FIXME(Manishearth) there is currently no way to set
+                            // lib features by edition
+                            set(&mut features, DUMMY_SP);
+                            edition_enabled_features.insert(Symbol::intern(name), *edition);
+                        }
+                    }
+                }
+
+                continue
+            }
+
             if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                set(&mut features, mi.span);
-                feature_checker.collect(&features, mi.span);
-                features.declared_lang_features.push((name, mi.span, None));
+                if let Some(edition) = edition_enabled_features.get(&name) {
+                    struct_span_err!(
+                        span_handler,
+                        mi.span,
+                        E0705,
+                        "the feature `{}` is included in the Rust {} edition",
+                        name,
+                        edition,
+                    ).emit();
+                } else {
+                    set(&mut features, mi.span);
+                    feature_checker.collect(&features, mi.span);
+                    features.declared_lang_features.push((name, mi.span, None));
+                }
                 continue
             }
 
@@ -1951,24 +1985,6 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
                 continue
             }
 
-            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
-                if *edition <= crate_edition {
-                    continue
-                }
-
-                for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
-                    if let Some(f_edition) = f_edition {
-                        if *edition >= f_edition {
-                            // FIXME(Manishearth) there is currently no way to set
-                            // lib features by edition
-                            set(&mut features, DUMMY_SP);
-                        }
-                    }
-                }
-
-                continue
-            }
-
             features.declared_lib_features.push((name, mi.span));
         }
     }
diff --git a/src/test/ui/E0705.rs b/src/test/ui/E0705.rs
new file mode 100644 (file)
index 0000000..743c108
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rust_2018_preview)]
+#![feature(raw_identifiers)]
+//~^ ERROR the feature `raw_identifiers` is included in the Rust 2018 edition
+
+fn main() {
+    let foo = 0;
+    let bar = r#foo;
+}
diff --git a/src/test/ui/E0705.stderr b/src/test/ui/E0705.stderr
new file mode 100644 (file)
index 0000000..cab443a
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0705]: the feature `raw_identifiers` is included in the Rust 2018 edition
+  --> $DIR/E0705.rs:12:12
+   |
+LL | #![feature(raw_identifiers)]
+   |            ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0705`.