about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/lint.rs52
1 files changed, 29 insertions, 23 deletions
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 363acb4f33e..d5a408fdfa6 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -55,6 +55,7 @@ impl LintLevelSource {
 #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
 pub struct LevelAndSource {
     pub level: Level,
+    pub lint_id: Option<LintExpectationId>,
     pub src: LintLevelSource,
 }
 
@@ -73,14 +74,18 @@ pub struct ShallowLintLevelMap {
 ///
 /// The return of this function is suitable for diagnostics.
 pub fn reveal_actual_level(
-    level: Option<Level>,
+    level: Option<(Level, Option<LintExpectationId>)>,
     src: &mut LintLevelSource,
     sess: &Session,
     lint: LintId,
-    probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
-) -> Level {
+    probe_for_lint_level: impl FnOnce(
+        LintId,
+    )
+        -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource),
+) -> (Level, Option<LintExpectationId>) {
     // If `level` is none then we actually assume the default level for this lint.
-    let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
+    let (mut level, mut lint_id) =
+        level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None));
 
     // If we're about to issue a warning, check at the last minute for any
     // directives against the warnings "lint". If, for example, there's an
@@ -92,16 +97,17 @@ pub fn reveal_actual_level(
     // future compatibility warning.
     if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
         let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
-        if let Some(configured_warning_level) = warnings_level {
+        if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
             if configured_warning_level != Level::Warn {
                 level = configured_warning_level;
+                lint_id = configured_lint_id;
                 *src = warnings_src;
             }
         }
     }
 
     // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
-    level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
+    level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src {
         level
     } else {
         cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
@@ -112,7 +118,7 @@ pub fn reveal_actual_level(
         level = cmp::min(*driver_level, level);
     }
 
-    level
+    (level, lint_id)
 }
 
 impl ShallowLintLevelMap {
@@ -125,11 +131,11 @@ impl ShallowLintLevelMap {
         tcx: TyCtxt<'_>,
         id: LintId,
         start: HirId,
-    ) -> (Option<Level>, LintLevelSource) {
+    ) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
         if let Some(map) = self.specs.get(&start.local_id)
-            && let Some(&LevelAndSource { level, src }) = map.get(&id)
+            && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
         {
-            return (Some(level), src);
+            return (Some((level, lint_id)), src);
         }
 
         let mut owner = start.owner;
@@ -141,9 +147,9 @@ impl ShallowLintLevelMap {
                 specs = &tcx.shallow_lint_levels_on(owner).specs;
             }
             if let Some(map) = specs.get(&parent.local_id)
-                && let Some(&LevelAndSource { level, src }) = map.get(&id)
+                && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
             {
-                return (Some(level), src);
+                return (Some((level, lint_id)), src);
             }
         }
 
@@ -159,10 +165,10 @@ impl ShallowLintLevelMap {
         cur: HirId,
     ) -> LevelAndSource {
         let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
-        let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
+        let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
             self.probe_for_lint_level(tcx, lint, cur)
         });
-        LevelAndSource { level, src }
+        LevelAndSource { level, lint_id, src }
     }
 }
 
@@ -285,7 +291,7 @@ pub fn lint_level(
         span: Option<MultiSpan>,
         decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
     ) {
-        let LevelAndSource { level, src } = level;
+        let LevelAndSource { level, lint_id, src } = level;
 
         // Check for future incompatibility lints and issue a stronger warning.
         let future_incompatible = lint.future_incompatible;
@@ -297,15 +303,15 @@ pub fn lint_level(
         );
 
         // Convert lint level to error level.
-        let (err_level, lint_id) = match level {
+        let err_level = match level {
             Level::Allow => {
                 if has_future_breakage {
-                    (rustc_errors::Level::Allow, None)
+                    rustc_errors::Level::Allow
                 } else {
                     return;
                 }
             }
-            Level::Expect(expect_id) => {
+            Level::Expect => {
                 // This case is special as we actually allow the lint itself in this context, but
                 // we can't return early like in the case for `Level::Allow` because we still
                 // need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`.
@@ -313,11 +319,11 @@ pub fn lint_level(
                 // We can also not mark the lint expectation as fulfilled here right away, as it
                 // can still be cancelled in the decorate function. All of this means that we simply
                 // create a `Diag` and continue as we would for warnings.
-                (rustc_errors::Level::Expect, Some(expect_id))
+                rustc_errors::Level::Expect
             }
-            Level::ForceWarn(expect_id) => (rustc_errors::Level::ForceWarning, expect_id),
-            Level::Warn => (rustc_errors::Level::Warning, None),
-            Level::Deny | Level::Forbid => (rustc_errors::Level::Error, None),
+            Level::ForceWarn => rustc_errors::Level::ForceWarning,
+            Level::Warn => rustc_errors::Level::Warning,
+            Level::Deny | Level::Forbid => rustc_errors::Level::Error,
         };
         let mut err = Diag::new(sess.dcx(), err_level, "");
         if let Some(span) = span {
@@ -356,7 +362,7 @@ pub fn lint_level(
         // the compiler. It is therefore not necessary to add any information for the user.
         // This will therefore directly call the decorate function which will in turn emit
         // the diagnostic.
-        if let Level::Expect(_) = level {
+        if let Level::Expect = level {
             decorate(&mut err);
             err.emit();
             return;