Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force warnings even when can_emit_warnings == false #86572

Merged
merged 3 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ impl AnnotateSnippetEmitterWriter {
title: Some(Annotation {
label: Some(&message),
id: code.as_ref().map(|c| match c {
DiagnosticId::Error(val)
| DiagnosticId::Lint { name: val, has_future_breakage: _ } => val.as_str(),
DiagnosticId::Error(val) | DiagnosticId::Lint { name: val, .. } => {
val.as_str()
}
}),
annotation_type: annotation_type_for_level(*level),
}),
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct Diagnostic {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum DiagnosticId {
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.
Expand Down Expand Up @@ -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
/// canceled or it will panic when dropped).
pub fn cancel(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ impl DiagnosticCode {
s.map(|s| {
let s = match s {
DiagnosticId::Error(s) => s,
DiagnosticId::Lint { name, has_future_breakage: _ } => name,
DiagnosticId::Lint { name, .. } => name,
};
let je_result =
je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();
Expand Down
33 changes: 31 additions & 2 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,12 +521,28 @@ impl Handler {
}

/// 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<'_> {
let mut result = self.struct_warn(msg);
result.set_span(span);
result
}

/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
rylev marked this conversation as resolved.
Show resolved Hide resolved
///
/// 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`.
pub fn struct_span_allow(
&self,
Expand All @@ -552,6 +568,8 @@ impl Handler {
}

/// 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<'_> {
let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
if !self.flags.can_emit_warnings {
Expand All @@ -560,6 +578,14 @@ impl Handler {
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`.
pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_> {
DiagnosticBuilder::new(self, Level::Allow, msg)
Expand Down Expand Up @@ -802,7 +828,10 @@ 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
&& !diagnostic.is_force_warn()
{
if diagnostic.has_future_breakage() {
(*TRACK_DIAGNOSTICS)(diagnostic);
}
Expand Down Expand Up @@ -874,7 +903,7 @@ impl HandlerInner {

match (errors.len(), warnings.len()) {
(0, 0) => return,
(0, _) => self.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
(0, _) => self.emitter.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
(_, 0) => {
let _ = self.fatal(&errors);
}
Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,13 @@ impl LintLevelSets {
}
}

// Ensure that we never exceed the `--cap-lints` argument.
level = cmp::min(level, self.lint_cap);
// 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
} else {
cmp::min(level, self.lint_cap)
};

if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
// Ensure that we never exceed driver level.
Expand Down Expand Up @@ -258,8 +263,10 @@ pub fn struct_lint_level<'s, 'd>(
return;
}
}
(Level::Warn | Level::ForceWarn, Some(span)) => sess.struct_span_warn(span, ""),
(Level::Warn | Level::ForceWarn, None) => sess.struct_warn(""),
(Level::Warn, Some(span)) => sess.struct_span_warn(span, ""),
(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, None) => sess.struct_err(""),
};
Expand Down Expand Up @@ -349,7 +356,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 {
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl Session {
.into_iter()
.map(|diag| {
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),
};
let lint = lint_store.name_to_lint(&lint_name);
Expand Down Expand Up @@ -369,6 +369,13 @@ impl Session {
pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> {
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>>(
&self,
sp: S,
Expand All @@ -380,6 +387,9 @@ impl Session {
pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
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<'_> {
self.diagnostic().struct_span_allow(sp, msg)
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/lint/force-warn/force-warn-cap-lints-warn.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions src/test/ui/lint/force-warn/force-warn-cap-lints-warn.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs
Original file line number Diff line number Diff line change
@@ -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() {}
12 changes: 12 additions & 0 deletions src/test/ui/lint/force-warn/force-warns-cap-lints-allow.stderr
Original file line number Diff line number Diff line change
@@ -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