Skip to content

Commit 26f74ef

Browse files
committed
Make E0609 a structured error
1 parent 7302dc6 commit 26f74ef

File tree

5 files changed

+51
-21
lines changed

5 files changed

+51
-21
lines changed

compiler/rustc_hir_typeck/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {
153153
*[other] {" "}in the current scope
154154
}
155155
156+
hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}`
157+
158+
hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}`
159+
hir_typeck_no_field_on_variant_enum = this enum variant...
160+
hir_typeck_no_field_on_variant_field = ...does not have this field
161+
156162
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}`
157163
158164
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide

compiler/rustc_hir_typeck/src/errors.rs

+23
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,29 @@ impl HelpUseLatestEdition {
454454
}
455455
}
456456

457+
#[derive(Diagnostic)]
458+
#[diag(hir_typeck_no_field_on_type, code = E0609)]
459+
pub(crate) struct NoFieldOnType<'tcx> {
460+
#[primary_span]
461+
pub(crate) span: Span,
462+
pub(crate) ty: Ty<'tcx>,
463+
pub(crate) field: Ident,
464+
}
465+
466+
#[derive(Diagnostic)]
467+
#[diag(hir_typeck_no_field_on_variant, code = E0609)]
468+
pub(crate) struct NoFieldOnVariant<'tcx> {
469+
#[primary_span]
470+
pub(crate) span: Span,
471+
pub(crate) container: Ty<'tcx>,
472+
pub(crate) ident: Ident,
473+
pub(crate) field: Ident,
474+
#[label(hir_typeck_no_field_on_variant_enum)]
475+
pub(crate) enum_span: Span,
476+
#[label(hir_typeck_no_field_on_variant_field)]
477+
pub(crate) field_span: Span,
478+
}
479+
457480
#[derive(Diagnostic)]
458481
#[diag(hir_typeck_cant_dereference, code = E0614)]
459482
pub(crate) struct CantDereference<'tcx> {

compiler/rustc_hir_typeck/src/expr.rs

+17-19
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ use crate::errors::{
4646
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
4747
BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
4848
CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
49-
HelpUseLatestEdition, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody,
50-
StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
49+
HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind,
50+
ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo,
51+
YieldExprOutsideOfCoroutine,
5152
};
5253
use crate::{
5354
BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust,
@@ -3282,13 +3283,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32823283
let span = field.span;
32833284
debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
32843285

3285-
let mut err = type_error_struct!(
3286-
self.dcx(),
3287-
span,
3288-
expr_t,
3289-
E0609,
3290-
"no field `{field}` on type `{expr_t}`",
3291-
);
3286+
let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field });
3287+
if expr_t.references_error() {
3288+
err.downgrade_to_delayed_bug();
3289+
}
32923290

32933291
// try to add a suggestion in case the field is a nested field of a field of the Adt
32943292
let mod_id = self.tcx.parent_module(id).to_def_id();
@@ -3862,16 +3860,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38623860
.iter_enumerated()
38633861
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident)
38643862
else {
3865-
type_error_struct!(
3866-
self.dcx(),
3867-
ident.span,
3868-
container,
3869-
E0609,
3870-
"no field named `{subfield}` on enum variant `{container}::{ident}`",
3871-
)
3872-
.with_span_label(field.span, "this enum variant...")
3873-
.with_span_label(subident.span, "...does not have this field")
3874-
.emit();
3863+
self.dcx()
3864+
.create_err(NoFieldOnVariant {
3865+
span: ident.span,
3866+
container,
3867+
ident,
3868+
field: subfield,
3869+
enum_span: field.span,
3870+
field_span: subident.span,
3871+
})
3872+
.emit_unless(container.references_error());
38753873
break;
38763874
};
38773875

tests/ui/diagnostic-width/long-E0609.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type C = (B, B, B, B);
77
type D = (C, C, C, C);
88

99
fn foo(x: D) {
10-
x.field; //~ ERROR no field `field` on type `(
10+
x.field; //~ ERROR no field `field` on type `(...
1111
}
1212

1313
fn main() {}

tests/ui/diagnostic-width/long-E0609.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
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))))`
1+
error[E0609]: no field `field` on type `(..., ..., ..., ...)`
22
--> $DIR/long-E0609.rs:10:7
33
|
44
LL | x.field;
55
| ^^^^^ unknown field
6+
|
7+
= note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
8+
= note: consider using `--verbose` to print the full type name to the console
69

710
error: aborting due to 1 previous error
811

0 commit comments

Comments
 (0)