1
Fork 0

Split ExpectationLintId off Level

This commit is contained in:
Oli Scherer 2025-03-18 17:18:54 +00:00
parent b6d74b5e15
commit f3eaf1624c
5 changed files with 48 additions and 34 deletions

View file

@ -91,13 +91,13 @@ fn annotation_level_for_level(level: Level) -> annotate_snippets::Level {
Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => { Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => {
annotate_snippets::Level::Error annotate_snippets::Level::Error
} }
Level::ForceWarning(_) | Level::Warning => annotate_snippets::Level::Warning, Level::ForceWarning | Level::Warning => annotate_snippets::Level::Warning,
Level::Note | Level::OnceNote => annotate_snippets::Level::Note, Level::Note | Level::OnceNote => annotate_snippets::Level::Note,
Level::Help | Level::OnceHelp => annotate_snippets::Level::Help, Level::Help | Level::OnceHelp => annotate_snippets::Level::Help,
// FIXME(#59346): Not sure how to map this level // FIXME(#59346): Not sure how to map this level
Level::FailureNote => annotate_snippets::Level::Error, Level::FailureNote => annotate_snippets::Level::Error,
Level::Allow => panic!("Should not call with Allow"), Level::Allow => panic!("Should not call with Allow"),
Level::Expect(_) => panic!("Should not call with Expect"), Level::Expect => panic!("Should not call with Expect"),
} }
} }

View file

@ -9,7 +9,7 @@ use std::thread::panicking;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_error_messages::{FluentValue, fluent_value_from_str_list_sep_by_and}; use rustc_error_messages::{FluentValue, fluent_value_from_str_list_sep_by_and};
use rustc_lint_defs::Applicability; use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_macros::{Decodable, Encodable}; use rustc_macros::{Decodable, Encodable};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_span::{DUMMY_SP, Span, Symbol};
@ -296,6 +296,7 @@ pub struct DiagInner {
pub messages: Vec<(DiagMessage, Style)>, pub messages: Vec<(DiagMessage, Style)>,
pub code: Option<ErrCode>, pub code: Option<ErrCode>,
pub lint_id: Option<LintExpectationId>,
pub span: MultiSpan, pub span: MultiSpan,
pub children: Vec<Subdiag>, pub children: Vec<Subdiag>,
pub suggestions: Suggestions, pub suggestions: Suggestions,
@ -324,6 +325,7 @@ impl DiagInner {
pub fn new_with_messages(level: Level, messages: Vec<(DiagMessage, Style)>) -> Self { pub fn new_with_messages(level: Level, messages: Vec<(DiagMessage, Style)>) -> Self {
DiagInner { DiagInner {
level, level,
lint_id: None,
messages, messages,
code: None, code: None,
span: MultiSpan::new(), span: MultiSpan::new(),
@ -346,7 +348,7 @@ impl DiagInner {
match self.level { match self.level {
Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true, Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,
Level::ForceWarning(_) Level::ForceWarning
| Level::Warning | Level::Warning
| Level::Note | Level::Note
| Level::OnceNote | Level::OnceNote
@ -354,7 +356,7 @@ impl DiagInner {
| Level::OnceHelp | Level::OnceHelp
| Level::FailureNote | Level::FailureNote
| Level::Allow | Level::Allow
| Level::Expect(_) => false, | Level::Expect => false,
} }
} }
@ -365,7 +367,7 @@ impl DiagInner {
pub(crate) fn is_force_warn(&self) -> bool { pub(crate) fn is_force_warn(&self) -> bool {
match self.level { match self.level {
Level::ForceWarning(_) => { Level::ForceWarning => {
assert!(self.is_lint.is_some()); assert!(self.is_lint.is_some());
true true
} }
@ -1259,6 +1261,17 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
self self
} } } }
with_fn! { with_lint_id,
/// Add an argument.
#[rustc_lint_diagnostics]
pub fn lint_id(
&mut self,
id: LintExpectationId,
) -> &mut Self {
self.lint_id = Some(id);
self
} }
with_fn! { with_primary_message, with_fn! { with_primary_message,
/// Add a primary message. /// Add a primary message.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]

View file

@ -144,7 +144,7 @@ impl Emitter for JsonEmitter {
// //
// So to avoid ICEs and confused users we "upgrade" the lint level for // So to avoid ICEs and confused users we "upgrade" the lint level for
// those `FutureBreakageItem` to warn. // those `FutureBreakageItem` to warn.
if matches!(diag.level, crate::Level::Allow | crate::Level::Expect(..)) { if matches!(diag.level, crate::Level::Allow | crate::Level::Expect) {
diag.level = crate::Level::Warning; diag.level = crate::Level::Warning;
} }
FutureBreakageItem { FutureBreakageItem {

View file

@ -905,8 +905,8 @@ impl<'a> DiagCtxtHandle<'a> {
DelayedBug => { DelayedBug => {
return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors); return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
} }
ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
| Expect(_) => None, | Expect => None,
}; };
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
@ -1045,7 +1045,7 @@ impl<'a> DiagCtxtHandle<'a> {
// Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
// configuration like `--cap-lints allow --force-warn bare_trait_objects`. // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
inner.emit_diagnostic( inner.emit_diagnostic(
DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)), DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
None, None,
); );
} }
@ -1450,7 +1450,7 @@ impl<'a> DiagCtxtHandle<'a> {
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> { pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
Diag::new(self, Expect(id), msg) Diag::new(self, Expect, msg).with_lint_id(id)
} }
} }
@ -1510,7 +1510,7 @@ impl DiagCtxtInner {
// Future breakages aren't emitted if they're `Level::Allow` or // Future breakages aren't emitted if they're `Level::Allow` or
// `Level::Expect`, but they still need to be constructed and // `Level::Expect`, but they still need to be constructed and
// stashed below, so they'll trigger the must_produce_diag check. // stashed below, so they'll trigger the must_produce_diag check.
assert_matches!(diagnostic.level, Error | Warning | Allow | Expect(_)); assert_matches!(diagnostic.level, Error | Warning | Allow | Expect);
self.future_breakage_diagnostics.push(diagnostic.clone()); self.future_breakage_diagnostics.push(diagnostic.clone());
} }
@ -1558,7 +1558,7 @@ impl DiagCtxtInner {
}; };
} }
} }
ForceWarning(None) => {} // `ForceWarning(Some(...))` is below, with `Expect` ForceWarning if diagnostic.lint_id.is_none() => {} // `ForceWarning(Some(...))` is below, with `Expect`
Warning => { Warning => {
if !self.flags.can_emit_warnings { if !self.flags.can_emit_warnings {
// We are not emitting warnings. // We are not emitting warnings.
@ -1580,9 +1580,9 @@ impl DiagCtxtInner {
} }
return None; return None;
} }
Expect(expect_id) | ForceWarning(Some(expect_id)) => { Expect | ForceWarning => {
self.fulfilled_expectations.insert(expect_id); self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
if let Expect(_) = diagnostic.level { if let Expect = diagnostic.level {
// Nothing emitted here for expected lints. // Nothing emitted here for expected lints.
TRACK_DIAGNOSTIC(diagnostic, &mut |_| None); TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
self.suppressed_expected_diag = true; self.suppressed_expected_diag = true;
@ -1631,7 +1631,7 @@ impl DiagCtxtInner {
if is_error { if is_error {
self.deduplicated_err_count += 1; self.deduplicated_err_count += 1;
} else if matches!(diagnostic.level, ForceWarning(_) | Warning) { } else if matches!(diagnostic.level, ForceWarning | Warning) {
self.deduplicated_warn_count += 1; self.deduplicated_warn_count += 1;
} }
self.has_printed = true; self.has_printed = true;
@ -1899,9 +1899,9 @@ pub enum Level {
/// A `force-warn` lint warning about the code being compiled. Does not prevent compilation /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
/// from finishing. /// from finishing.
/// ///
/// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this /// Requires a [`LintExpectationId`] for expected lint diagnostics. In all other cases this
/// should be `None`. /// should be `None`.
ForceWarning(Option<LintExpectationId>), ForceWarning,
/// A warning about the code being compiled. Does not prevent compilation from finishing. /// A warning about the code being compiled. Does not prevent compilation from finishing.
/// Will be skipped if `can_emit_warnings` is false. /// Will be skipped if `can_emit_warnings` is false.
@ -1926,8 +1926,8 @@ pub enum Level {
/// Only used for lints. /// Only used for lints.
Allow, Allow,
/// Only used for lints. /// Only used for lints. Requires a [`LintExpectationId`] for silencing the lints.
Expect(LintExpectationId), Expect,
} }
impl fmt::Display for Level { impl fmt::Display for Level {
@ -1943,7 +1943,7 @@ impl Level {
Bug | Fatal | Error | DelayedBug => { Bug | Fatal | Error | DelayedBug => {
spec.set_fg(Some(Color::Red)).set_intense(true); spec.set_fg(Some(Color::Red)).set_intense(true);
} }
ForceWarning(_) | Warning => { ForceWarning | Warning => {
spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows));
} }
Note | OnceNote => { Note | OnceNote => {
@ -1953,7 +1953,7 @@ impl Level {
spec.set_fg(Some(Color::Cyan)).set_intense(true); spec.set_fg(Some(Color::Cyan)).set_intense(true);
} }
FailureNote => {} FailureNote => {}
Allow | Expect(_) => unreachable!(), Allow | Expect => unreachable!(),
} }
spec spec
} }
@ -1962,11 +1962,11 @@ impl Level {
match self { match self {
Bug | DelayedBug => "error: internal compiler error", Bug | DelayedBug => "error: internal compiler error",
Fatal | Error => "error", Fatal | Error => "error",
ForceWarning(_) | Warning => "warning", ForceWarning | Warning => "warning",
Note | OnceNote => "note", Note | OnceNote => "note",
Help | OnceHelp => "help", Help | OnceHelp => "help",
FailureNote => "failure-note", FailureNote => "failure-note",
Allow | Expect(_) => unreachable!(), Allow | Expect => unreachable!(),
} }
} }
@ -1977,8 +1977,7 @@ impl Level {
// Can this level be used in a subdiagnostic message? // Can this level be used in a subdiagnostic message?
fn can_be_subdiag(&self) -> bool { fn can_be_subdiag(&self) -> bool {
match self { match self {
Bug | DelayedBug | Fatal | Error | ForceWarning(_) | FailureNote | Allow Bug | DelayedBug | Fatal | Error | ForceWarning | FailureNote | Allow | Expect => false,
| Expect(_) => false,
Warning | Note | Help | OnceNote | OnceHelp => true, Warning | Note | Help | OnceNote | OnceHelp => true,
} }

View file

@ -293,10 +293,10 @@ pub fn lint_level(
); );
// Convert lint level to error level. // Convert lint level to error level.
let err_level = match level { let (err_level, lint_id) = match level {
Level::Allow => { Level::Allow => {
if has_future_breakage { if has_future_breakage {
rustc_errors::Level::Allow (rustc_errors::Level::Allow, None)
} else { } else {
return; return;
} }
@ -309,17 +309,19 @@ pub fn lint_level(
// We can also not mark the lint expectation as fulfilled here right away, as it // We can also not mark the lint expectation as fulfilled here right away, as it
// can still be cancelled in the decorate function. All of this means that we simply // can still be cancelled in the decorate function. All of this means that we simply
// create a `Diag` and continue as we would for warnings. // create a `Diag` and continue as we would for warnings.
rustc_errors::Level::Expect(expect_id) (rustc_errors::Level::Expect, Some(expect_id))
} }
Level::ForceWarn(Some(expect_id)) => rustc_errors::Level::ForceWarning(Some(expect_id)), Level::ForceWarn(expect_id) => (rustc_errors::Level::ForceWarning, expect_id),
Level::ForceWarn(None) => rustc_errors::Level::ForceWarning(None), Level::Warn => (rustc_errors::Level::Warning, None),
Level::Warn => rustc_errors::Level::Warning, Level::Deny | Level::Forbid => (rustc_errors::Level::Error, None),
Level::Deny | Level::Forbid => rustc_errors::Level::Error,
}; };
let mut err = Diag::new(sess.dcx(), err_level, ""); let mut err = Diag::new(sess.dcx(), err_level, "");
if let Some(span) = span { if let Some(span) = span {
err.span(span); err.span(span);
} }
if let Some(lint_id) = lint_id {
err.lint_id(lint_id);
}
// If this code originates in a foreign macro, aka something that this crate // If this code originates in a foreign macro, aka something that this crate
// did not itself author, then it's likely that there's nothing this crate // did not itself author, then it's likely that there's nothing this crate