Skip to content

Commit

Permalink
Tweak "field not found" suggestion when giving struct literal for tup…
Browse files Browse the repository at this point in the history
…le 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 });
   |               ~~~~~~~~~~~~~~~~~~~~~~~
```
  • Loading branch information
estebank committed Jul 18, 2024
1 parent ec7a188 commit 33bd4bd
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 37 deletions.
34 changes: 25 additions & 9 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-4736.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-80607.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/numeric/numeric-fields.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/suggestions/incorrect-variant-literal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 16 additions & 16 deletions tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down

0 comments on commit 33bd4bd

Please sign in to comment.