Skip to content

Commit

Permalink
Make E0609 a structured error
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Feb 18, 2025
1 parent 2970cd3 commit ce259e2
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 21 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
36 changes: 17 additions & 19 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,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,
Expand Down Expand Up @@ -3281,13 +3282,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();
Expand Down Expand Up @@ -3863,16 +3861,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;
};

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/diagnostic-width/long-E0609.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type C = (B, B, B, B);
type D = (C, C, C, C);

fn foo(x: D) {
x.field; //~ ERROR no field `field` on type `(
x.field; //~ ERROR no field `field` on type `(...
}

fn main() {}
5 changes: 4 additions & 1 deletion tests/ui/diagnostic-width/long-E0609.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
error[E0609]: no field `field` on type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))`
error[E0609]: no field `field` on type `(..., ..., ..., ...)`
--> $DIR/long-E0609.rs:10:7
|
LL | x.field;
| ^^^^^ unknown field
|
= note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
= note: consider using `--verbose` to print the full type name to the console

error: aborting due to 1 previous error

Expand Down

0 comments on commit ce259e2

Please sign in to comment.