]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/feature_gate.rs
Rollup merge of #53413 - eddyb:featured-in-the-latest-edition, r=varkor
[rust.git] / src / libsyntax / feature_gate.rs
index 395e5c98652326091ed5ce6f79d573698426722c..7a8a7b073185a6477dfeb8fdbb73dec1995d1202 100644 (file)
@@ -1930,7 +1930,15 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
     let mut features = Features::new();
     let mut edition_enabled_features = FxHashMap();
 
-    for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
+    for &edition in ALL_EDITIONS {
+        if edition <= crate_edition {
+            // The `crate_edition` implies its respective umbrella feature-gate
+            // (i.e. `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
+            edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition);
+        }
+    }
+
+    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
         if let Some(f_edition) = f_edition {
             if f_edition <= crate_edition {
                 set(&mut features, DUMMY_SP);
@@ -1939,6 +1947,8 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         }
     }
 
+    // Process the edition umbrella feature-gates first, to ensure
+    // `edition_enabled_features` is completed before it's queried.
     for attr in krate_attrs {
         if !attr.check_name("feature") {
             continue
@@ -1946,19 +1956,13 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
 
         let list = match attr.meta_item_list() {
             Some(list) => list,
-            None => {
-                span_err!(span_handler, attr.span, E0555,
-                          "malformed feature attribute, expected #![feature(...)]");
-                continue
-            }
+            None => continue,
         };
 
         for mi in list {
             let name = if let Some(word) = mi.word() {
                 word.name()
             } else {
-                span_err!(span_handler, mi.span, E0556,
-                          "malformed feature, expected just one word");
                 continue
             };
 
@@ -1974,10 +1978,10 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
 
             if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
                 if *edition <= crate_edition {
-                    continue
+                    continue;
                 }
 
-                for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
+                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
                     if let Some(f_edition) = f_edition {
                         if f_edition <= *edition {
                             // FIXME(Manishearth) there is currently no way to set
@@ -1987,24 +1991,53 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
                         }
                     }
                 }
+            }
+        }
+    }
+
+    for attr in krate_attrs {
+        if !attr.check_name("feature") {
+            continue
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => {
+                span_err!(span_handler, attr.span, E0555,
+                          "malformed feature attribute, expected #![feature(...)]");
+                continue
+            }
+        };
 
+        for mi in list {
+            let name = if let Some(word) = mi.word() {
+                word.name()
+            } else {
+                span_err!(span_handler, mi.span, E0556,
+                          "malformed feature, expected just one word");
                 continue
+            };
+
+            if let Some(edition) = edition_enabled_features.get(&name) {
+                struct_span_warn!(
+                    span_handler,
+                    mi.span,
+                    E0705,
+                    "the feature `{}` is included in the Rust {} edition",
+                    name,
+                    edition,
+                ).emit();
+                continue;
+            }
+
+            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
+                // Handled in the separate loop above.
+                continue;
             }
 
             if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                if let Some(edition) = edition_enabled_features.get(&name) {
-                    struct_span_warn!(
-                        span_handler,
-                        mi.span,
-                        E0705,
-                        "the feature `{}` is included in the Rust {} edition",
-                        name,
-                        edition,
-                    ).emit();
-                } else {
-                    set(&mut features, mi.span);
-                    features.declared_lang_features.push((name, mi.span, None));
-                }
+                set(&mut features, mi.span);
+                features.declared_lang_features.push((name, mi.span, None));
                 continue
             }