about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-06-07 15:33:42 +0200
committerGitHub <noreply@github.com>2020-06-07 15:33:42 +0200
commit1ff0ba03ef71abf1f744d9acba6d9b3c82c9764b (patch)
tree80669d163f2a59e816938dcc5b103bdf7c8ab430
parentcbab74528acb244a146c6bc0754efca5f0e9e5a7 (diff)
parente7e6bc1126884fb20233b1be104af6458cad7c76 (diff)
downloadrust-1ff0ba03ef71abf1f744d9acba6d9b3c82c9764b.tar.gz
rust-1ff0ba03ef71abf1f744d9acba6d9b3c82c9764b.zip
Rollup merge of #72970 - OddCoincidence:feature-gated-lints, r=petrochenkov
Properly handle feature-gated lints

Closes #72694
-rw-r--r--src/librustc_lint/levels.rs29
-rw-r--r--src/librustc_session/lint.rs10
-rw-r--r--src/librustc_session/lint/builtin.rs2
-rw-r--r--src/librustdoc/core.rs9
4 files changed, 29 insertions, 21 deletions
diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs
index 3d2ddf12a0a..05e7c9a0c78 100644
--- a/src/librustc_lint/levels.rs
+++ b/src/librustc_lint/levels.rs
@@ -214,9 +214,9 @@ impl<'s> LintLevelsBuilder<'s> {
                 match store.check_lint_name(&name.as_str(), tool_name) {
                     CheckLintNameResult::Ok(ids) => {
                         let src = LintSource::Node(name, li.span(), reason);
-                        for id in ids {
-                            self.check_gated_lint(*id, attr.span);
-                            specs.insert(*id, (level, src));
+                        for &id in ids {
+                            self.check_gated_lint(id, attr.span);
+                            specs.insert(id, (level, src));
                         }
                     }
 
@@ -386,17 +386,18 @@ impl<'s> LintLevelsBuilder<'s> {
         BuilderPush { prev, changed: prev != self.cur }
     }
 
-    fn check_gated_lint(&self, id: LintId, span: Span) {
-        if id == LintId::of(builtin::UNSAFE_OP_IN_UNSAFE_FN)
-            && !self.sess.features_untracked().unsafe_block_in_unsafe_fn
-        {
-            feature_err(
-                &self.sess.parse_sess,
-                sym::unsafe_block_in_unsafe_fn,
-                span,
-                "the `unsafe_op_in_unsafe_fn` lint is unstable",
-            )
-            .emit();
+    /// Checks if the lint is gated on a feature that is not enabled.
+    fn check_gated_lint(&self, lint_id: LintId, span: Span) {
+        if let Some(feature) = lint_id.lint.feature_gate {
+            if !self.sess.features_untracked().enabled(feature) {
+                feature_err(
+                    &self.sess.parse_sess,
+                    feature,
+                    span,
+                    &format!("the `{}` lint is unstable", lint_id.lint.name_lower()),
+                )
+                .emit();
+            }
         }
     }
 
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 8a66fac1e36..ffb45793090 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -85,6 +85,9 @@ pub struct Lint {
     pub future_incompatible: Option<FutureIncompatibleInfo>,
 
     pub is_plugin: bool,
+
+    /// `Some` if this lint is feature gated, otherwise `None`.
+    pub feature_gate: Option<Symbol>,
 }
 
 /// Extra information for a future incompatibility lint.
@@ -107,6 +110,7 @@ impl Lint {
             is_plugin: false,
             report_in_external_macro: false,
             future_incompatible: None,
+            feature_gate: None,
         }
     }
 
@@ -276,7 +280,9 @@ macro_rules! declare_lint {
         );
     );
     ($vis: vis $NAME: ident, $Level: ident, $desc: expr,
-     $(@future_incompatible = $fi:expr;)? $($v:ident),*) => (
+     $(@future_incompatible = $fi:expr;)?
+     $(@feature_gate = $gate:expr;)?
+     $($v:ident),*) => (
         $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
             name: stringify!($NAME),
             default_level: $crate::lint::$Level,
@@ -285,6 +291,7 @@ macro_rules! declare_lint {
             is_plugin: false,
             $($v: true,)*
             $(future_incompatible: Some($fi),)*
+            $(feature_gate: Some($gate),)*
             ..$crate::lint::Lint::default_fields_for_macro()
         };
     );
@@ -328,6 +335,7 @@ macro_rules! declare_tool_lint {
             report_in_external_macro: $external,
             future_incompatible: None,
             is_plugin: true,
+            feature_gate: None,
         };
     );
 }
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
index 7112ac35b08..bb0d6e1a47e 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -7,6 +7,7 @@
 use crate::lint::FutureIncompatibleInfo;
 use crate::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
+use rustc_span::symbol::sym;
 
 declare_lint! {
     pub ILL_FORMED_ATTRIBUTE_INPUT,
@@ -530,6 +531,7 @@ declare_lint! {
     pub UNSAFE_OP_IN_UNSAFE_FN,
     Allow,
     "unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
+    @feature_gate = sym::unsafe_block_in_unsafe_fn;
 }
 
 declare_lint_pass! {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 06293a98712..1690b946bb6 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -225,11 +225,6 @@ where
 {
     let warnings_lint_name = lint::builtin::WARNINGS.name;
 
-    // Whitelist feature-gated lints to avoid feature errors when trying to
-    // allow all lints.
-    // FIXME(#72694): handle feature-gated lints properly.
-    let unsafe_op_in_unsafe_fn_name = rustc_lint::builtin::UNSAFE_OP_IN_UNSAFE_FN.name;
-
     whitelisted_lints.push(warnings_lint_name.to_owned());
     whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
 
@@ -241,7 +236,9 @@ where
 
     let lint_opts = lints()
         .filter_map(|lint| {
-            if lint.name == warnings_lint_name || lint.name == unsafe_op_in_unsafe_fn_name {
+            // Whitelist feature-gated lints to avoid feature errors when trying to
+            // allow all lints.
+            if lint.name == warnings_lint_name || lint.feature_gate.is_some() {
                 None
             } else {
                 filter_call(lint)