Skip to content

Commit b0ea916

Browse files
committed
Tweak "field not found" suggestion when giving struct literal for tuple struct type
``` error[E0560]: struct `S` has no field named `x` --> $DIR/nested-non-tuple-tuple-struct.rs:8:19 | LL | pub struct S(f32, f32); | - `S` defined here ... LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 }); | ^ field does not exist | help: `S` is a tuple struct, use the appropriate syntax | LL - let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 }); LL + let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 }); | ```
1 parent 396e9bd commit b0ea916

File tree

3 files changed

+40
-23
lines changed

3 files changed

+40
-23
lines changed

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,8 +2218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22182218
);
22192219

22202220
let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap();
2221-
match variant.ctor_kind() {
2222-
Some(CtorKind::Fn) => match ty.kind() {
2221+
match variant.ctor {
2222+
Some((CtorKind::Fn, def_id)) => match ty.kind() {
22232223
ty::Adt(adt, ..) if adt.is_enum() => {
22242224
err.span_label(
22252225
variant_ident_span,
@@ -2230,28 +2230,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22302230
),
22312231
);
22322232
err.span_label(field.ident.span, "field does not exist");
2233+
// err.note(format!("{expr:#?}"));
2234+
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
2235+
let inputs = fn_sig.inputs().skip_binder();
2236+
let fields = format!(
2237+
"({})",
2238+
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
2239+
);
2240+
let (replace_span, sugg) = match expr.kind {
2241+
hir::ExprKind::Struct(qpath, ..) => {
2242+
(qpath.span().shrink_to_hi().with_hi(expr.span.hi()), fields)
2243+
}
2244+
_ => {
2245+
(expr.span, format!("{ty}::{variant}{fields}", variant = variant.name))
2246+
}
2247+
};
22332248
err.span_suggestion_verbose(
2234-
expr.span,
2249+
replace_span,
22352250
format!(
22362251
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
22372252
adt = ty,
22382253
variant = variant.name,
22392254
),
2240-
format!(
2241-
"{adt}::{variant}(/* fields */)",
2242-
adt = ty,
2243-
variant = variant.name,
2244-
),
2255+
sugg,
22452256
Applicability::HasPlaceholders,
22462257
);
22472258
}
22482259
_ => {
22492260
err.span_label(variant_ident_span, format!("`{ty}` defined here"));
22502261
err.span_label(field.ident.span, "field does not exist");
2262+
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
2263+
let inputs = fn_sig.inputs().skip_binder();
2264+
let fields = format!(
2265+
"({})",
2266+
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
2267+
);
22512268
err.span_suggestion_verbose(
22522269
expr.span,
22532270
format!("`{ty}` is a tuple {kind_name}, use the appropriate syntax",),
2254-
format!("{ty}(/* fields */)"),
2271+
format!("{ty}{fields}"),
22552272
Applicability::HasPlaceholders,
22562273
);
22572274
}

tests/ui/suggestions/incorrect-variant-literal.svg

Lines changed: 6 additions & 6 deletions
Loading

tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
1010
help: `S` is a tuple struct, use the appropriate syntax
1111
|
1212
LL - let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
13-
LL + let _x = (S(/* fields */), S { x: 3.0, y: 4.0 });
13+
LL + let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
1414
|
1515

1616
error[E0560]: struct `S` has no field named `y`
@@ -25,7 +25,7 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
2525
help: `S` is a tuple struct, use the appropriate syntax
2626
|
2727
LL - let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
28-
LL + let _x = (S(/* fields */), S { x: 3.0, y: 4.0 });
28+
LL + let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
2929
|
3030

3131
error[E0560]: struct `S` has no field named `x`
@@ -40,7 +40,7 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
4040
help: `S` is a tuple struct, use the appropriate syntax
4141
|
4242
LL - let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
43-
LL + let _x = (S { x: 1.0, y: 2.0 }, S(/* fields */));
43+
LL + let _x = (S { x: 1.0, y: 2.0 }, S(/* f32 */, /* f32 */));
4444
|
4545

4646
error[E0560]: struct `S` has no field named `y`
@@ -55,7 +55,7 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
5555
help: `S` is a tuple struct, use the appropriate syntax
5656
|
5757
LL - let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
58-
LL + let _x = (S { x: 1.0, y: 2.0 }, S(/* fields */));
58+
LL + let _x = (S { x: 1.0, y: 2.0 }, S(/* f32 */, /* f32 */));
5959
|
6060

6161
error[E0559]: variant `E::V` has no field named `x`
@@ -70,7 +70,7 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
7070
help: `E::V` is a tuple variant, use the appropriate syntax
7171
|
7272
LL - let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
73-
LL + let _y = (E::V(/* fields */), E::V { x: 3.0, y: 4.0 });
73+
LL + let _y = (E::V(/* f32 */, /* f32 */), E::V { x: 3.0, y: 4.0 });
7474
|
7575

7676
error[E0559]: variant `E::V` has no field named `y`
@@ -85,7 +85,7 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
8585
help: `E::V` is a tuple variant, use the appropriate syntax
8686
|
8787
LL - let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
88-
LL + let _y = (E::V(/* fields */), E::V { x: 3.0, y: 4.0 });
88+
LL + let _y = (E::V(/* f32 */, /* f32 */), E::V { x: 3.0, y: 4.0 });
8989
|
9090

9191
error[E0559]: variant `E::V` has no field named `x`
@@ -100,7 +100,7 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
100100
help: `E::V` is a tuple variant, use the appropriate syntax
101101
|
102102
LL - let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
103-
LL + let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* fields */));
103+
LL + let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* f32 */, /* f32 */));
104104
|
105105

106106
error[E0559]: variant `E::V` has no field named `y`
@@ -115,7 +115,7 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
115115
help: `E::V` is a tuple variant, use the appropriate syntax
116116
|
117117
LL - let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
118-
LL + let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* fields */));
118+
LL + let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* f32 */, /* f32 */));
119119
|
120120

121121
error: aborting due to 8 previous errors

0 commit comments

Comments
 (0)