Auto merge of #86572 - rylev:force-warnings-always, r=nikomatsakis
Force warnings even when can_emit_warnings == false Fixes an issue mentioned in #85512 with --cap-lints overriding --force-warnings. Fixes https://github.com/rust-lang/rust/issues/86751 r? `@ehuss`
This commit is contained in:
commit
238fd72880
10 changed files with 116 additions and 12 deletions
|
@ -145,8 +145,9 @@ impl AnnotateSnippetEmitterWriter {
|
||||||
title: Some(Annotation {
|
title: Some(Annotation {
|
||||||
label: Some(&message),
|
label: Some(&message),
|
||||||
id: code.as_ref().map(|c| match c {
|
id: code.as_ref().map(|c| match c {
|
||||||
DiagnosticId::Error(val)
|
DiagnosticId::Error(val) | DiagnosticId::Lint { name: val, .. } => {
|
||||||
| DiagnosticId::Lint { name: val, has_future_breakage: _ } => val.as_str(),
|
val.as_str()
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
annotation_type: annotation_type_for_level(*level),
|
annotation_type: annotation_type_for_level(*level),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub struct Diagnostic {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||||
pub enum DiagnosticId {
|
pub enum DiagnosticId {
|
||||||
Error(String),
|
Error(String),
|
||||||
Lint { name: String, has_future_breakage: bool },
|
Lint { name: String, has_future_breakage: bool, is_force_warn: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "sub"-diagnostic attached to a parent diagnostic.
|
/// A "sub"-diagnostic attached to a parent diagnostic.
|
||||||
|
@ -109,6 +109,13 @@ impl Diagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_force_warn(&self) -> bool {
|
||||||
|
match self.code {
|
||||||
|
Some(DiagnosticId::Lint { is_force_warn, .. }) => is_force_warn,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
|
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
|
||||||
/// canceled or it will panic when dropped).
|
/// canceled or it will panic when dropped).
|
||||||
pub fn cancel(&mut self) {
|
pub fn cancel(&mut self) {
|
||||||
|
|
|
@ -559,7 +559,7 @@ impl DiagnosticCode {
|
||||||
s.map(|s| {
|
s.map(|s| {
|
||||||
let s = match s {
|
let s = match s {
|
||||||
DiagnosticId::Error(s) => s,
|
DiagnosticId::Error(s) => s,
|
||||||
DiagnosticId::Lint { name, has_future_breakage: _ } => name,
|
DiagnosticId::Lint { name, .. } => name,
|
||||||
};
|
};
|
||||||
let je_result =
|
let je_result =
|
||||||
je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();
|
je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();
|
||||||
|
|
|
@ -520,12 +520,28 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
|
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
|
||||||
|
///
|
||||||
|
/// The builder will be canceled if warnings cannot be emitted.
|
||||||
pub fn struct_span_warn(&self, span: impl Into<MultiSpan>, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_span_warn(&self, span: impl Into<MultiSpan>, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
let mut result = self.struct_warn(msg);
|
let mut result = self.struct_warn(msg);
|
||||||
result.set_span(span);
|
result.set_span(span);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
|
||||||
|
///
|
||||||
|
/// This will "force" the warning meaning it will not be canceled even
|
||||||
|
/// if warnings cannot be emitted.
|
||||||
|
pub fn struct_span_force_warn(
|
||||||
|
&self,
|
||||||
|
span: impl Into<MultiSpan>,
|
||||||
|
msg: &str,
|
||||||
|
) -> DiagnosticBuilder<'_> {
|
||||||
|
let mut result = self.struct_force_warn(msg);
|
||||||
|
result.set_span(span);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a builder at the `Allow` level at the given `span` and with the `msg`.
|
/// Construct a builder at the `Allow` level at the given `span` and with the `msg`.
|
||||||
pub fn struct_span_allow(
|
pub fn struct_span_allow(
|
||||||
&self,
|
&self,
|
||||||
|
@ -551,6 +567,8 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a builder at the `Warning` level with the `msg`.
|
/// Construct a builder at the `Warning` level with the `msg`.
|
||||||
|
///
|
||||||
|
/// The builder will be canceled if warnings cannot be emitted.
|
||||||
pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
|
||||||
if !self.flags.can_emit_warnings {
|
if !self.flags.can_emit_warnings {
|
||||||
|
@ -559,6 +577,14 @@ impl Handler {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a builder at the `Warning` level with the `msg`.
|
||||||
|
///
|
||||||
|
/// This will "force" a warning meaning it will not be canceled even
|
||||||
|
/// if warnings cannot be emitted.
|
||||||
|
pub fn struct_force_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
|
DiagnosticBuilder::new(self, Level::Warning, msg)
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a builder at the `Allow` level with the `msg`.
|
/// Construct a builder at the `Allow` level with the `msg`.
|
||||||
pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
DiagnosticBuilder::new(self, Level::Allow, msg)
|
DiagnosticBuilder::new(self, Level::Allow, msg)
|
||||||
|
@ -801,7 +827,10 @@ impl HandlerInner {
|
||||||
self.future_breakage_diagnostics.push(diagnostic.clone());
|
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
|
||||||
|
&& !diagnostic.is_force_warn()
|
||||||
|
{
|
||||||
if diagnostic.has_future_breakage() {
|
if diagnostic.has_future_breakage() {
|
||||||
(*TRACK_DIAGNOSTICS)(diagnostic);
|
(*TRACK_DIAGNOSTICS)(diagnostic);
|
||||||
}
|
}
|
||||||
|
@ -873,7 +902,7 @@ impl HandlerInner {
|
||||||
|
|
||||||
match (errors.len(), warnings.len()) {
|
match (errors.len(), warnings.len()) {
|
||||||
(0, 0) => return,
|
(0, 0) => return,
|
||||||
(0, _) => self.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
|
(0, _) => self.emitter.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
|
||||||
(_, 0) => {
|
(_, 0) => {
|
||||||
let _ = self.fatal(&errors);
|
let _ = self.fatal(&errors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,13 @@ impl LintLevelSets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that we never exceed the `--cap-lints` argument.
|
// Ensure that we never exceed the `--cap-lints` argument
|
||||||
level = cmp::min(level, self.lint_cap);
|
// unless the source is a --force-warn
|
||||||
|
level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src {
|
||||||
|
level
|
||||||
|
} else {
|
||||||
|
cmp::min(level, self.lint_cap)
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
|
if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
|
||||||
// Ensure that we never exceed driver level.
|
// Ensure that we never exceed driver level.
|
||||||
|
@ -233,8 +238,10 @@ pub fn struct_lint_level<'s, 'd>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Level::Warn | Level::ForceWarn, Some(span)) => sess.struct_span_warn(span, ""),
|
(Level::Warn, Some(span)) => sess.struct_span_warn(span, ""),
|
||||||
(Level::Warn | Level::ForceWarn, None) => sess.struct_warn(""),
|
(Level::Warn, None) => sess.struct_warn(""),
|
||||||
|
(Level::ForceWarn, Some(span)) => sess.struct_span_force_warn(span, ""),
|
||||||
|
(Level::ForceWarn, None) => sess.struct_force_warn(""),
|
||||||
(Level::Deny | Level::Forbid, Some(span)) => sess.struct_span_err(span, ""),
|
(Level::Deny | Level::Forbid, Some(span)) => sess.struct_span_err(span, ""),
|
||||||
(Level::Deny | Level::Forbid, None) => sess.struct_err(""),
|
(Level::Deny | Level::Forbid, None) => sess.struct_err(""),
|
||||||
};
|
};
|
||||||
|
@ -324,7 +331,8 @@ pub fn struct_lint_level<'s, 'd>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err.code(DiagnosticId::Lint { name, has_future_breakage });
|
let is_force_warn = matches!(level, Level::ForceWarn);
|
||||||
|
err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn });
|
||||||
|
|
||||||
if let Some(future_incompatible) = future_incompatible {
|
if let Some(future_incompatible) = future_incompatible {
|
||||||
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
|
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
|
||||||
|
|
|
@ -324,7 +324,7 @@ impl Session {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|diag| {
|
.map(|diag| {
|
||||||
let lint_name = match &diag.code {
|
let lint_name = match &diag.code {
|
||||||
Some(DiagnosticId::Lint { name, has_future_breakage: true }) => name,
|
Some(DiagnosticId::Lint { name, has_future_breakage: true, .. }) => name,
|
||||||
_ => panic!("Unexpected code in diagnostic {:?}", diag),
|
_ => panic!("Unexpected code in diagnostic {:?}", diag),
|
||||||
};
|
};
|
||||||
let lint = lint_store.name_to_lint(&lint_name);
|
let lint = lint_store.name_to_lint(&lint_name);
|
||||||
|
@ -351,6 +351,13 @@ impl Session {
|
||||||
pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
self.diagnostic().struct_span_warn(sp, msg)
|
self.diagnostic().struct_span_warn(sp, msg)
|
||||||
}
|
}
|
||||||
|
pub fn struct_span_force_warn<S: Into<MultiSpan>>(
|
||||||
|
&self,
|
||||||
|
sp: S,
|
||||||
|
msg: &str,
|
||||||
|
) -> DiagnosticBuilder<'_> {
|
||||||
|
self.diagnostic().struct_span_force_warn(sp, msg)
|
||||||
|
}
|
||||||
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
|
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
|
||||||
&self,
|
&self,
|
||||||
sp: S,
|
sp: S,
|
||||||
|
@ -362,6 +369,9 @@ impl Session {
|
||||||
pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
self.diagnostic().struct_warn(msg)
|
self.diagnostic().struct_warn(msg)
|
||||||
}
|
}
|
||||||
|
pub fn struct_force_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
|
self.diagnostic().struct_force_warn(msg)
|
||||||
|
}
|
||||||
pub fn struct_span_allow<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> {
|
pub fn struct_span_allow<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> {
|
||||||
self.diagnostic().struct_span_allow(sp, msg)
|
self.diagnostic().struct_span_allow(sp, msg)
|
||||||
}
|
}
|
||||||
|
|
15
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.rs
Normal file
15
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// compile-flags: --cap-lints warn --force-warns rust-2021-compatibility -Zunstable-options
|
||||||
|
// check-pass
|
||||||
|
#![allow(ellipsis_inclusive_range_patterns)]
|
||||||
|
|
||||||
|
pub fn f() -> bool {
|
||||||
|
let x = 123;
|
||||||
|
match x {
|
||||||
|
0...100 => true,
|
||||||
|
//~^ WARN range patterns are deprecated
|
||||||
|
//~| WARN this is accepted in the current edition
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.stderr
Normal file
12
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
warning: `...` range patterns are deprecated
|
||||||
|
--> $DIR/force-warn-cap-lints-warn.rs:8:10
|
||||||
|
|
|
||||||
|
LL | 0...100 => true,
|
||||||
|
| ^^^ help: use `..=` for an inclusive range
|
||||||
|
|
|
||||||
|
= note: `--force-warns ellipsis-inclusive-range-patterns` implied by `--force-warns rust-2021-compatibility`
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
10
src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs
Normal file
10
src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// compile-flags: --cap-lints allow --force-warns bare_trait_objects -Zunstable-options
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
pub trait SomeTrait {}
|
||||||
|
|
||||||
|
pub fn function(_x: Box<SomeTrait>) {}
|
||||||
|
//~^ WARN trait objects without an explicit `dyn` are deprecated
|
||||||
|
//~| WARN this is accepted in the current edition
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
|
--> $DIR/force-warns-cap-lints-allow.rs:6:25
|
||||||
|
|
|
||||||
|
LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
|
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
||||||
|
|
|
||||||
|
= note: requested on the command line with `--force-warns bare-trait-objects`
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue