about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-08-02 17:31:54 +0100
committervarkor <github@varkor.com>2018-08-05 15:54:49 +0100
commit60ad63640f61c457e94fefa72f0ece65c6a6edd5 (patch)
treec38007268ecbc3ff83d0fa264d3986488a815a42 /src/libsyntax
parentd19832105e60195d82326a2468956f4d6a79f460 (diff)
downloadrust-60ad63640f61c457e94fefa72f0ece65c6a6edd5.tar.gz
rust-60ad63640f61c457e94fefa72f0ece65c6a6edd5.zip
Add an error when declaring features that are stable in the current Rust edition
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/diagnostic_list.rs14
-rw-r--r--src/libsyntax/feature_gate.rs60
2 files changed, 52 insertions, 22 deletions
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 8534969c623..bfbe9ef1fee 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -374,6 +374,20 @@ and likely to change in the future.
 
 "##,
 
+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! {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 833b6953dcd..0014fd5ae48 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -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 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
 
     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 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 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 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 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));
         }
     }