Skip to content

Commit ce259e2

Browse files
committed
Make E0609 a structured error
1 parent 2970cd3 commit ce259e2

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
@@ -45,8 +45,9 @@ use crate::errors::{
4545
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
4646
BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
4747
CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
48-
HelpUseLatestEdition, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody,
49-
StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
48+
HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind,
49+
ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo,
50+
YieldExprOutsideOfCoroutine,
5051
};
5152
use crate::{
5253
BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust,
@@ -3281,13 +3282,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32813282
let span = field.span;
32823283
debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
32833284

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

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

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)