]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #83722 - jyn514:stable-help, r=estebank
authorbors <bors@rust-lang.org>
Sat, 24 Apr 2021 02:25:54 +0000 (02:25 +0000)
committerbors <bors@rust-lang.org>
Sat, 24 Apr 2021 02:25:54 +0000 (02:25 +0000)
On stable, suggest removing `#![feature]` for features that have been stabilized

I don't know how to test this (https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Run.20tests.20without.20enabling.20nightly.20features.3F). I confirmed locally that this gives the
appropriate help with `channel = "beta"`:

```
error[E0554]: `#![feature]` may not be used on the beta release channel
 --> src/lib.rs:2:1
  |
2 | #![feature(min_const_generics)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attribute
  |
  = help: the feature `min_const_generics` has been stable since 1.51.0 and no longer requires an attribute to enable

error[E0554]: `#![feature]` may not be used on the beta release channel
 --> src/lib.rs:3:1
  |
3 | #![feature(min_const_generics, min_specialization)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: the feature `min_const_generics` has been stable since 1.51.0 and no longer requires an attribute to enable

error[E0554]: `#![feature]` may not be used on the beta release channel
 --> src/lib.rs:4:1
  |
4 | #![feature(box_patterns)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
```

Closes https://github.com/rust-lang/rust/issues/83715.

compiler/rustc_ast_passes/src/feature_gate.rs

index c803c8a83b15c54e223e36c08c05f08ca7808e47..0679ccabe726c76c0f6178565f15d2894bdfe619 100644 (file)
@@ -727,16 +727,46 @@ macro_rules! gate_all {
 }
 
 fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
+    use rustc_errors::Applicability;
+
     if !sess.opts.unstable_features.is_nightly_build() {
+        let lang_features = &sess.features_untracked().declared_lang_features;
         for attr in krate.attrs.iter().filter(|attr| sess.check_name(attr, sym::feature)) {
-            struct_span_err!(
+            let mut err = struct_span_err!(
                 sess.parse_sess.span_diagnostic,
                 attr.span,
                 E0554,
                 "`#![feature]` may not be used on the {} release channel",
                 option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)")
-            )
-            .emit();
+            );
+            let mut all_stable = true;
+            for ident in
+                attr.meta_item_list().into_iter().flatten().map(|nested| nested.ident()).flatten()
+            {
+                let name = ident.name;
+                let stable_since = lang_features
+                    .iter()
+                    .flat_map(|&(feature, _, since)| if feature == name { since } else { None })
+                    .next();
+                if let Some(since) = stable_since {
+                    err.help(&format!(
+                        "the feature `{}` has been stable since {} and no longer requires \
+                                  an attribute to enable",
+                        name, since
+                    ));
+                } else {
+                    all_stable = false;
+                }
+            }
+            if all_stable {
+                err.span_suggestion(
+                    attr.span,
+                    "remove the attribute",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+            }
+            err.emit();
         }
     }
 }