Skip to content

Commit 69dc318

Browse files
Rollup merge of #153452 - GuillaumeGomez:migrate-diag, r=JonathanBrouwer
Cleanup unused diagnostic emission methods Part of #153099. To remove `lint_level`, we need to remove all functions calling it. One of them is `TyCtxt::node_span_lint`, so removing it. r? @JonathanBrouwer
2 parents bdaa048 + e01a7e7 commit 69dc318

44 files changed

Lines changed: 1117 additions & 751 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_hir::attrs::{
55
use rustc_hir::def::DefKind;
66
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
77
use rustc_hir::{self as hir, Attribute, find_attr};
8+
use rustc_macros::Diagnostic;
89
use rustc_middle::middle::codegen_fn_attrs::{
910
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
1011
};
@@ -385,6 +386,17 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
385386
}
386387
}
387388

389+
#[derive(Diagnostic)]
390+
#[diag("non-default `sanitize` will have no effect after inlining")]
391+
struct SanitizeOnInline {
392+
#[note("inlining requested here")]
393+
inline_span: Span,
394+
}
395+
396+
#[derive(Diagnostic)]
397+
#[diag("the async executor can run blocking code, without realtime sanitizer catching it")]
398+
struct AsyncBlocking;
399+
388400
fn check_result(
389401
tcx: TyCtxt<'_>,
390402
did: LocalDefId,
@@ -425,10 +437,12 @@ fn check_result(
425437
(interesting_spans.sanitize, interesting_spans.inline)
426438
{
427439
let hir_id = tcx.local_def_id_to_hir_id(did);
428-
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| {
429-
lint.primary_message("non-default `sanitize` will have no effect after inlining");
430-
lint.span_note(inline_span, "inlining requested here");
431-
})
440+
tcx.emit_node_span_lint(
441+
lint::builtin::INLINE_NO_SANITIZE,
442+
hir_id,
443+
sanitize_span,
444+
SanitizeOnInline { inline_span },
445+
)
432446
}
433447

434448
// warn for nonblocking async functions, blocks and closures.
@@ -445,13 +459,11 @@ fn check_result(
445459
!= rustc_hir::ClosureKind::Closure))
446460
{
447461
let hir_id = tcx.local_def_id_to_hir_id(did);
448-
tcx.node_span_lint(
462+
tcx.emit_node_span_lint(
449463
lint::builtin::RTSAN_NONBLOCKING_ASYNC,
450464
hir_id,
451465
sanitize_span,
452-
|lint| {
453-
lint.primary_message(r#"the async executor can run blocking code, without realtime sanitizer catching it"#);
454-
}
466+
AsyncBlocking,
455467
);
456468
}
457469

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
106106
pub trait Diagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
107107
/// Write out as a diagnostic out of `DiagCtxt`.
108108
#[must_use]
109+
#[track_caller]
109110
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G>;
110111
}
111112

@@ -139,15 +140,15 @@ where
139140
}
140141

141142
#[derive(Clone, Debug, Encodable, Decodable)]
142-
pub(crate) struct DiagLocation {
143+
pub struct DiagLocation {
143144
file: Cow<'static, str>,
144145
line: u32,
145146
col: u32,
146147
}
147148

148149
impl DiagLocation {
149150
#[track_caller]
150-
fn caller() -> Self {
151+
pub fn caller() -> Self {
151152
let loc = panic::Location::caller();
152153
DiagLocation { file: loc.file().into(), line: loc.line(), col: loc.column() }
153154
}
@@ -248,7 +249,7 @@ pub struct DiagInner {
248249
pub long_ty_path: Option<PathBuf>,
249250
/// With `-Ztrack_diagnostics` enabled,
250251
/// we print where in rustc this error was emitted.
251-
pub(crate) emitted_at: DiagLocation,
252+
pub emitted_at: DiagLocation,
252253
}
253254

254255
impl DiagInner {

compiler/rustc_errors/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ pub use anstyle::{
3737
pub use codes::*;
3838
pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
3939
pub use diagnostic::{
40-
BugAbort, Diag, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee, FatalAbort,
41-
StringPart, Subdiag, Subdiagnostic,
40+
BugAbort, Diag, DiagInner, DiagLocation, DiagStyledString, Diagnostic, EmissionGuarantee,
41+
FatalAbort, StringPart, Subdiag, Subdiagnostic,
4242
};
4343
pub use diagnostic_impls::{
4444
DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ use std::ops::ControlFlow;
44
use rustc_abi::{ExternAbi, FieldIdx, ScalableElt};
55
use rustc_data_structures::unord::{UnordMap, UnordSet};
66
use rustc_errors::codes::*;
7-
use rustc_errors::{EmissionGuarantee, MultiSpan};
7+
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan};
88
use rustc_hir as hir;
99
use rustc_hir::attrs::ReprAttr::ReprPacked;
1010
use rustc_hir::def::{CtorKind, DefKind};
1111
use rustc_hir::{LangItem, Node, find_attr, intravisit};
1212
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1313
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
1414
use rustc_lint_defs::builtin::{REPR_TRANSPARENT_NON_ZST_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS};
15+
use rustc_macros::Diagnostic;
1516
use rustc_middle::hir::nested_filter;
1617
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
1718
use rustc_middle::middle::stability::EvalResult;
@@ -53,6 +54,22 @@ fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T
5354
}
5455

5556
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
57+
struct UnsupportedCallingConventions {
58+
abi: ExternAbi,
59+
}
60+
61+
impl<'a> Diagnostic<'a, ()> for UnsupportedCallingConventions {
62+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
63+
let Self { abi } = self;
64+
let mut lint = Diag::new(
65+
dcx,
66+
level,
67+
format!("{abi} is not a supported ABI for the current target"),
68+
);
69+
add_abi_diag_help(abi, &mut lint);
70+
lint
71+
}
72+
}
5673
// FIXME: This should be checked earlier, e.g. in `rustc_ast_lowering`, as this
5774
// currently only guards function imports, function definitions, and function pointer types.
5875
// Functions in trait declarations can still use "deprecated" ABIs without any warning.
@@ -64,12 +81,12 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi
6481
tcx.dcx().span_delayed_bug(span, format!("{abi} should be rejected in ast_lowering"));
6582
}
6683
AbiMapping::Deprecated(..) => {
67-
tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
68-
lint.primary_message(format!(
69-
"{abi} is not a supported ABI for the current target"
70-
));
71-
add_abi_diag_help(abi, lint);
72-
});
84+
tcx.emit_node_span_lint(
85+
UNSUPPORTED_CALLING_CONVENTIONS,
86+
hir_id,
87+
span,
88+
UnsupportedCallingConventions { abi },
89+
);
7390
}
7491
}
7592
}
@@ -174,6 +191,11 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
174191

175192
/// Check that a `static` is inhabited.
176193
fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
194+
#[derive(Diagnostic)]
195+
#[diag("static of uninhabited type")]
196+
#[note("uninhabited statics cannot be initialized, and any access would be an immediate error")]
197+
struct StaticOfUninhabitedType;
198+
177199
// Make sure statics are inhabited.
178200
// Other parts of the compiler assume that there are no uninhabited places. In principle it
179201
// would be enough to check this for `extern` statics, as statics with an initializer will
@@ -204,15 +226,11 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
204226
}
205227
};
206228
if layout.is_uninhabited() {
207-
tcx.node_span_lint(
229+
tcx.emit_node_span_lint(
208230
UNINHABITED_STATIC,
209231
tcx.local_def_id_to_hir_id(def_id),
210232
span,
211-
|lint| {
212-
lint.primary_message("static of uninhabited type");
213-
lint
214-
.note("uninhabited statics cannot be initialized, and any access would be an immediate error");
215-
},
233+
StaticOfUninhabitedType,
216234
);
217235
}
218236
}
@@ -1637,6 +1655,39 @@ pub(super) fn check_packed_inner(
16371655
}
16381656

16391657
pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
1658+
struct ZeroSizedFieldReprTransparentIncompatibility<'tcx> {
1659+
unsuited: UnsuitedInfo<'tcx>,
1660+
}
1661+
1662+
impl<'a, 'tcx> Diagnostic<'a, ()> for ZeroSizedFieldReprTransparentIncompatibility<'tcx> {
1663+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
1664+
let Self { unsuited } = self;
1665+
let (title, note) = match unsuited.reason {
1666+
UnsuitedReason::NonExhaustive => (
1667+
"external non-exhaustive types",
1668+
"is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.",
1669+
),
1670+
UnsuitedReason::PrivateField => (
1671+
"external types with private fields",
1672+
"contains private fields, so it could become non-zero-sized in the future.",
1673+
),
1674+
UnsuitedReason::ReprC => (
1675+
"`repr(C)` types",
1676+
"is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.",
1677+
),
1678+
};
1679+
Diag::new(
1680+
dcx,
1681+
level,
1682+
format!("zero-sized fields in `repr(transparent)` cannot contain {title}"),
1683+
)
1684+
.with_note(format!(
1685+
"this field contains `{field_ty}`, which {note}",
1686+
field_ty = unsuited.ty,
1687+
))
1688+
}
1689+
}
1690+
16401691
if !adt.repr().transparent() {
16411692
return;
16421693
}
@@ -1747,29 +1798,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
17471798
// If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
17481799
// Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
17491800
if non_trivial_count > 0 || prev_unsuited_1zst {
1750-
tcx.node_span_lint(
1801+
tcx.emit_node_span_lint(
17511802
REPR_TRANSPARENT_NON_ZST_FIELDS,
17521803
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
17531804
field.span,
1754-
|lint| {
1755-
let title = match unsuited.reason {
1756-
UnsuitedReason::NonExhaustive => "external non-exhaustive types",
1757-
UnsuitedReason::PrivateField => "external types with private fields",
1758-
UnsuitedReason::ReprC => "`repr(C)` types",
1759-
};
1760-
lint.primary_message(
1761-
format!("zero-sized fields in `repr(transparent)` cannot contain {title}"),
1762-
);
1763-
let note = match unsuited.reason {
1764-
UnsuitedReason::NonExhaustive => "is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.",
1765-
UnsuitedReason::PrivateField => "contains private fields, so it could become non-zero-sized in the future.",
1766-
UnsuitedReason::ReprC => "is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.",
1767-
};
1768-
lint.note(format!(
1769-
"this field contains `{field_ty}`, which {note}",
1770-
field_ty = unsuited.ty,
1771-
));
1772-
},
1805+
ZeroSizedFieldReprTransparentIncompatibility { unsuited },
17731806
);
17741807
} else {
17751808
prev_unsuited_1zst = true;

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use std::num::NonZero;
7777
pub use check::{check_abi, check_custom_abi};
7878
use rustc_abi::VariantIdx;
7979
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
80-
use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};
80+
use rustc_errors::{ErrorGuaranteed, pluralize, struct_span_code_err};
8181
use rustc_hir::LangItem;
8282
use rustc_hir::def_id::{DefId, LocalDefId};
8383
use rustc_hir::intravisit::Visitor;

compiler/rustc_hir_analysis/src/check_unused.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
use rustc_data_structures::unord::{ExtendUnord, UnordSet};
2+
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level};
23
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::LocalDefId;
45
use rustc_middle::ty::TyCtxt;
56
use rustc_session::lint;
7+
use rustc_span::Span;
68
use tracing::debug;
79

10+
struct UnusedImport<'tcx> {
11+
tcx: TyCtxt<'tcx>,
12+
span: Span,
13+
}
14+
15+
impl<'a, 'tcx> Diagnostic<'a, ()> for UnusedImport<'tcx> {
16+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
17+
let Self { tcx, span } = self;
18+
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
19+
Diag::new(dcx, level, format!("unused import: `{snippet}`"))
20+
} else {
21+
Diag::new(dcx, level, "unused import")
22+
}
23+
}
24+
}
25+
826
pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
927
let mut used_trait_imports = UnordSet::<LocalDefId>::default();
1028

@@ -31,12 +49,11 @@ pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
3149
continue;
3250
}
3351
let (path, _) = item.expect_use();
34-
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
35-
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
36-
lint.primary_message(format!("unused import: `{snippet}`"));
37-
} else {
38-
lint.primary_message("unused import");
39-
}
40-
});
52+
tcx.emit_node_span_lint(
53+
lint::builtin::UNUSED_IMPORTS,
54+
item.hir_id(),
55+
path.span,
56+
UnusedImport { tcx, span: path.span },
57+
);
4158
}
4259
}

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use rustc_abi::{ExternAbi, Size};
2222
use rustc_ast::Recovered;
2323
use rustc_data_structures::assert_matches;
2424
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
25-
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey};
25+
use rustc_errors::{
26+
Applicability, Diag, DiagCtxtHandle, Diagnostic, E0228, ErrorGuaranteed, Level, StashKey,
27+
};
2628
use rustc_hir::def::{DefKind, Res};
2729
use rustc_hir::def_id::{DefId, LocalDefId};
2830
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
@@ -610,6 +612,19 @@ pub(super) fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
610612
}
611613

612614
pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
615+
struct ReprCIssue {
616+
msg: &'static str,
617+
}
618+
619+
impl<'a> Diagnostic<'a, ()> for ReprCIssue {
620+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
621+
let Self { msg } = self;
622+
Diag::new(dcx, level, msg)
623+
.with_note("`repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C")
624+
.with_help("use `repr($int_ty)` instead to explicitly set the size of this enum")
625+
}
626+
}
627+
613628
let def = tcx.adt_def(def_id);
614629
let repr_type = def.repr().discr_type();
615630
let initial = repr_type.initial_discriminant(tcx);
@@ -659,15 +674,11 @@ pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
659674
} else {
660675
"`repr(C)` enum discriminant does not fit into C `int`, and a previous discriminant does not fit into C `unsigned int`"
661676
};
662-
tcx.node_span_lint(
677+
tcx.emit_node_span_lint(
663678
rustc_session::lint::builtin::REPR_C_ENUMS_LARGER_THAN_INT,
664679
tcx.local_def_id_to_hir_id(def_id),
665680
span,
666-
|d| {
667-
d.primary_message(msg)
668-
.note("`repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C")
669-
.help("use `repr($int_ty)` instead to explicitly set the size of this enum");
670-
}
681+
ReprCIssue { msg },
671682
);
672683
}
673684
}

0 commit comments

Comments
 (0)