diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dc677595f05e0..1032d01e61bf1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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::>().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::>().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, ); } diff --git a/tests/ui/issues/issue-4736.stderr b/tests/ui/issues/issue-4736.stderr index 146dd1d57ce33..c1ae2c47b43a7 100644 --- a/tests/ui/issues/issue-4736.stderr +++ b/tests/ui/issues/issue-4736.stderr @@ -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 diff --git a/tests/ui/issues/issue-80607.stderr b/tests/ui/issues/issue-80607.stderr index 20494f319ddd0..d096910297b79 100644 --- a/tests/ui/issues/issue-80607.stderr +++ b/tests/ui/issues/issue-80607.stderr @@ -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 diff --git a/tests/ui/numeric/numeric-fields.stderr b/tests/ui/numeric/numeric-fields.stderr index 668405ed638c1..8ab1718ff5e8f 100644 --- a/tests/ui/numeric/numeric-fields.stderr +++ b/tests/ui/numeric/numeric-fields.stderr @@ -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 diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg index 7858cc466b321..971e72ba18be6 100644 --- a/tests/ui/suggestions/incorrect-variant-literal.svg +++ b/tests/ui/suggestions/incorrect-variant-literal.svg @@ -237,9 +237,9 @@ | - LL | Enum::Tuple(/* fields */); + LL | Enum::Tuple(/* i32 */); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~ @@ -375,9 +375,9 @@ | - LL | Enum::Tuple(/* fields */); + LL | Enum::Tuple(/* i32 */); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~ @@ -403,9 +403,9 @@ | - LL | Enum::Tuple(/* fields */); + LL | Enum::Tuple(/* i32 */); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~ diff --git a/tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr b/tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr index 948f09fc3fab7..4523333850c06 100644 --- a/tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr +++ b/tests/ui/suggestions/nested-non-tuple-tuple-struct.stderr @@ -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