Skip to content

Commit 82684d0

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 c55f14e commit 82684d0

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
@@ -2216,8 +2216,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22162216
);
22172217

22182218
let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap();
2219-
match variant.ctor_kind() {
2220-
Some(CtorKind::Fn) => match ty.kind() {
2219+
match variant.ctor {
2220+
Some((CtorKind::Fn, def_id)) => match ty.kind() {
22212221
ty::Adt(adt, ..) if adt.is_enum() => {
22222222
err.span_label(
22232223
variant_ident_span,
@@ -2228,28 +2228,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22282228
),
22292229
);
22302230
err.span_label(field.ident.span, "field does not exist");
2231+
// err.note(format!("{expr:#?}"));
2232+
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
2233+
let inputs = fn_sig.inputs().skip_binder();
2234+
let fields = format!(
2235+
"({})",
2236+
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
2237+
);
2238+
let (replace_span, sugg) = match expr.kind {
2239+
hir::ExprKind::Struct(qpath, ..) => {
2240+
(qpath.span().shrink_to_hi().with_hi(expr.span.hi()), fields)
2241+
}
2242+
_ => {
2243+
(expr.span, format!("{ty}::{variant}{fields}", variant = variant.name))
2244+
}
2245+
};
22312246
err.span_suggestion_verbose(
2232-
expr.span,
2247+
replace_span,
22332248
format!(
22342249
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
22352250
adt = ty,
22362251
variant = variant.name,
22372252
),
2238-
format!(
2239-
"{adt}::{variant}(/* fields */)",
2240-
adt = ty,
2241-
variant = variant.name,
2242-
),
2253+
sugg,
22432254
Applicability::HasPlaceholders,
22442255
);
22452256
}
22462257
_ => {
22472258
err.span_label(variant_ident_span, format!("`{ty}` defined here"));
22482259
err.span_label(field.ident.span, "field does not exist");
2260+
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
2261+
let inputs = fn_sig.inputs().skip_binder();
2262+
let fields = format!(
2263+
"({})",
2264+
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
2265+
);
22492266
err.span_suggestion_verbose(
22502267
expr.span,
22512268
format!("`{ty}` is a tuple {kind_name}, use the appropriate syntax",),
2252-
format!("{ty}(/* fields */)"),
2269+
format!("{ty}{fields}"),
22532270
Applicability::HasPlaceholders,
22542271
);
22552272
}

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)