1
Fork 0

Make E0609 a structured error

This commit is contained in:
Esteban Küber 2025-02-18 03:54:04 +00:00
parent 7302dc660b
commit 26f74ef586
5 changed files with 51 additions and 21 deletions

View file

@ -153,6 +153,12 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {
*[other] {" "}in the current scope
}
hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}`
hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}`
hir_typeck_no_field_on_variant_enum = this enum variant...
hir_typeck_no_field_on_variant_field = ...does not have this field
hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide

View file

@ -454,6 +454,29 @@ impl HelpUseLatestEdition {
}
}
#[derive(Diagnostic)]
#[diag(hir_typeck_no_field_on_type, code = E0609)]
pub(crate) struct NoFieldOnType<'tcx> {
#[primary_span]
pub(crate) span: Span,
pub(crate) ty: Ty<'tcx>,
pub(crate) field: Ident,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_no_field_on_variant, code = E0609)]
pub(crate) struct NoFieldOnVariant<'tcx> {
#[primary_span]
pub(crate) span: Span,
pub(crate) container: Ty<'tcx>,
pub(crate) ident: Ident,
pub(crate) field: Ident,
#[label(hir_typeck_no_field_on_variant_enum)]
pub(crate) enum_span: Span,
#[label(hir_typeck_no_field_on_variant_field)]
pub(crate) field_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_cant_dereference, code = E0614)]
pub(crate) struct CantDereference<'tcx> {

View file

@ -46,8 +46,9 @@ use crate::errors::{
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
HelpUseLatestEdition, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody,
StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind,
ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo,
YieldExprOutsideOfCoroutine,
};
use crate::{
BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust,
@ -3282,13 +3283,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = field.span;
debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
let mut err = type_error_struct!(
self.dcx(),
span,
expr_t,
E0609,
"no field `{field}` on type `{expr_t}`",
);
let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field });
if expr_t.references_error() {
err.downgrade_to_delayed_bug();
}
// try to add a suggestion in case the field is a nested field of a field of the Adt
let mod_id = self.tcx.parent_module(id).to_def_id();
@ -3862,16 +3860,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter_enumerated()
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident)
else {
type_error_struct!(
self.dcx(),
ident.span,
container,
E0609,
"no field named `{subfield}` on enum variant `{container}::{ident}`",
)
.with_span_label(field.span, "this enum variant...")
.with_span_label(subident.span, "...does not have this field")
.emit();
self.dcx()
.create_err(NoFieldOnVariant {
span: ident.span,
container,
ident,
field: subfield,
enum_span: field.span,
field_span: subident.span,
})
.emit_unless(container.references_error());
break;
};