From ed6232927b5d2f198ec33f77f0eb597a9eb68aa8 Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 3 Feb 2021 21:29:00 -0800 Subject: [PATCH] typeck: Emit structured suggestions for tuple struct syntax And tuple variant syntax, but that didn't fit in the subject :) Now the fact that these are suggestions is exposed both to the layout engine and to IDEs and rustfix for automatic application. --- compiler/rustc_typeck/src/check/expr.rs | 25 ++++++++++++++--------- src/test/ui/issues/issue-4736.stderr | 2 +- src/test/ui/issues/issue-80607.stderr | 2 +- src/test/ui/numeric/numeric-fields.stderr | 2 +- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 33b1c0bb2c9..1a11aad1441 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1460,28 +1460,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); err.span_label(field.ident.span, "field does not exist"); - err.span_label( + err.span_suggestion( ty_span, - format!( - "`{adt}::{variant}` is a tuple {kind_name}, \ - use the appropriate syntax: `{adt}::{variant}(/* fields */)`", + &format!( + "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, variant = variant.ident, - kind_name = kind_name ), + format!( + "{adt}::{variant}(/* fields */)", + adt = ty, + variant = variant.ident, + ), + Applicability::HasPlaceholders, ); } _ => { err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty)); err.span_label(field.ident.span, "field does not exist"); - err.span_label( + err.span_suggestion( ty_span, - format!( - "`{adt}` is a tuple {kind_name}, \ - use the appropriate syntax: `{adt}(/* fields */)`", + &format!( + "`{adt}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, - kind_name = kind_name + kind_name = kind_name, ), + format!("{adt}(/* fields */)", adt = ty), + Applicability::HasPlaceholders, ); } }, diff --git a/src/test/ui/issues/issue-4736.stderr b/src/test/ui/issues/issue-4736.stderr index 257ec914a61..9be4eb1c7fd 100644 --- a/src/test/ui/issues/issue-4736.stderr +++ b/src/test/ui/issues/issue-4736.stderr @@ -7,7 +7,7 @@ LL | struct NonCopyable(()); LL | let z = NonCopyable{ p: () }; | ----------- ^ field does not exist | | - | `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` + | help: `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-80607.stderr b/src/test/ui/issues/issue-80607.stderr index 5375478942b..22a660b4167 100644 --- a/src/test/ui/issues/issue-80607.stderr +++ b/src/test/ui/issues/issue-80607.stderr @@ -7,7 +7,7 @@ LL | V1(i32), LL | Enum::V1 { x } | -------- ^ field does not exist | | - | `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)` + | help: `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index 5202393f559..13b6cfae4ec 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -7,7 +7,7 @@ LL | struct S(u8, u16); LL | let s = S{0b1: 10, 0: 11}; | - ^^^ field does not exist | | - | `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` + | help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17