Skip to content

Commit a3d6905

Browse files
committed
Force warnings even when can_emit_warnings == false
1 parent e98897e commit a3d6905

File tree

8 files changed

+54
-8
lines changed

8 files changed

+54
-8
lines changed

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,9 @@ impl AnnotateSnippetEmitterWriter {
145145
title: Some(Annotation {
146146
label: Some(&message),
147147
id: code.as_ref().map(|c| match c {
148-
DiagnosticId::Error(val)
149-
| DiagnosticId::Lint { name: val, has_future_breakage: _ } => val.as_str(),
148+
DiagnosticId::Error(val) | DiagnosticId::Lint { name: val, .. } => {
149+
val.as_str()
150+
}
150151
}),
151152
annotation_type: annotation_type_for_level(*level),
152153
}),

compiler/rustc_errors/src/diagnostic.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct Diagnostic {
2929
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
3030
pub enum DiagnosticId {
3131
Error(String),
32-
Lint { name: String, has_future_breakage: bool },
32+
Lint { name: String, has_future_breakage: bool, is_force_warn: bool },
3333
}
3434

3535
/// A "sub"-diagnostic attached to a parent diagnostic.
@@ -109,6 +109,13 @@ impl Diagnostic {
109109
}
110110
}
111111

112+
pub fn is_force_warn(&self) -> bool {
113+
match self.code {
114+
Some(DiagnosticId::Lint { is_force_warn, .. }) => is_force_warn,
115+
_ => false,
116+
}
117+
}
118+
112119
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
113120
/// canceled or it will panic when dropped).
114121
pub fn cancel(&mut self) {

compiler/rustc_errors/src/json.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ impl DiagnosticCode {
559559
s.map(|s| {
560560
let s = match s {
561561
DiagnosticId::Error(s) => s,
562-
DiagnosticId::Lint { name, has_future_breakage: _ } => name,
562+
DiagnosticId::Lint { name, .. } => name,
563563
};
564564
let je_result =
565565
je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();

compiler/rustc_errors/src/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,10 @@ impl HandlerInner {
802802
self.future_breakage_diagnostics.push(diagnostic.clone());
803803
}
804804

805-
if diagnostic.level == Warning && !self.flags.can_emit_warnings {
805+
if diagnostic.level == Warning
806+
&& !self.flags.can_emit_warnings
807+
&& !diagnostic.is_force_warn()
808+
{
806809
if diagnostic.has_future_breakage() {
807810
(*TRACK_DIAGNOSTICS)(diagnostic);
808811
}
@@ -874,7 +877,7 @@ impl HandlerInner {
874877

875878
match (errors.len(), warnings.len()) {
876879
(0, 0) => return,
877-
(0, _) => self.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
880+
(0, _) => self.emitter.emit_diagnostic(&Diagnostic::new(Level::Warning, &warnings)),
878881
(_, 0) => {
879882
let _ = self.fatal(&errors);
880883
}

compiler/rustc_middle/src/lint.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ pub fn struct_lint_level<'s, 'd>(
246246
let has_future_breakage =
247247
future_incompatible.map_or(false, |incompat| incompat.future_breakage.is_some());
248248

249+
let is_force_warn = matches!(level, Level::ForceWarn)
250+
|| matches!(src, LintLevelSource::CommandLine(_, Level::ForceWarn));
251+
249252
let mut err = match (level, span) {
250253
(Level::Allow, span) => {
251254
if has_future_breakage {
@@ -254,6 +257,16 @@ pub fn struct_lint_level<'s, 'd>(
254257
} else {
255258
sess.struct_allow("")
256259
}
260+
} else if is_force_warn {
261+
let mut err = if let Some(span) = span {
262+
sess.struct_span_warn(span, "")
263+
} else {
264+
sess.struct_warn("")
265+
};
266+
// Ensure force-warn warns even if the diagnostic has
267+
// been canceled for reasons like `--cap-lints`
268+
err.level = rustc_errors::Level::Warning;
269+
err
257270
} else {
258271
return;
259272
}
@@ -349,7 +362,7 @@ pub fn struct_lint_level<'s, 'd>(
349362
}
350363
}
351364

352-
err.code(DiagnosticId::Lint { name, has_future_breakage });
365+
err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn });
353366

354367
if let Some(future_incompatible) = future_incompatible {
355368
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {

compiler/rustc_session/src/session.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl Session {
323323
.into_iter()
324324
.map(|diag| {
325325
let lint_name = match &diag.code {
326-
Some(DiagnosticId::Lint { name, has_future_breakage: true }) => name,
326+
Some(DiagnosticId::Lint { name, has_future_breakage: true, .. }) => name,
327327
_ => panic!("Unexpected code in diagnostic {:?}", diag),
328328
};
329329
let lint = lint_store.name_to_lint(&lint_name);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// compile-flags: --cap-lints allow --force-warns bare_trait_objects -Zunstable-options
2+
// check-pass
3+
4+
pub trait SomeTrait {}
5+
6+
pub fn function(_x: Box<SomeTrait>) {}
7+
//~^ WARN trait objects without an explicit `dyn` are deprecated
8+
//~| WARN this is accepted in the current edition
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/force-warns-cap-lints.rs:6:25
3+
|
4+
LL | pub fn function(_x: Box<SomeTrait>) {}
5+
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
6+
|
7+
= note: requested on the command line with `--force-warns bare-trait-objects`
8+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
9+
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
10+
11+
warning: 1 warning emitted
12+

0 commit comments

Comments
 (0)