Skip to content

Commit 16f4b02

Browse files
committed
Auto merge of #119922 - nnethercote:fix-Diag-code-is_lint, r=oli-obk
Rework how diagnostic lints are stored. `Diagnostic::code` has the type `DiagnosticId`, which has `Error` and `Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be redundant w.r.t. `Diagnostic::code`. Seems simple. Except it's possible for a lint to have an error code, in which case its `code` field is recorded as `Error`, and `is_lint` is required to indicate that it's a lint. This is what happens with `derive(LintDiagnostic)` lints. Which means those lints don't have a lint name or a `has_future_breakage` field because those are stored in the `DiagnosticId::Lint`. It's all a bit messy and confused and seems unintentional. This commit: - removes `DiagnosticId`; - changes `Diagnostic::code` to `Option<String>`, which means both errors and lints can straightforwardly have an error code; - changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a new type containing a lint name and a `has_future_breakage` bool, so all lints can have those, error code or not. r? `@oli-obk`
2 parents f45fe57 + d71f535 commit 16f4b02

File tree

24 files changed

+111
-135
lines changed

24 files changed

+111
-135
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_data_structures::memmap::Mmap;
1414
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
1515
use rustc_data_structures::sync::Lrc;
1616
use rustc_errors::emitter::Emitter;
17-
use rustc_errors::{translation::Translate, DiagCtxt, DiagnosticId, FatalError, Level};
17+
use rustc_errors::{translation::Translate, DiagCtxt, FatalError, Level};
1818
use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Style};
1919
use rustc_fs_util::link_or_copy;
2020
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -1000,7 +1000,7 @@ type DiagnosticArgName<'source> = Cow<'source, str>;
10001000
struct Diagnostic {
10011001
msgs: Vec<(DiagnosticMessage, Style)>,
10021002
args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>,
1003-
code: Option<DiagnosticId>,
1003+
code: Option<String>,
10041004
lvl: Level,
10051005
}
10061006

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::emitter::FileWithAnnotatedLines;
99
use crate::snippet::Line;
1010
use crate::translation::{to_fluent_args, Translate};
1111
use crate::{
12-
CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle,
13-
LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
12+
CodeSuggestion, Diagnostic, DiagnosticMessage, Emitter, FluentBundle, LazyFallbackBundle,
13+
Level, MultiSpan, Style, SubDiagnostic,
1414
};
1515
use annotate_snippets::{Annotation, AnnotationType, Renderer, Slice, Snippet, SourceAnnotation};
1616
use rustc_data_structures::sync::Lrc;
@@ -127,7 +127,7 @@ impl AnnotateSnippetEmitter {
127127
level: &Level,
128128
messages: &[(DiagnosticMessage, Style)],
129129
args: &FluentArgs<'_>,
130-
code: &Option<DiagnosticId>,
130+
code: &Option<String>,
131131
msp: &MultiSpan,
132132
_children: &[SubDiagnostic],
133133
_suggestions: &[CodeSuggestion],
@@ -181,11 +181,7 @@ impl AnnotateSnippetEmitter {
181181
let snippet = Snippet {
182182
title: Some(Annotation {
183183
label: Some(&message),
184-
id: code.as_ref().map(|c| match c {
185-
DiagnosticId::Error(val) | DiagnosticId::Lint { name: val, .. } => {
186-
val.as_str()
187-
}
188-
}),
184+
id: code.as_deref(),
189185
annotation_type: annotation_type_for_level(*level),
190186
}),
191187
footer: vec![],

compiler/rustc_errors/src/diagnostic.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub struct Diagnostic {
104104
pub(crate) level: Level,
105105

106106
pub messages: Vec<(DiagnosticMessage, Style)>,
107-
pub code: Option<DiagnosticId>,
107+
pub code: Option<String>,
108108
pub span: MultiSpan,
109109
pub children: Vec<SubDiagnostic>,
110110
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
@@ -115,9 +115,9 @@ pub struct Diagnostic {
115115
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
116116
pub sort_span: Span,
117117

118-
/// If diagnostic is from Lint, custom hash function ignores notes
119-
/// otherwise hash is based on the all the fields
120-
pub is_lint: bool,
118+
/// If diagnostic is from Lint, custom hash function ignores children.
119+
/// Otherwise hash is based on the all the fields.
120+
pub is_lint: Option<IsLint>,
121121

122122
/// With `-Ztrack_diagnostics` enabled,
123123
/// we print where in rustc this error was emitted.
@@ -146,13 +146,11 @@ impl fmt::Display for DiagnosticLocation {
146146
}
147147

148148
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
149-
pub enum DiagnosticId {
150-
Error(String),
151-
Lint {
152-
name: String,
153-
/// Indicates whether this lint should show up in cargo's future breakage report.
154-
has_future_breakage: bool,
155-
},
149+
pub struct IsLint {
150+
/// The lint name.
151+
pub(crate) name: String,
152+
/// Indicates whether this lint should show up in cargo's future breakage report.
153+
has_future_breakage: bool,
156154
}
157155

158156
/// A "sub"-diagnostic attached to a parent diagnostic.
@@ -231,7 +229,7 @@ impl Diagnostic {
231229
suggestions: Ok(vec![]),
232230
args: Default::default(),
233231
sort_span: DUMMY_SP,
234-
is_lint: false,
232+
is_lint: None,
235233
emitted_at: DiagnosticLocation::caller(),
236234
}
237235
}
@@ -288,16 +286,13 @@ impl Diagnostic {
288286

289287
/// Indicates whether this diagnostic should show up in cargo's future breakage report.
290288
pub(crate) fn has_future_breakage(&self) -> bool {
291-
match self.code {
292-
Some(DiagnosticId::Lint { has_future_breakage, .. }) => has_future_breakage,
293-
_ => false,
294-
}
289+
matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. }))
295290
}
296291

297292
pub(crate) fn is_force_warn(&self) -> bool {
298293
match self.level {
299294
Level::ForceWarning(_) => {
300-
assert!(self.is_lint);
295+
assert!(self.is_lint.is_some());
301296
true
302297
}
303298
_ => false,
@@ -893,12 +888,12 @@ impl Diagnostic {
893888
self
894889
}
895890

896-
pub fn is_lint(&mut self) -> &mut Self {
897-
self.is_lint = true;
891+
pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
892+
self.is_lint = Some(IsLint { name, has_future_breakage });
898893
self
899894
}
900895

901-
pub fn code(&mut self, s: DiagnosticId) -> &mut Self {
896+
pub fn code(&mut self, s: String) -> &mut Self {
902897
self.code = Some(s);
903898
self
904899
}
@@ -908,8 +903,8 @@ impl Diagnostic {
908903
self
909904
}
910905

911-
pub fn get_code(&self) -> Option<DiagnosticId> {
912-
self.code.clone()
906+
pub fn get_code(&self) -> Option<&str> {
907+
self.code.as_deref()
913908
}
914909

915910
pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
@@ -995,7 +990,8 @@ impl Diagnostic {
995990
&Level,
996991
&[(DiagnosticMessage, Style)],
997992
Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>,
998-
&Option<DiagnosticId>,
993+
&Option<String>,
994+
&Option<IsLint>,
999995
&MultiSpan,
1000996
&Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
1001997
Option<&[SubDiagnostic]>,
@@ -1005,9 +1001,10 @@ impl Diagnostic {
10051001
&self.messages,
10061002
self.args().collect(),
10071003
&self.code,
1004+
&self.is_lint,
10081005
&self.span,
10091006
&self.suggestions,
1010-
(if self.is_lint { None } else { Some(&self.children) }),
1007+
(if self.is_lint.is_some() { None } else { Some(&self.children) }),
10111008
)
10121009
}
10131010
}

compiler/rustc_errors/src/diagnostic_builder.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::diagnostic::IntoDiagnosticArg;
22
use crate::{DiagCtxt, Level, MultiSpan, StashKey};
33
use crate::{
4-
Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed,
5-
ExplicitBug, SubdiagnosticMessage,
4+
Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, ExplicitBug,
5+
SubdiagnosticMessage,
66
};
77
use rustc_lint_defs::Applicability;
88
use rustc_span::source_map::Spanned;
@@ -395,8 +395,11 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
395395
forward!((span, with_span)(
396396
sp: impl Into<MultiSpan>,
397397
));
398+
forward!((is_lint, with_is_lint)(
399+
name: String, has_future_breakage: bool,
400+
));
398401
forward!((code, with_code)(
399-
s: DiagnosticId,
402+
s: String,
400403
));
401404
forward!((arg, with_arg)(
402405
name: impl Into<Cow<'static, str>>, arg: impl IntoDiagnosticArg,
@@ -437,15 +440,11 @@ impl<G: EmissionGuarantee> Drop for DiagnosticBuilder<'_, G> {
437440
#[macro_export]
438441
macro_rules! struct_span_code_err {
439442
($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({
440-
$dcx.struct_span_err(
441-
$span,
442-
format!($($message)*),
443-
)
444-
.with_code($crate::error_code!($code))
443+
$dcx.struct_span_err($span, format!($($message)*)).with_code($crate::error_code!($code))
445444
})
446445
}
447446

448447
#[macro_export]
449448
macro_rules! error_code {
450-
($code:ident) => {{ $crate::DiagnosticId::Error(stringify!($code).to_owned()) }};
449+
($code:ident) => {{ stringify!($code).to_owned() }};
451450
}

compiler/rustc_errors/src/emitter.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use crate::snippet::{
1616
use crate::styled_buffer::StyledBuffer;
1717
use crate::translation::{to_fluent_args, Translate};
1818
use crate::{
19-
diagnostic::DiagnosticLocation, CodeSuggestion, DiagCtxt, Diagnostic, DiagnosticId,
20-
DiagnosticMessage, FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
21-
SubstitutionHighlight, SuggestionStyle, TerminalUrl,
19+
diagnostic::DiagnosticLocation, CodeSuggestion, DiagCtxt, Diagnostic, DiagnosticMessage,
20+
FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
21+
SuggestionStyle, TerminalUrl,
2222
};
2323
use rustc_lint_defs::pluralize;
2424

@@ -1309,7 +1309,7 @@ impl HumanEmitter {
13091309
msp: &MultiSpan,
13101310
msgs: &[(DiagnosticMessage, Style)],
13111311
args: &FluentArgs<'_>,
1312-
code: &Option<DiagnosticId>,
1312+
code: &Option<String>,
13131313
level: &Level,
13141314
max_line_num_len: usize,
13151315
is_secondary: bool,
@@ -1336,14 +1336,13 @@ impl HumanEmitter {
13361336
buffer.append(0, level.to_str(), Style::Level(*level));
13371337
label_width += level.to_str().len();
13381338
}
1339-
// only render error codes, not lint codes
1340-
if let Some(DiagnosticId::Error(ref code)) = *code {
1339+
if let Some(code) = code {
13411340
buffer.append(0, "[", Style::Level(*level));
13421341
let code = if let TerminalUrl::Yes = self.terminal_url {
13431342
let path = "https://doc.rust-lang.org/error_codes";
1344-
format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07")
1343+
Cow::Owned(format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07"))
13451344
} else {
1346-
code.clone()
1345+
Cow::Borrowed(code)
13471346
};
13481347
buffer.append(0, &code, Style::Level(*level));
13491348
buffer.append(0, "]", Style::Level(*level));
@@ -2077,7 +2076,7 @@ impl HumanEmitter {
20772076
level: &Level,
20782077
messages: &[(DiagnosticMessage, Style)],
20792078
args: &FluentArgs<'_>,
2080-
code: &Option<DiagnosticId>,
2079+
code: &Option<String>,
20812080
span: &MultiSpan,
20822081
children: &[SubDiagnostic],
20832082
suggestions: &[CodeSuggestion],

compiler/rustc_errors/src/json.rs

+17-20
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ use termcolor::{ColorSpec, WriteColor};
1515
use crate::emitter::{should_show_source_code, Emitter, HumanReadableErrorType};
1616
use crate::registry::Registry;
1717
use crate::translation::{to_fluent_args, Translate};
18-
use crate::DiagnosticId;
1918
use crate::{
20-
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
21-
TerminalUrl,
19+
diagnostic::IsLint, CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel,
20+
SubDiagnostic, TerminalUrl,
2221
};
2322
use rustc_lint_defs::Applicability;
2423

@@ -301,7 +300,8 @@ struct DiagnosticSpanMacroExpansion {
301300

302301
#[derive(Serialize)]
303302
struct DiagnosticCode {
304-
/// The code itself.
303+
/// The error code (e.g. "E1234"), if the diagnostic has one. Or the lint
304+
/// name, if it's a lint without an error code.
305305
code: String,
306306
/// An explanation for the code.
307307
explanation: Option<&'static str>,
@@ -399,9 +399,21 @@ impl Diagnostic {
399399
let output = String::from_utf8(output).unwrap();
400400

401401
let translated_message = je.translate_messages(&diag.messages, &args);
402+
403+
let code = if let Some(code) = &diag.code {
404+
Some(DiagnosticCode {
405+
code: code.to_string(),
406+
explanation: je.registry.as_ref().unwrap().try_find_description(&code).ok(),
407+
})
408+
} else if let Some(IsLint { name, .. }) = &diag.is_lint {
409+
Some(DiagnosticCode { code: name.to_string(), explanation: None })
410+
} else {
411+
None
412+
};
413+
402414
Diagnostic {
403415
message: translated_message.to_string(),
404-
code: DiagnosticCode::map_opt_string(diag.code.clone(), je),
416+
code,
405417
level: diag.level.to_str(),
406418
spans: DiagnosticSpan::from_multispan(&diag.span, &args, je),
407419
children: diag
@@ -592,18 +604,3 @@ impl DiagnosticSpanLine {
592604
.unwrap_or_else(|_| vec![])
593605
}
594606
}
595-
596-
impl DiagnosticCode {
597-
fn map_opt_string(s: Option<DiagnosticId>, je: &JsonEmitter) -> Option<DiagnosticCode> {
598-
s.map(|s| {
599-
let s = match s {
600-
DiagnosticId::Error(s) => s,
601-
DiagnosticId::Lint { name, .. } => name,
602-
};
603-
let je_result =
604-
je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();
605-
606-
DiagnosticCode { code: s, explanation: je_result.ok() }
607-
})
608-
}
609-
}

0 commit comments

Comments
 (0)