diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 2b1a8132e65e8..7705b3ef7ccbc 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -28,9 +28,9 @@ use crate::lifetime_syntax::LifetimeSyntaxCategories; #[diag("{$lint_level}({$lint_name}) incompatible with previous forbid", code = E0453)] pub(crate) struct OverruledAttribute<'a> { #[primary_span] - pub span: Span, + pub span: Option, #[label("overruled by previous forbid")] - pub overruled: Span, + pub overruled: Option, pub lint_level: &'a str, pub lint_name: LintName, #[subdiagnostic] diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index fd9a4ee74f5d7..df00093f4453d 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -539,16 +539,16 @@ where continue; }; for &id in ids { - // ForceWarn and Forbid cannot be overridden + // ForceWarn cannot be overridden if let Some(level_spec) = self.provider.current_specs().get(&id) - && matches!(level_spec.level(), Level::ForceWarn | Level::Forbid) + && matches!(level_spec.level(), Level::ForceWarn) { continue; } if self.check_gated_lint(id, DUMMY_SP, true) { let src = LintLevelSource::CommandLine(lint_name, level); - self.provider.insert(id, LevelSpec::new(level, None, src)); + self.insert_spec(id, LevelSpec::new(level, None, src)); } } } @@ -582,11 +582,15 @@ where // as preventing `allow(lint)` for some lint `lint` in // `lint_group`. For now, issue a future-compatibility // warning for this case. - let fcw_warning = match old_src { - LintLevelSource::Default => false, - LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), - LintLevelSource::CommandLine(name, _) => self.store.is_lint_group(name), - }; + // + // Command-line flags were never able to lower a forbid, so there is + // nothing to stay compatible with there. + let fcw_warning = !matches!(src, LintLevelSource::CommandLine(..)) + && match old_src { + LintLevelSource::Default => false, + LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), + LintLevelSource::CommandLine(name, _) => self.store.is_lint_group(name), + }; debug!( "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}", fcw_warning, @@ -606,9 +610,13 @@ where } }; if !fcw_warning { + let span = match src { + LintLevelSource::CommandLine(..) => None, + _ => Some(src.span()), + }; self.sess.dcx().emit_err(OverruledAttribute { - span: src.span(), - overruled: src.span(), + span, + overruled: span, lint_level: level.as_str(), lint_name: src.name(), sub, diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 57c5a8dbe4c61..a72647283bf27 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -214,15 +214,16 @@ The order of these command line arguments is taken into account. The following a $ rustc lib.rs --crate-type=lib -D unused-variables -A unused-variables ``` -You can make use of this behavior by overriding the level of one specific lint out of a group of lints. The following example denies all the lints in the `unused` group, but explicitly allows the `unused-variables` lint in that group (forbid still trumps everything regardless of ordering): +You can make use of this behavior by overriding the level of one specific lint out of a group of lints. The following example denies all the lints in the `unused` group, but explicitly allows the `unused-variables` lint in that group (this does not work for `forbid`, see below): ```bash $ rustc lib.rs --crate-type=lib -D unused -A unused-variables ``` -Since `force-warn` and `forbid` cannot be overridden, setting -one of them will prevent any later level for the same lint from -taking effect. +Since `force-warn` cannot be overridden, setting it will prevent +any later level for the same lint from taking effect. A later `-A`, +`-W` or `--force-warn` for a lint set to `forbid` is an error, and a +later `-D` is ignored. ### Via an attribute diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr index 07773ee4ddfea..12aa36d9e918b 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 + --> $DIR/forbid-always-trumps-cli.rs:18:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr index cf357ef8ca8f9..33a4047e4bc49 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 + --> $DIR/forbid-always-trumps-cli.rs:18:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr index 07773ee4ddfea..12aa36d9e918b 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 + --> $DIR/forbid-always-trumps-cli.rs:18:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr index cf357ef8ca8f9..33a4047e4bc49 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 + --> $DIR/forbid-always-trumps-cli.rs:18:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr index 07773ee4ddfea..52d0576a6923c 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr @@ -1,10 +1,7 @@ -error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 +error[E0453]: allow(unused) incompatible with previous forbid | -LL | let x = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: `-F unused-variables` implied by `-F unused` + = note: `forbid` lint level was set on command line (`-F unused`) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr index cf357ef8ca8f9..0546e60957a06 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr @@ -1,10 +1,7 @@ -error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 +error[E0453]: allow(unused_variables) incompatible with previous forbid | -LL | let x = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: requested on the command line with `-F unused-variables` + = note: `forbid` lint level was set on command line (`-F unused_variables`) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr index 07773ee4ddfea..ac97f7d8fe169 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr @@ -1,10 +1,7 @@ -error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 +error[E0453]: allow(unused_variables) incompatible with previous forbid | -LL | let x = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: `-F unused-variables` implied by `-F unused` + = note: `forbid` lint level was set on command line (`-F unused`) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr index cf357ef8ca8f9..f14ce2f99ec0b 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr @@ -1,10 +1,7 @@ -error: unused variable: `x` - --> $DIR/forbid-always-trumps-cli.rs:15:9 +error[E0453]: allow(unused) incompatible with previous forbid | -LL | let x = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: requested on the command line with `-F unused-variables` + = note: `forbid` lint level was set on command line (`-F unused_variables`) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/forbid-always-trumps-cli.rs b/tests/ui/lint/forbid-always-trumps-cli.rs index d94cc2e8efef9..52efb48127681 100644 --- a/tests/ui/lint/forbid-always-trumps-cli.rs +++ b/tests/ui/lint/forbid-always-trumps-cli.rs @@ -10,8 +10,11 @@ //@[allow-first-mix1] compile-flags: -A unused_variables -F unused //@[forbid-first-mix2] compile-flags: -F unused_variables -A unused //@[allow-first-mix2] compile-flags: -A unused -F unused_variables +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +//[forbid-first-group,forbid-first-lint,forbid-first-mix1,forbid-first-mix2]~? ERROR incompatible with previous forbid fn main() { let x = 1; - //~^ ERROR unused variable: `x` + //[allow-first-group,allow-first-lint,allow-first-mix1,allow-first-mix2]~^ ERROR unused variable: `x` }