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(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
   |               ~~~~~~~~~~~~~~~~~~~~~~~
```
This commit is contained in:
Esteban Küber 2024-07-11 18:08:41 +00:00
parent ec7a188f16
commit 33bd4bdeb5
6 changed files with 53 additions and 37 deletions

View File

@ -2218,8 +2218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap();
match variant.ctor_kind() {
Some(CtorKind::Fn) => match ty.kind() {
match variant.ctor {
Some((CtorKind::Fn, def_id)) => match ty.kind() {
ty::Adt(adt, ..) if adt.is_enum() => {
err.span_label(
variant_ident_span,
@ -2230,28 +2230,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
err.span_label(field.ident.span, "field does not exist");
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
let inputs = fn_sig.inputs().skip_binder();
let fields = format!(
"({})",
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
);
let (replace_span, sugg) = match expr.kind {
hir::ExprKind::Struct(qpath, ..) => {
(qpath.span().shrink_to_hi().with_hi(expr.span.hi()), fields)
}
_ => {
(expr.span, format!("{ty}::{variant}{fields}", variant = variant.name))
}
};
err.span_suggestion_verbose(
expr.span,
replace_span,
format!(
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
adt = ty,
variant = variant.name,
),
format!(
"{adt}::{variant}(/* fields */)",
adt = ty,
variant = variant.name,
),
sugg,
Applicability::HasPlaceholders,
);
}
_ => {
err.span_label(variant_ident_span, format!("`{ty}` defined here"));
err.span_label(field.ident.span, "field does not exist");
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity();
let inputs = fn_sig.inputs().skip_binder();
let fields = format!(
"({})",
inputs.iter().map(|i| format!("/* {i} */")).collect::<Vec<_>>().join(", ")
);
err.span_suggestion_verbose(
expr.span,
format!("`{ty}` is a tuple {kind_name}, use the appropriate syntax",),
format!("{ty}(/* fields */)"),
format!("{ty}{fields}"),
Applicability::HasPlaceholders,
);
}

View File

@ -9,8 +9,8 @@ LL | let z = NonCopyable{ p: () };
|
help: `NonCopyable` is a tuple struct, use the appropriate syntax
|
LL | let z = NonCopyable(/* fields */);
| ~~~~~~~~~~~~~~~~~~~~~~~~~
LL | let z = NonCopyable(/* () */);
| ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error

View File

@ -9,8 +9,8 @@ LL | Enum::V1 { x }
|
help: `Enum::V1` is a tuple variant, use the appropriate syntax
|
LL | Enum::V1(/* fields */)
| ~~~~~~~~~~~~~~~~~~~~~~
LL | Enum::V1(/* i32 */)
| ~~~~~~~~~~~
error: aborting due to 1 previous error

View File

@ -9,8 +9,8 @@ LL | let s = S{0b1: 10, 0: 11};
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let s = S(/* fields */);
| ~~~~~~~~~~~~~~~
LL | let s = S(/* u8 */, /* u16 */);
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0026]: struct `S` does not have a field named `0x1`
--> $DIR/numeric-fields.rs:7:17

View File

@ -237,9 +237,9 @@
</tspan>
<tspan x="10px" y="1954px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="1972px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-010">Enum::Tuple(/* fields */)</tspan><tspan>;</tspan>
<tspan x="10px" y="1972px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> Enum::Tuple</tspan><tspan class="fg-ansi256-010">(/* i32 */)</tspan><tspan>;</tspan>
</tspan>
<tspan x="10px" y="1990px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~~~~~~~~~~~~~~~</tspan>
<tspan x="10px" y="1990px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~</tspan>
</tspan>
<tspan x="10px" y="2008px">
</tspan>
@ -375,9 +375,9 @@
</tspan>
<tspan x="10px" y="3196px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="3214px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-010">Enum::Tuple(/* fields */)</tspan><tspan>;</tspan>
<tspan x="10px" y="3214px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> Enum::Tuple</tspan><tspan class="fg-ansi256-010">(/* i32 */)</tspan><tspan>;</tspan>
</tspan>
<tspan x="10px" y="3232px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~~~~~~~~~~~~~~~</tspan>
<tspan x="10px" y="3232px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~</tspan>
</tspan>
<tspan x="10px" y="3250px">
</tspan>
@ -403,9 +403,9 @@
</tspan>
<tspan x="10px" y="3448px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="3466px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-010">Enum::Tuple(/* fields */)</tspan><tspan>;</tspan>
<tspan x="10px" y="3466px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> Enum::Tuple</tspan><tspan class="fg-ansi256-010">(/* i32 */)</tspan><tspan>;</tspan>
</tspan>
<tspan x="10px" y="3484px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~~~~~~~~~~~~~~~</tspan>
<tspan x="10px" y="3484px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~~~~~~~~~~~</tspan>
</tspan>
<tspan x="10px" y="3502px">
</tspan>

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -9,8 +9,8 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S(/* fields */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~
LL | let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0560]: struct `S` has no field named `y`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:27
@ -23,8 +23,8 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S(/* fields */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~
LL | let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0560]: struct `S` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:41
@ -37,8 +37,8 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S { x: 1.0, y: 2.0 }, S(/* fields */));
| ~~~~~~~~~~~~~~~
LL | let _x = (S { x: 1.0, y: 2.0 }, S(/* f32 */, /* f32 */));
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0560]: struct `S` has no field named `y`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:49
@ -51,8 +51,8 @@ LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S { x: 1.0, y: 2.0 }, S(/* fields */));
| ~~~~~~~~~~~~~~~
LL | let _x = (S { x: 1.0, y: 2.0 }, S(/* f32 */, /* f32 */));
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0559]: variant `E::V` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:13:22
@ -65,8 +65,8 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
help: `E::V` is a tuple variant, use the appropriate syntax
|
LL | let _y = (E::V(/* fields */), E::V { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~
LL | let _y = (E::V(/* f32 */, /* f32 */), E::V { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0559]: variant `E::V` has no field named `y`
--> $DIR/nested-non-tuple-tuple-struct.rs:13:30
@ -79,8 +79,8 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
help: `E::V` is a tuple variant, use the appropriate syntax
|
LL | let _y = (E::V(/* fields */), E::V { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~
LL | let _y = (E::V(/* f32 */, /* f32 */), E::V { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0559]: variant `E::V` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:13:47
@ -93,8 +93,8 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
help: `E::V` is a tuple variant, use the appropriate syntax
|
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* fields */));
| ~~~~~~~~~~~~~~~~~~
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* f32 */, /* f32 */));
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0559]: variant `E::V` has no field named `y`
--> $DIR/nested-non-tuple-tuple-struct.rs:13:55
@ -107,8 +107,8 @@ LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
help: `E::V` is a tuple variant, use the appropriate syntax
|
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* fields */));
| ~~~~~~~~~~~~~~~~~~
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V(/* f32 */, /* f32 */));
| ~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 8 previous errors