Skip to content

Commit 289ce57

Browse files
committed
tweak logic of "unknown field" label
1 parent 1ee37bf commit 289ce57

12 files changed

+101
-49
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+31-25
Original file line numberDiff line numberDiff line change
@@ -2191,7 +2191,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21912191
if let Some(field_name) =
21922192
find_best_match_for_name(&available_field_names, field.ident.name, None)
21932193
{
2194-
err.span_suggestion(
2194+
err.span_label(field.ident.span, "unknown field");
2195+
err.span_suggestion_verbose(
21952196
field.ident.span,
21962197
"a field with a similar name exists",
21972198
field_name,
@@ -2420,30 +2421,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24202421
ty: Ty<'tcx>,
24212422
) {
24222423
let Some(output_ty) = self.get_impl_future_output_ty(ty) else {
2424+
err.span_label(field_ident.span, "unknown field");
24232425
return;
24242426
};
2425-
if let ty::Adt(def, _) = output_ty.kind() {
2426-
// no field access on enum type
2427-
if !def.is_enum() {
2428-
if def
2429-
.non_enum_variant()
2430-
.fields
2431-
.iter()
2432-
.any(|field| field.ident(self.tcx) == field_ident)
2433-
{
2434-
err.span_label(
2435-
field_ident.span,
2436-
"field not available in `impl Future`, but it is available in its `Output`",
2437-
);
2438-
err.span_suggestion_verbose(
2439-
base.span.shrink_to_hi(),
2440-
"consider `await`ing on the `Future` and access the field of its `Output`",
2441-
".await",
2442-
Applicability::MaybeIncorrect,
2443-
);
2444-
}
2445-
}
2427+
let ty::Adt(def, _) = output_ty.kind() else {
2428+
err.span_label(field_ident.span, "unknown field");
2429+
return;
2430+
};
2431+
// no field access on enum type
2432+
if def.is_enum() {
2433+
err.span_label(field_ident.span, "unknown field");
2434+
return;
24462435
}
2436+
if !def.non_enum_variant().fields.iter().any(|field| field.ident(self.tcx) == field_ident) {
2437+
err.span_label(field_ident.span, "unknown field");
2438+
return;
2439+
}
2440+
err.span_label(
2441+
field_ident.span,
2442+
"field not available in `impl Future`, but it is available in its `Output`",
2443+
);
2444+
err.span_suggestion_verbose(
2445+
base.span.shrink_to_hi(),
2446+
"consider `await`ing on the `Future` and access the field of its `Output`",
2447+
".await",
2448+
Applicability::MaybeIncorrect,
2449+
);
24472450
}
24482451

24492452
fn ban_nonexisting_field(
@@ -2467,16 +2470,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24672470
self.suggest_first_deref_field(&mut err, expr, base, ident);
24682471
}
24692472
ty::Param(param_ty) => {
2473+
err.span_label(ident.span, "unknown field");
24702474
self.point_at_param_definition(&mut err, param_ty);
24712475
}
24722476
ty::Alias(ty::Opaque, _) => {
24732477
self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs());
24742478
}
2475-
_ => {}
2479+
_ => {
2480+
err.span_label(ident.span, "unknown field");
2481+
}
24762482
}
24772483

2478-
err.span_label(ident.span, "unknown field");
2479-
24802484
self.suggest_fn_call(&mut err, base, base_ty, |output_ty| {
24812485
if let ty::Adt(def, _) = output_ty.kind()
24822486
&& !def.is_enum()
@@ -2635,6 +2639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26352639
field: Ident,
26362640
len: ty::Const<'tcx>,
26372641
) {
2642+
err.span_label(field.span, "unknown field");
26382643
if let (Some(len), Ok(user_index)) =
26392644
(len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
26402645
&& let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
@@ -2657,6 +2662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26572662
base: &hir::Expr<'_>,
26582663
field: Ident,
26592664
) {
2665+
err.span_label(field.span, "unknown field");
26602666
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
26612667
let msg = format!("`{base}` is a raw pointer; try dereferencing it");
26622668
let suggestion = format!("(*{base}).{field}");

tests/ui/async-await/issue-61076.rs

-2
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,10 @@ async fn baz() -> Result<(), ()> {
7171
let _: i32 = tuple().0; //~ ERROR no field `0`
7272
//~^ HELP consider `await`ing on the `Future`
7373
//~| NOTE field not available in `impl Future`
74-
//~| NOTE unknown field
7574

7675
let _: i32 = struct_().a; //~ ERROR no field `a`
7776
//~^ HELP consider `await`ing on the `Future`
7877
//~| NOTE field not available in `impl Future`
79-
//~| NOTE unknown field
8078

8179
struct_().method(); //~ ERROR no method named
8280
//~^ NOTE method not found in `impl Future<Output = Struct>`

tests/ui/async-await/issue-61076.stderr

+5-11
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,26 @@ error[E0609]: no field `0` on type `impl Future<Output = Tuple>`
2626
--> $DIR/issue-61076.rs:71:26
2727
|
2828
LL | let _: i32 = tuple().0;
29-
| ^
30-
| |
31-
| field not available in `impl Future`, but it is available in its `Output`
32-
| unknown field
29+
| ^ field not available in `impl Future`, but it is available in its `Output`
3330
|
3431
help: consider `await`ing on the `Future` and access the field of its `Output`
3532
|
3633
LL | let _: i32 = tuple().await.0;
3734
| ++++++
3835

3936
error[E0609]: no field `a` on type `impl Future<Output = Struct>`
40-
--> $DIR/issue-61076.rs:76:28
37+
--> $DIR/issue-61076.rs:75:28
4138
|
4239
LL | let _: i32 = struct_().a;
43-
| ^
44-
| |
45-
| field not available in `impl Future`, but it is available in its `Output`
46-
| unknown field
40+
| ^ field not available in `impl Future`, but it is available in its `Output`
4741
|
4842
help: consider `await`ing on the `Future` and access the field of its `Output`
4943
|
5044
LL | let _: i32 = struct_().await.a;
5145
| ++++++
5246

5347
error[E0599]: no method named `method` found for opaque type `impl Future<Output = Struct>` in the current scope
54-
--> $DIR/issue-61076.rs:81:15
48+
--> $DIR/issue-61076.rs:79:15
5549
|
5650
LL | struct_().method();
5751
| ^^^^^^ method not found in `impl Future<Output = Struct>`
@@ -62,7 +56,7 @@ LL | struct_().await.method();
6256
| ++++++
6357

6458
error[E0308]: mismatched types
65-
--> $DIR/issue-61076.rs:90:9
59+
--> $DIR/issue-61076.rs:88:9
6660
|
6761
LL | match tuple() {
6862
| ------- this expression has type `impl Future<Output = Tuple>`

tests/ui/did_you_mean/dont-suggest-hygienic-fields.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ LL | environment!();
55
| -------------- in this macro invocation
66
...
77
LL | const CRATE: Crate = Crate { fiel: () };
8-
| ^^^^ help: a field with a similar name exists: `field`
8+
| ^^^^ unknown field
99
|
1010
= note: this error originates in the macro `environment` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
help: a field with a similar name exists
12+
|
13+
LL | const CRATE: Crate = Crate { field: () };
14+
| ~~~~~
1115

1216
error[E0609]: no field `field` on type `Compound`
1317
--> $DIR/dont-suggest-hygienic-fields.rs:24:16

tests/ui/did_you_mean/issue-42599_available_fields_note.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: struct `Demo` has no field named `inocently_mispellable`
22
--> $DIR/issue-42599_available_fields_note.rs:16:39
33
|
44
LL | Self { secret_integer: 2, inocently_mispellable: () }
5-
| ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`
5+
| ^^^^^^^^^^^^^^^^^^^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | Self { secret_integer: 2, innocently_misspellable: () }
10+
| ~~~~~~~~~~~~~~~~~~~~~~~
611

712
error[E0560]: struct `Demo` has no field named `egregiously_nonexistent_field`
813
--> $DIR/issue-42599_available_fields_note.rs:21:39

tests/ui/rmeta/rmeta_meta_main.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: struct `Foo` has no field named `field2`
22
--> $DIR/rmeta_meta_main.rs:13:19
33
|
44
LL | let _ = Foo { field2: 42 };
5-
| ^^^^^^ help: a field with a similar name exists: `field`
5+
| ^^^^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | let _ = Foo { field: 42 };
10+
| ~~~~~
611

712
error: aborting due to previous error
813

tests/ui/structs/struct-fields-hints-no-dupe.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: struct `A` has no field named `bar`
22
--> $DIR/struct-fields-hints-no-dupe.rs:10:9
33
|
44
LL | bar : 42,
5-
| ^^^ help: a field with a similar name exists: `barr`
5+
| ^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | barr : 42,
10+
| ~~~~
611

712
error: aborting due to previous error
813

tests/ui/structs/struct-fields-hints.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: struct `A` has no field named `bar`
22
--> $DIR/struct-fields-hints.rs:10:9
33
|
44
LL | bar : 42,
5-
| ^^^ help: a field with a similar name exists: `car`
5+
| ^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | car : 42,
10+
| ~~~
611

712
error: aborting due to previous error
813

tests/ui/structs/suggest-private-fields.stderr

+18-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: struct `B` has no field named `aa`
22
--> $DIR/suggest-private-fields.rs:15:9
33
|
44
LL | aa: 20,
5-
| ^^ help: a field with a similar name exists: `a`
5+
| ^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | a: 20,
10+
| ~
611

712
error[E0560]: struct `B` has no field named `bb`
813
--> $DIR/suggest-private-fields.rs:17:9
@@ -16,13 +21,23 @@ error[E0560]: struct `A` has no field named `aa`
1621
--> $DIR/suggest-private-fields.rs:22:9
1722
|
1823
LL | aa: 20,
19-
| ^^ help: a field with a similar name exists: `a`
24+
| ^^ unknown field
25+
|
26+
help: a field with a similar name exists
27+
|
28+
LL | a: 20,
29+
| ~
2030

2131
error[E0560]: struct `A` has no field named `bb`
2232
--> $DIR/suggest-private-fields.rs:24:9
2333
|
2434
LL | bb: 20,
25-
| ^^ help: a field with a similar name exists: `b`
35+
| ^^ unknown field
36+
|
37+
help: a field with a similar name exists
38+
|
39+
LL | b: 20,
40+
| ~
2641

2742
error: aborting due to 4 previous errors
2843

tests/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ error[E0560]: struct `RGB` has no field named `c`
2424
--> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:25
2525
|
2626
LL | let _ = RGB { r, g, c };
27-
| ^ help: a field with a similar name exists: `b`
27+
| ^ unknown field
28+
|
29+
help: a field with a similar name exists
30+
|
31+
LL | let _ = RGB { r, g, b };
32+
| ~
2833

2934
error: aborting due to 3 previous errors
3035

tests/ui/union/union-suggest-field.mirunsafeck.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: union `U` has no field named `principle`
22
--> $DIR/union-suggest-field.rs:13:17
33
|
44
LL | let u = U { principle: 0 };
5-
| ^^^^^^^^^ help: a field with a similar name exists: `principal`
5+
| ^^^^^^^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | let u = U { principal: 0 };
10+
| ~~~~~~~~~
611

712
error[E0609]: no field `principial` on type `U`
813
--> $DIR/union-suggest-field.rs:17:15

tests/ui/union/union-suggest-field.thirunsafeck.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0560]: union `U` has no field named `principle`
22
--> $DIR/union-suggest-field.rs:13:17
33
|
44
LL | let u = U { principle: 0 };
5-
| ^^^^^^^^^ help: a field with a similar name exists: `principal`
5+
| ^^^^^^^^^ unknown field
6+
|
7+
help: a field with a similar name exists
8+
|
9+
LL | let u = U { principal: 0 };
10+
| ~~~~~~~~~
611

712
error[E0609]: no field `principial` on type `U`
813
--> $DIR/union-suggest-field.rs:17:15

0 commit comments

Comments
 (0)