From 440b63904f85d2795c795e0926cced241c57fdf7 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Thu, 13 May 2021 15:33:29 +0200 Subject: [PATCH 1/4] Check whether -F is ever overridden on the command line --- compiler/rustc_lint/src/levels.rs | 43 +++++++++++++++++++++------- compiler/rustc_session/src/config.rs | 12 ++------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 0ee434f5fb50b..7e9bde2721fe8 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -84,7 +84,7 @@ impl<'s> LintLevelsBuilder<'s> { } fn process_command_line(&mut self, sess: &Session, store: &LintStore) { - let mut specs = FxHashMap::default(); + self.sets.list.push(LintSet::CommandLine { specs: FxHashMap::default() }); self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); for &(ref lint_name, level) in &sess.opts.lint_opts { @@ -105,7 +105,17 @@ impl<'s> LintLevelsBuilder<'s> { for id in ids { self.check_gated_lint(id, DUMMY_SP); let src = LintLevelSource::CommandLine(lint_flag_val, orig_level); - specs.insert(id, (level, src)); + let specs = match self.sets.list.last().unwrap() { + LintSet::CommandLine { ref specs } => specs, + _ => unreachable!(), + }; + if self.check_before_insert_spec(specs, id, (level, src)) { + let specs = match self.sets.list.last_mut().unwrap() { + LintSet::CommandLine { ref mut specs } => specs, + _ => unreachable!(), + }; + specs.insert(id, (level, src)); + } } } @@ -122,15 +132,12 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.list.push(LintSet::CommandLine { specs }); } - /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful - /// (e.g. if a forbid was already inserted on the same scope), then emits a - /// diagnostic with no change to `specs`. - fn insert_spec( - &mut self, - specs: &mut FxHashMap, + fn check_before_insert_spec( + &self, + specs: &FxHashMap, id: LintId, (level, src): LevelAndSource, - ) { + ) -> bool { // Setting to a non-forbid level is an error if the lint previously had // a forbid level. Note that this is not necessarily true even with a // `#[forbid(..)]` attribute present, as that is overriden by `--cap-lints`. @@ -212,11 +219,25 @@ impl<'s> LintLevelsBuilder<'s> { // issuing a FCW. In the FCW case, we want to // respect the new setting. if !fcw_warning { - return; + return false; } } } - specs.insert(id, (level, src)); + true + } + + /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful + /// (e.g. if a forbid was already inserted on the same scope), then emits a + /// diagnostic with no change to `specs`. + fn insert_spec( + &mut self, + specs: &mut FxHashMap, + id: LintId, + (level, src): LevelAndSource, + ) { + if self.check_before_insert_spec(specs, id, (level, src)) { + specs.insert(id, (level, src)); + } } /// Pushes a list of AST lint attributes onto this context. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index af24358fe645f..6c9d0a17f282b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1169,16 +1169,8 @@ pub fn get_cmd_lint_options( let mut lint_opts_with_position = vec![]; let mut describe_lints = false; - for level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid] { - for (passed_arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) { - let arg_pos = if let lint::Forbid = level { - // HACK: forbid is always specified last, so it can't be overridden. - // FIXME: remove this once is - // fixed and `forbid` works as expected. - usize::MAX - } else { - passed_arg_pos - }; + for &level in &[lint::Allow, lint::Warn, lint::Deny, lint::Forbid] { + for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) { if lint_name == "help" { describe_lints = true; } else { From 034f1fb13a8a20ce1e236e5479512b40abc43e3b Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Fri, 14 May 2021 19:24:25 +0200 Subject: [PATCH 2/4] Fix handling of allow/deny/forbid(warnings) --- .../rustc_errors/src/diagnostic_builder.rs | 14 ++++- compiler/rustc_errors/src/lib.rs | 25 ++++++--- compiler/rustc_lint/src/levels.rs | 50 ++++++++++++++---- compiler/rustc_middle/src/lint.rs | 52 +++++++++++++++---- compiler/rustc_session/src/session.rs | 5 +- src/test/ui/lint/issue-41941.rs | 10 ++++ src/test/ui/lint/issue-41941.stderr | 14 +++++ .../ui/lint/issue-70819-command-line-F.rs | 7 +++ .../ui/lint/issue-70819-command-line-F.stderr | 15 ++++++ src/test/ui/lint/issue-75668.rs | 10 ++++ src/test/ui/lint/issue-75668.stderr | 13 +++++ src/test/ui/lint/override-command-line-D.rs | 8 +++ .../ui/lint/override-command-line-D.stderr | 15 ++++++ 13 files changed, 209 insertions(+), 29 deletions(-) create mode 100644 src/test/ui/lint/issue-41941.rs create mode 100644 src/test/ui/lint/issue-41941.stderr create mode 100644 src/test/ui/lint/issue-70819-command-line-F.rs create mode 100644 src/test/ui/lint/issue-70819-command-line-F.stderr create mode 100644 src/test/ui/lint/issue-75668.rs create mode 100644 src/test/ui/lint/issue-75668.stderr create mode 100644 src/test/ui/lint/override-command-line-D.rs create mode 100644 src/test/ui/lint/override-command-line-D.stderr diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 282877d5dd109..333d1856decf7 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -28,6 +28,7 @@ struct DiagnosticBuilderInner<'a> { handler: &'a Handler, diagnostic: Diagnostic, allow_suggestions: bool, + is_lint: bool, } /// In general, the `DiagnosticBuilder` uses deref to allow access to @@ -100,7 +101,7 @@ impl<'a> DerefMut for DiagnosticBuilder<'a> { impl<'a> DiagnosticBuilder<'a> { /// Emit the diagnostic. pub fn emit(&mut self) { - self.0.handler.emit_diagnostic(&self); + self.0.handler.emit_diagnostic_with_ignore(&self, self.0.is_lint); self.cancel(); } @@ -373,6 +374,16 @@ impl<'a> DiagnosticBuilder<'a> { self } + /// Set by LintDiagnosticBuilder to distinguish lint warnings from other + /// warnings. Necessary because `-A warnings` on the command line turns + /// off all regular warnings, but lint warnings can be turned on again + /// with #[warn(...)]. + pub fn is_lint(&mut self, value: bool) -> &mut Self { + debug!("is_lint({:?})", value); + self.0.is_lint = value; + self + } + /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> { @@ -399,6 +410,7 @@ impl<'a> DiagnosticBuilder<'a> { handler, diagnostic, allow_suggestions: true, + is_lint: false, })) } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 979f2d3b3005d..bf6ccb8e9e0fb 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -553,11 +553,7 @@ impl Handler { /// Construct a builder at the `Warning` level with the `msg`. pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { - let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); - if !self.flags.can_emit_warnings { - result.cancel(); - } - result + DiagnosticBuilder::new(self, Level::Warning, msg) } /// Construct a builder at the `Allow` level with the `msg`. @@ -752,6 +748,14 @@ impl Handler { self.inner.borrow_mut().force_print_diagnostic(db) } + pub fn emit_diagnostic_with_ignore( + &self, + diagnostic: &Diagnostic, + ignore_can_emit_warnings: bool, + ) { + self.inner.borrow_mut().emit_diagnostic_with_ignore(diagnostic, ignore_can_emit_warnings) + } + pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { self.inner.borrow_mut().emit_diagnostic(diagnostic) } @@ -794,6 +798,14 @@ impl HandlerInner { } fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) { + self.emit_diagnostic_with_ignore(diagnostic, false); + } + + fn emit_diagnostic_with_ignore( + &mut self, + diagnostic: &Diagnostic, + ignore_can_emit_warnings: bool, + ) { if diagnostic.cancelled() { return; } @@ -802,7 +814,8 @@ impl HandlerInner { self.future_breakage_diagnostics.push(diagnostic.clone()); } - if diagnostic.level == Warning && !self.flags.can_emit_warnings { + if diagnostic.level == Warning && !self.flags.can_emit_warnings && !ignore_can_emit_warnings + { if diagnostic.has_future_breakage() { (*TRACK_DIAGNOSTICS)(diagnostic); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7e9bde2721fe8..8c32fdb5adf65 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -87,8 +87,8 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.list.push(LintSet::CommandLine { specs: FxHashMap::default() }); self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); - for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, Some(level)); + for (position, &(ref lint_name, level)) in (0u32..).zip(sess.opts.lint_opts.iter()) { + store.check_lint_name_cmdline(sess, &lint_name, level); let orig_level = level; // If the cap is less than this specified level, e.g., if we've got @@ -97,14 +97,15 @@ impl<'s> LintLevelsBuilder<'s> { let level = cmp::min(level, self.sets.lint_cap); let lint_flag_val = Symbol::intern(lint_name); + let src = LintLevelSource::CommandLine(lint_flag_val, orig_level, position); let ids = match store.find_lints(&lint_name) { Ok(ids) => ids, Err(_) => continue, // errors handled in check_lint_name_cmdline above }; + for id in ids { self.check_gated_lint(id, DUMMY_SP); - let src = LintLevelSource::CommandLine(lint_flag_val, orig_level); let specs = match self.sets.list.last().unwrap() { LintSet::CommandLine { ref specs } => specs, _ => unreachable!(), @@ -132,6 +133,22 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.list.push(LintSet::CommandLine { specs }); } + fn get_current_depth(&self) -> u32 { + let mut idx = self.cur; + let mut depth = 0; + loop { + match &self.sets.list[idx as usize] { + LintSet::CommandLine { .. } => { + return depth; + } + LintSet::Node { parent, .. } => { + depth += 1; + idx = *parent; + } + } + } + } + fn check_before_insert_spec( &self, specs: &FxHashMap, @@ -157,8 +174,8 @@ impl<'s> LintLevelsBuilder<'s> { let id_name = id.lint.name_lower(); let fcw_warning = match old_src { LintLevelSource::Default => false, - LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol), - LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol), + LintLevelSource::Node(symbol, ..) => self.store.is_lint_group(symbol), + LintLevelSource::CommandLine(symbol, ..) => self.store.is_lint_group(symbol), LintLevelSource::ForceWarn(_symbol) => { bug!("forced warn lint returned a forbid lint level") } @@ -177,13 +194,13 @@ impl<'s> LintLevelsBuilder<'s> { id.to_string() )); } - LintLevelSource::Node(_, forbid_source_span, reason) => { + LintLevelSource::Node(_, forbid_source_span, reason, ..) => { diag_builder.span_label(forbid_source_span, "`forbid` level set here"); if let Some(rationale) = reason { diag_builder.note(&rationale.as_str()); } } - LintLevelSource::CommandLine(_, _) => { + LintLevelSource::CommandLine(..) => { diag_builder.note("`forbid` lint level was set on command line"); } _ => bug!("forced warn lint returned a forbid lint level"), @@ -263,7 +280,7 @@ impl<'s> LintLevelsBuilder<'s> { let mut specs = FxHashMap::default(); let sess = self.sess; let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); - for attr in attrs { + for (attr_pos, attr) in (0u32..).zip(attrs.iter()) { let level = match Level::from_symbol(attr.name_or_empty()) { None => continue, Some(lvl) => lvl, @@ -374,7 +391,10 @@ impl<'s> LintLevelsBuilder<'s> { meta_item.path.segments.last().expect("empty lint name").ident.name, sp, reason, + self.get_current_depth(), + attr_pos, ); + for &id in *ids { self.check_gated_lint(id, attr.span); self.insert_spec(&mut specs, id, (level, src)); @@ -389,6 +409,8 @@ impl<'s> LintLevelsBuilder<'s> { Symbol::intern(complete_name), sp, reason, + self.get_current_depth(), + attr_pos, ); for id in ids { self.insert_spec(&mut specs, *id, (level, src)); @@ -425,6 +447,8 @@ impl<'s> LintLevelsBuilder<'s> { Symbol::intern(&new_lint_name), sp, reason, + self.get_current_depth(), + attr_pos, ); for id in ids { self.insert_spec(&mut specs, *id, (level, src)); @@ -495,7 +519,13 @@ impl<'s> LintLevelsBuilder<'s> { // Ignore any errors or warnings that happen because the new name is inaccurate // NOTE: `new_name` already includes the tool name, so we don't have to add it again. if let CheckLintNameResult::Ok(ids) = store.check_lint_name(&new_name, None) { - let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason); + let src = LintLevelSource::Node( + Symbol::intern(&new_name), + sp, + reason, + self.get_current_depth(), + attr_pos, + ); for &id in ids { self.check_gated_lint(id, attr.span); self.insert_spec(&mut specs, id, (level, src)); @@ -514,7 +544,7 @@ impl<'s> LintLevelsBuilder<'s> { } let (lint_attr_name, lint_attr_span) = match *src { - LintLevelSource::Node(name, span, _) => (name, span), + LintLevelSource::Node(name, span, _, _, _) => (name, span), _ => continue, }; diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 4c7ea937ceb7d..da278e55d2793 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -22,12 +22,18 @@ pub enum LintLevelSource { Default, /// Lint level was set by an attribute. - Node(Symbol, Span, Option /* RFC 2383 reason */), + Node( + Symbol, + Span, + Option, /* RFC 2383 reason */ + u32, /* depth */ + u32, /* position */ + ), /// Lint level was set by a command-line flag. /// The provided `Level` is the level specified on the command line. /// (The actual level may be lower due to `--cap-lints`.) - CommandLine(Symbol, Level), + CommandLine(Symbol, Level, u32 /* position */), /// Lint is being forced to warn no matter what. ForceWarn(Symbol), @@ -37,8 +43,8 @@ impl LintLevelSource { pub fn name(&self) -> Symbol { match *self { LintLevelSource::Default => symbol::kw::Default, - LintLevelSource::Node(name, _, _) => name, - LintLevelSource::CommandLine(name, _) => name, + LintLevelSource::Node(name, ..) => name, + LintLevelSource::CommandLine(name, ..) => name, LintLevelSource::ForceWarn(name) => name, } } @@ -46,11 +52,32 @@ impl LintLevelSource { pub fn span(&self) -> Span { match *self { LintLevelSource::Default => DUMMY_SP, - LintLevelSource::Node(_, span, _) => span, - LintLevelSource::CommandLine(_, _) => DUMMY_SP, + LintLevelSource::Node(_, span, ..) => span, + LintLevelSource::CommandLine(..) => DUMMY_SP, LintLevelSource::ForceWarn(_) => DUMMY_SP, } } + + /// Whether a lint level specified at `a` can be overridden by one at `b`. + pub fn can_override(a: &Self, b: &Self) -> bool { + match (a, b) { + (LintLevelSource::Default, LintLevelSource::Default) => false, + (LintLevelSource::ForceWarn(_), LintLevelSource::ForceWarn(_)) => false, + (_, LintLevelSource::ForceWarn(_)) => true, + (LintLevelSource::ForceWarn(_), _) => false, + (LintLevelSource::Default, _) => true, + (_, LintLevelSource::Default) => false, + (LintLevelSource::CommandLine(.., pos_a), LintLevelSource::CommandLine(.., pos_b)) => { + pos_a < pos_b + } + (LintLevelSource::CommandLine(..), LintLevelSource::Node(..)) => true, + (LintLevelSource::Node(..), LintLevelSource::CommandLine(..)) => false, + ( + LintLevelSource::Node(.., depth_a, pos_a), + LintLevelSource::Node(.., depth_b, pos_b), + ) => (depth_a < depth_b) || (depth_a == depth_b && pos_a < pos_b), + } + } } /// A tuple of a lint level and its source. @@ -116,9 +143,11 @@ impl LintLevelSets { let (warnings_level, warnings_src) = self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); if let Some(configured_warning_level) = warnings_level { - if configured_warning_level != Level::Warn { - level = configured_warning_level; - src = warnings_src; + if LintLevelSource::can_override(&src, &warnings_src) { + if configured_warning_level != Level::Warn { + level = configured_warning_level; + src = warnings_src; + } } } } @@ -227,6 +256,7 @@ impl<'a> LintDiagnosticBuilder<'a> { /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`. pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a> { self.0.set_primary_message(msg); + self.0.is_lint(true); self.0 } @@ -310,7 +340,7 @@ pub fn struct_lint_level<'s, 'd>( &format!("`#[{}({})]` on by default", level.as_str(), name), ); } - LintLevelSource::CommandLine(lint_flag_val, orig_level) => { + LintLevelSource::CommandLine(lint_flag_val, orig_level, _) => { let flag = match orig_level { Level::Warn => "-W", Level::Deny => "-D", @@ -339,7 +369,7 @@ pub fn struct_lint_level<'s, 'd>( ); } } - LintLevelSource::Node(lint_attr_name, src, reason) => { + LintLevelSource::Node(lint_attr_name, src, reason, _, _) => { if let Some(rationale) = reason { err.note(&rationale.as_str()); } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 86b8389a670e6..25b9a44603581 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1266,8 +1266,11 @@ pub fn build_session( .lint_opts .iter() .filter(|&&(ref key, _)| *key == "warnings") - .map(|&(_, ref level)| *level == lint::Allow) + // We are only interested in the last one, because there might be a chain + // of `-A warnings -D warnings -W warnings ...`, and only the last one + // should have an effect .last() + .map(|&(_, ref level)| *level == lint::Allow) .unwrap_or(false); let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow); let can_emit_warnings = !(warnings_allow || cap_lints_allow); diff --git a/src/test/ui/lint/issue-41941.rs b/src/test/ui/lint/issue-41941.rs new file mode 100644 index 0000000000000..90168833e18ae --- /dev/null +++ b/src/test/ui/lint/issue-41941.rs @@ -0,0 +1,10 @@ +// Checks whether exceptions can be added to #![deny(warnings)]. +// check-pass + +#![deny(warnings)] +#![warn(unused_variables)] + +fn main() { + let a = 5; + //~^ WARNING: unused +} diff --git a/src/test/ui/lint/issue-41941.stderr b/src/test/ui/lint/issue-41941.stderr new file mode 100644 index 0000000000000..2c34efcc0c9ea --- /dev/null +++ b/src/test/ui/lint/issue-41941.stderr @@ -0,0 +1,14 @@ +warning: unused variable: `a` + --> $DIR/issue-41941.rs:8:9 + | +LL | let a = 5; + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/issue-41941.rs:5:9 + | +LL | #![warn(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/src/test/ui/lint/issue-70819-command-line-F.rs b/src/test/ui/lint/issue-70819-command-line-F.rs new file mode 100644 index 0000000000000..1ffd34ae6aebe --- /dev/null +++ b/src/test/ui/lint/issue-70819-command-line-F.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z deduplicate-diagnostics=yes -F unused -D forbidden_lint_groups -A unused +//~^ ERROR: allow(unused) incompatible +//~| WARNING: this was previously accepted +//~| ERROR: allow(unused) incompatible +//~| WARNING: this was previously accepted + +fn main() {} diff --git a/src/test/ui/lint/issue-70819-command-line-F.stderr b/src/test/ui/lint/issue-70819-command-line-F.stderr new file mode 100644 index 0000000000000..4ebd4eacefda3 --- /dev/null +++ b/src/test/ui/lint/issue-70819-command-line-F.stderr @@ -0,0 +1,15 @@ +error: allow(unused) incompatible with previous forbid + | + = note: requested on the command line with `-D forbidden-lint-groups` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `forbid` lint level was set on command line + +error: allow(unused) incompatible with previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `forbid` lint level was set on command line + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/issue-75668.rs b/src/test/ui/lint/issue-75668.rs new file mode 100644 index 0000000000000..3049750fa8f48 --- /dev/null +++ b/src/test/ui/lint/issue-75668.rs @@ -0,0 +1,10 @@ +// Checks that `-A warnings` on the command line can be overridden. +// compile-flags: -A warnings +// check-pass + +#![warn(unused)] + +fn main() { + let a = 5; + //~^ WARNING: unused +} diff --git a/src/test/ui/lint/issue-75668.stderr b/src/test/ui/lint/issue-75668.stderr new file mode 100644 index 0000000000000..06e01344ef195 --- /dev/null +++ b/src/test/ui/lint/issue-75668.stderr @@ -0,0 +1,13 @@ +warning: unused variable: `a` + --> $DIR/issue-75668.rs:8:9 + | +LL | let a = 5; + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/issue-75668.rs:5:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + diff --git a/src/test/ui/lint/override-command-line-D.rs b/src/test/ui/lint/override-command-line-D.rs new file mode 100644 index 0000000000000..5e3e15d7d0750 --- /dev/null +++ b/src/test/ui/lint/override-command-line-D.rs @@ -0,0 +1,8 @@ +// compile-flags: -D warnings +// check-pass + +fn main() { + #[warn(unused)] + let a = 5; + //~^ WARNING: unused +} diff --git a/src/test/ui/lint/override-command-line-D.stderr b/src/test/ui/lint/override-command-line-D.stderr new file mode 100644 index 0000000000000..f0430a5dca18a --- /dev/null +++ b/src/test/ui/lint/override-command-line-D.stderr @@ -0,0 +1,15 @@ +warning: unused variable: `a` + --> $DIR/override-command-line-D.rs:6:9 + | +LL | let a = 5; + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/override-command-line-D.rs:5:12 + | +LL | #[warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: 1 warning emitted + From 80ae9ef14641e0cff52d55a0a8cb5eb2d96fb317 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Fri, 14 May 2021 20:36:44 +0200 Subject: [PATCH 3/4] Fix test case failure in ui-fulldeps suite --- .../lint-group-forbid-always-trumps-cli.rs | 7 +++++-- .../lint-group-forbid-always-trumps-cli.stderr | 17 +++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs b/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs index fc19bc039063a..5e09c70e7e288 100644 --- a/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs +++ b/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs @@ -1,7 +1,10 @@ // aux-build:lint-group-plugin-test.rs -// compile-flags: -F unused -A unused +// compile-flags: -F unused -D forbidden_lint_groups -A unused -Z deduplicate-diagnostics=yes +//~^^ ERROR: allow(unused) incompatible +//~| WARNING: this was previously accepted +//~| ERROR: allow(unused) incompatible +//~| WARNING: this was previously accepted fn main() { let x = 1; - //~^ ERROR unused variable: `x` } diff --git a/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr b/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr index 6bab367b0d175..4ebd4eacefda3 100644 --- a/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr +++ b/src/test/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr @@ -1,10 +1,15 @@ -error: unused variable: `x` - --> $DIR/lint-group-forbid-always-trumps-cli.rs:5:9 +error: 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 `-D forbidden-lint-groups` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `forbid` lint level was set on command line + +error: allow(unused) incompatible with previous forbid | - = note: `-F unused-variables` implied by `-F unused` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `forbid` lint level was set on command line -error: aborting due to previous error +error: aborting due to 2 previous errors From 88ff8f82a53e1e469b16a482b8bd208df50fbccc Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Fri, 4 Jun 2021 21:42:11 +0200 Subject: [PATCH 4/4] Fix compilation errors after rebase --- compiler/rustc_lint/src/levels.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 8c32fdb5adf65..709d89fa0081b 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -88,7 +88,7 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); for (position, &(ref lint_name, level)) in (0u32..).zip(sess.opts.lint_opts.iter()) { - store.check_lint_name_cmdline(sess, &lint_name, level); + store.check_lint_name_cmdline(sess, &lint_name, Some(level)); let orig_level = level; // If the cap is less than this specified level, e.g., if we've got @@ -129,8 +129,6 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.force_warns.extend(&lints); } } - - self.sets.list.push(LintSet::CommandLine { specs }); } fn get_current_depth(&self) -> u32 {