Rollup merge of #152119 - JonathanBrouwer:convert_middle, r=jdonszelmann

Convert to inline diagnostics in `rustc_middle`

For https://github.com/rust-lang/rust/issues/151366
r? @jdonszelmann
This commit is contained in:
Jonathan Brouwer 2026-02-05 12:17:01 +01:00 committed by GitHub
commit 4d535f5642
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 103 additions and 203 deletions

View file

@ -4258,7 +4258,6 @@ dependencies = [
"rustc_error_messages",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_graphviz",
"rustc_hashes",
"rustc_hir",

View file

@ -119,7 +119,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_lint::DEFAULT_LOCALE_RESOURCE,
rustc_middle::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,

View file

@ -18,7 +18,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hashes = { path = "../rustc_hashes" }
rustc_hir = { path = "../rustc_hir" }

View file

@ -1,133 +0,0 @@
middle_assert_async_resume_after_drop = `async fn` resumed after async drop
middle_assert_async_resume_after_panic = `async fn` resumed after panicking
middle_assert_async_resume_after_return = `async fn` resumed after completion
middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
middle_assert_divide_by_zero =
attempt to divide `{$val}` by zero
middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped
middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
middle_assert_invalid_enum_construction =
trying to construct an enum from an invalid value `{$source}`
middle_assert_misaligned_ptr_deref =
misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
middle_assert_null_ptr_deref =
null pointer dereference occurred
middle_assert_op_overflow =
attempt to compute `{$left} {$op} {$right}`, which would overflow
middle_assert_overflow_neg =
attempt to negate `{$val}`, which would overflow
middle_assert_remainder_by_zero =
attempt to calculate the remainder of `{$val}` with a divisor of zero
middle_assert_shl_overflow =
attempt to shift left by `{$val}`, which would overflow
middle_assert_shr_overflow =
attempt to shift right by `{$val}`, which would overflow
middle_autodiff_unsafe_inner_const_ref = reading from a `Duplicated` const {$ty} is unsafe
middle_bounds_check =
index out of bounds: the length is {$len} but the index is {$index}
middle_conflict_types =
this expression supplies two conflicting concrete types for the same opaque type
middle_consider_type_length_limit =
consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate
middle_const_eval_non_int =
constant evaluation of enum discriminant resulted in non-integer
middle_const_not_used_in_type_alias =
const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_future = use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_suggestion = replace the use of the deprecated {$kind}
middle_drop_check_overflow =
overflow while adding drop-check rules for `{$ty}`
.note = overflowed on `{$overflow_ty}`
middle_erroneous_constant = erroneous constant encountered
middle_failed_writing_file =
failed to write file {$path}: {$error}"
# Note: We only mention patterns here since the error can only occur with references, and those
# are forbidden in const generics.
middle_invalid_const_in_valtree = constant {$global_const_id} cannot be used as pattern
.note = constants that reference mutable or external memory cannot be used as patterns
middle_layout_cycle =
a cycle occurred during layout computation
middle_layout_normalization_failure =
unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
middle_layout_references_error =
the type has an unknown layout
middle_layout_simd_too_many =
the SIMD type `{$ty}` has more elements than the limit {$max_lanes}
middle_layout_simd_zero_length =
the SIMD type `{$ty}` has zero elements
middle_layout_size_overflow =
values of the type `{$ty}` are too big for the target architecture
middle_layout_too_generic = the type `{$ty}` does not have a fixed layout
middle_layout_unknown =
the type `{$ty}` has an unknown layout
middle_max_num_nodes_in_valtree = maximum number of nodes exceeded in constant {$global_const_id}
middle_opaque_hidden_type_mismatch =
concrete type differs from previous defining opaque type use
.label = expected `{$self_ty}`, got `{$other_ty}`
middle_previous_use_here =
previous use here
middle_recursion_limit_reached =
reached the recursion limit finding the struct tail for `{$ty}`
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]`
middle_requires_lang_item = requires `{$name}` lang_item
middle_strict_coherence_needs_negative_coherence =
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
.label = due to this attribute
middle_type_length_limit = reached the type-length limit while instantiating `{$instance}`
middle_unsupported_union = we don't support unions yet: '{$ty_name}'

View file

@ -9,8 +9,8 @@ use rustc_span::{Span, Symbol};
use crate::ty::{Instance, Ty};
#[derive(Diagnostic)]
#[diag(middle_drop_check_overflow, code = E0320)]
#[note]
#[diag("overflow while adding drop-check rules for `{$ty}`", code = E0320)]
#[note("overflowed on `{$overflow_ty}`")]
pub(crate) struct DropCheckOverflow<'tcx> {
#[primary_span]
pub span: Span,
@ -19,33 +19,33 @@ pub(crate) struct DropCheckOverflow<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_failed_writing_file)]
#[diag("failed to write file {$path}: {$error}\"")]
pub(crate) struct FailedWritingFile<'a> {
pub path: &'a Path,
pub error: io::Error,
}
#[derive(Diagnostic)]
#[diag(middle_opaque_hidden_type_mismatch)]
#[diag("concrete type differs from previous defining opaque type use")]
pub(crate) struct OpaqueHiddenTypeMismatch<'tcx> {
pub self_ty: Ty<'tcx>,
pub other_ty: Ty<'tcx>,
#[primary_span]
#[label]
#[label("expected `{$self_ty}`, got `{$other_ty}`")]
pub other_span: Span,
#[subdiagnostic]
pub sub: TypeMismatchReason,
}
#[derive(Diagnostic)]
#[diag(middle_unsupported_union)]
#[diag("we don't support unions yet: '{$ty_name}'")]
pub struct UnsupportedUnion {
pub ty_name: String,
}
// FIXME(autodiff): I should get used somewhere
#[derive(Diagnostic)]
#[diag(middle_autodiff_unsafe_inner_const_ref)]
#[diag("reading from a `Duplicated` const {$ty} is unsafe")]
pub struct AutodiffUnsafeInnerConstRef<'tcx> {
#[primary_span]
pub span: Span,
@ -54,12 +54,12 @@ pub struct AutodiffUnsafeInnerConstRef<'tcx> {
#[derive(Subdiagnostic)]
pub enum TypeMismatchReason {
#[label(middle_conflict_types)]
#[label("this expression supplies two conflicting concrete types for the same opaque type")]
ConflictType {
#[primary_span]
span: Span,
},
#[note(middle_previous_use_here)]
#[note("previous use here")]
PreviousUse {
#[primary_span]
span: Span,
@ -67,8 +67,10 @@ pub enum TypeMismatchReason {
}
#[derive(Diagnostic)]
#[diag(middle_recursion_limit_reached)]
#[help]
#[diag("reached the recursion limit finding the struct tail for `{$ty}`")]
#[help(
"consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]`"
)]
pub(crate) struct RecursionLimitReached<'tcx> {
#[primary_span]
pub span: Span,
@ -77,23 +79,25 @@ pub(crate) struct RecursionLimitReached<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_const_eval_non_int)]
#[diag("constant evaluation of enum discriminant resulted in non-integer")]
pub(crate) struct ConstEvalNonIntError {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(middle_strict_coherence_needs_negative_coherence)]
#[diag(
"to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled"
)]
pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
#[primary_span]
pub span: Span,
#[label]
#[label("due to this attribute")]
pub attr_span: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(middle_requires_lang_item)]
#[diag("requires `{$name}` lang_item")]
pub(crate) struct RequiresLangItem {
#[primary_span]
pub span: Span,
@ -101,7 +105,9 @@ pub(crate) struct RequiresLangItem {
}
#[derive(Diagnostic)]
#[diag(middle_const_not_used_in_type_alias)]
#[diag(
"const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias"
)]
pub(super) struct ConstNotUsedTraitAlias {
pub ct: String,
#[primary_span]
@ -133,41 +139,41 @@ impl fmt::Debug for CustomSubdiagnostic<'_> {
#[derive(Diagnostic)]
pub enum LayoutError<'tcx> {
#[diag(middle_layout_unknown)]
#[diag("the type `{$ty}` has an unknown layout")]
Unknown { ty: Ty<'tcx> },
#[diag(middle_layout_too_generic)]
#[diag("the type `{$ty}` does not have a fixed layout")]
TooGeneric { ty: Ty<'tcx> },
#[diag(middle_layout_size_overflow)]
#[diag("values of the type `{$ty}` are too big for the target architecture")]
Overflow { ty: Ty<'tcx> },
#[diag(middle_layout_simd_too_many)]
#[diag("the SIMD type `{$ty}` has more elements than the limit {$max_lanes}")]
SimdTooManyLanes { ty: Ty<'tcx>, max_lanes: u64 },
#[diag(middle_layout_simd_zero_length)]
#[diag("the SIMD type `{$ty}` has zero elements")]
SimdZeroLength { ty: Ty<'tcx> },
#[diag(middle_layout_normalization_failure)]
#[diag("unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized")]
NormalizationFailure { ty: Ty<'tcx>, failure_ty: String },
#[diag(middle_layout_cycle)]
#[diag("a cycle occurred during layout computation")]
Cycle,
#[diag(middle_layout_references_error)]
#[diag("the type has an unknown layout")]
ReferencesError,
}
#[derive(Diagnostic)]
#[diag(middle_erroneous_constant)]
#[diag("erroneous constant encountered")]
pub(crate) struct ErroneousConstant {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(middle_type_length_limit)]
#[help(middle_consider_type_length_limit)]
#[diag("reached the type-length limit while instantiating `{$instance}`")]
#[help("consider adding a `#![type_length_limit=\"{$type_length}\"]` attribute to your crate")]
pub(crate) struct TypeLengthLimit<'tcx> {
#[primary_span]
pub span: Span,
@ -176,7 +182,7 @@ pub(crate) struct TypeLengthLimit<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_max_num_nodes_in_valtree)]
#[diag("maximum number of nodes exceeded in constant {$global_const_id}")]
pub(crate) struct MaxNumNodesInValtree {
#[primary_span]
pub span: Span,
@ -184,8 +190,8 @@ pub(crate) struct MaxNumNodesInValtree {
}
#[derive(Diagnostic)]
#[diag(middle_invalid_const_in_valtree)]
#[note]
#[diag("constant {$global_const_id} cannot be used as pattern")]
#[note("constants that reference mutable or external memory cannot be used as patterns")]
pub(crate) struct InvalidConstInValtree {
#[primary_span]
pub span: Span,

View file

@ -91,5 +91,3 @@ pub mod dep_graph;
// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -4,7 +4,7 @@
use std::num::NonZero;
use rustc_ast::NodeId;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer};
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer, inline_fluent};
use rustc_feature::GateIssue;
use rustc_hir::attrs::{DeprecatedSince, Deprecation};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -103,7 +103,7 @@ fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
#[derive(Subdiagnostic)]
#[suggestion(
middle_deprecated_suggestion,
"replace the use of the deprecated {$kind}",
code = "{suggestion}",
style = "verbose",
applicability = "machine-applicable"
@ -128,10 +128,19 @@ pub struct Deprecated {
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(match &self.since_kind {
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note ->
[true] : {$note}
*[other] {\"\"}
}"),
DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
[true] : {$note}
*[other] {\"\"}
}"),
DeprecatedSinceKind::InVersion(_) => {
crate::fluent_generated::middle_deprecated_in_version
inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
[true] : {$note}
*[other] {\"\"}
}")
}
});
diag.arg("kind", self.kind);

View file

@ -336,18 +336,26 @@ impl<O> AssertKind<O> {
pub fn diagnostic_message(&self) -> DiagMessage {
use AssertKind::*;
use crate::fluent_generated::*;
match self {
BoundsCheck { .. } => middle_bounds_check,
Overflow(BinOp::Shl, _, _) => middle_assert_shl_overflow,
Overflow(BinOp::Shr, _, _) => middle_assert_shr_overflow,
Overflow(_, _, _) => middle_assert_op_overflow,
OverflowNeg(_) => middle_assert_overflow_neg,
DivisionByZero(_) => middle_assert_divide_by_zero,
RemainderByZero(_) => middle_assert_remainder_by_zero,
BoundsCheck { .. } => inline_fluent!(
"index out of bounds: the length is {$len} but the index is {$index}"
),
Overflow(BinOp::Shl, _, _) => {
inline_fluent!("attempt to shift left by `{$val}`, which would overflow")
}
Overflow(BinOp::Shr, _, _) => {
inline_fluent!("attempt to shift right by `{$val}`, which would overflow")
}
Overflow(_, _, _) => {
inline_fluent!("attempt to compute `{$left} {$op} {$right}`, which would overflow")
}
OverflowNeg(_) => inline_fluent!("attempt to negate `{$val}`, which would overflow"),
DivisionByZero(_) => inline_fluent!("attempt to divide `{$val}` by zero"),
RemainderByZero(_) => inline_fluent!(
"attempt to calculate the remainder of `{$val}` with a divisor of zero"
),
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_return
inline_fluent!("`async fn` resumed after completion")
}
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
@ -356,36 +364,42 @@ impl<O> AssertKind<O> {
bug!("gen blocks can be resumed after they return and will keep returning `None`")
}
ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_return
inline_fluent!("coroutine resumed after completion")
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_panic
inline_fluent!("`async fn` resumed after panicking")
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
middle_assert_gen_resume_after_panic
inline_fluent!("`gen` fn or block cannot be further iterated on after it panicked")
}
ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_panic
inline_fluent!("coroutine resumed after panicking")
}
NullPointerDereference => inline_fluent!("null pointer dereference occurred"),
InvalidEnumConstruction(_) => {
inline_fluent!("trying to construct an enum from an invalid value `{$source}`")
}
NullPointerDereference => middle_assert_null_ptr_deref,
InvalidEnumConstruction(_) => middle_assert_invalid_enum_construction,
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_drop
inline_fluent!("`async fn` resumed after async drop")
}
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
}
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
middle_assert_gen_resume_after_drop
inline_fluent!(
"`gen` fn or block cannot be further iterated on after it async dropped"
)
}
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_drop
inline_fluent!("coroutine resumed after async drop")
}
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
MisalignedPointerDereference { .. } => inline_fluent!(
"misaligned pointer dereference: address must be a multiple of {$required} but is {$found}"
),
}
}
@ -498,6 +512,7 @@ impl<'tcx> TerminatorKind<'tcx> {
}
pub use helper::*;
use rustc_errors::inline_fluent;
mod helper {
use super::*;

View file

@ -9,6 +9,7 @@ use rustc_abi::{
use rustc_error_messages::DiagMessage;
use rustc_errors::{
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
inline_fluent,
};
use rustc_hir::LangItem;
use rustc_hir::def_id::DefId;
@ -268,18 +269,25 @@ impl<'tcx> LayoutError<'tcx> {
pub fn diagnostic_message(&self) -> DiagMessage {
use LayoutError::*;
use crate::fluent_generated::*;
match self {
Unknown(_) => middle_layout_unknown,
SizeOverflow(_) => middle_layout_size_overflow,
InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
middle_layout_simd_too_many
Unknown(_) => inline_fluent!("the type `{$ty}` has an unknown layout"),
SizeOverflow(_) => {
inline_fluent!("values of the type `{$ty}` are too big for the target architecture")
}
InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => middle_layout_simd_zero_length,
TooGeneric(_) => middle_layout_too_generic,
NormalizationFailure(_, _) => middle_layout_normalization_failure,
Cycle(_) => middle_layout_cycle,
ReferencesError(_) => middle_layout_references_error,
InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
inline_fluent!(
"the SIMD type `{$ty}` has more elements than the limit {$max_lanes}"
)
}
InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => {
inline_fluent!("the SIMD type `{$ty}` has zero elements")
}
TooGeneric(_) => inline_fluent!("the type `{$ty}` does not have a fixed layout"),
NormalizationFailure(_, _) => inline_fluent!(
"unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized"
),
Cycle(_) => inline_fluent!("a cycle occurred during layout computation"),
ReferencesError(_) => inline_fluent!("the type has an unknown layout"),
}
}