From f1b8b7d7ae190a9cfc14a9c6ac5e4f78445ade46 Mon Sep 17 00:00:00 2001
From: clubby789 <jamie@hill-daniel.co.uk>
Date: Fri, 26 May 2023 13:49:01 +0000
Subject: [PATCH] Add error code for missing base expression in struct update
 syntax

---
 compiler/rustc_ast_lowering/messages.ftl      |  2 +-
 compiler/rustc_ast_lowering/src/errors.rs     |  4 +--
 compiler/rustc_error_codes/src/error_codes.rs |  1 +
 .../src/error_codes/E0797.md                  | 26 +++++++++++++++++++
 .../struct_destructure_fail.stderr            | 11 +++++---
 5 files changed, 38 insertions(+), 6 deletions(-)
 create mode 100644 compiler/rustc_error_codes/src/error_codes/E0797.md

diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index f4e3086f2b5..e7177402db1 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -35,7 +35,7 @@ ast_lowering_bad_return_type_notation_output =
 
 ast_lowering_base_expression_double_dot =
     base expression required after `..`
-    .label = add a base expression here
+    .suggestion = add a base expression here
 
 ast_lowering_clobber_abi_not_supported =
     `clobber_abi` is not supported on this target
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index faa22eece38..2811fe104cd 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -114,10 +114,10 @@ pub struct UnderscoreExprLhsAssign {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_base_expression_double_dot)]
+#[diag(ast_lowering_base_expression_double_dot, code = "E0797")]
 pub struct BaseExpressionDoubleDot {
     #[primary_span]
-    #[label]
+    #[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
     pub span: Span,
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index a1391cceb71..9cd9ed54d41 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -516,6 +516,7 @@ E0793: include_str!("./error_codes/E0793.md"),
 E0794: include_str!("./error_codes/E0794.md"),
 E0795: include_str!("./error_codes/E0795.md"),
 E0796: include_str!("./error_codes/E0796.md"),
+E0797: include_str!("./error_codes/E0797.md"),
 }
 
 // Undocumented removed error codes. Note that many removed error codes are kept in the list above
diff --git a/compiler/rustc_error_codes/src/error_codes/E0797.md b/compiler/rustc_error_codes/src/error_codes/E0797.md
new file mode 100644
index 00000000000..8a912307264
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0797.md
@@ -0,0 +1,26 @@
+Struct update syntax was used without a base expression.
+
+Erroneous code example:
+
+```compile_fail,E0797
+struct Foo {
+    fizz: u8,
+    buzz: u8
+}
+
+let f1 = Foo { fizz: 10, buzz: 1};
+let f2 = Foo { fizz: 10, .. }; // error
+```
+
+Using struct update syntax requires a 'base expression'.
+This will be used to fill remaining fields.
+
+```
+struct Foo {
+    fizz: u8,
+    buzz: u8
+}
+
+let f1 = Foo { fizz: 10, buzz: 1};
+let f2 = Foo { fizz: 10, ..f1 };
+```
diff --git a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr
index ae7b3d1e5a9..57851ed417e 100644
--- a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr
+++ b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr
@@ -12,11 +12,16 @@ error: functional record updates are not allowed in destructuring assignments
 LL |     Struct { a, ..d } = Struct { a: 1, b: 2 };
    |                   ^ help: consider removing the trailing pattern
 
-error: base expression required after `..`
+error[E0797]: base expression required after `..`
   --> $DIR/struct_destructure_fail.rs:15:19
    |
 LL |     Struct { a, .. };
-   |                   ^ add a base expression here
+   |                   ^
+   |
+help: add a base expression here
+   |
+LL |     Struct { a, ../* expr */ };
+   |                   ++++++++++
 
 error[E0026]: struct `Struct` does not have a field named `c`
   --> $DIR/struct_destructure_fail.rs:10:20
@@ -41,5 +46,5 @@ LL |     Struct { a, .. } = Struct { a: 1, b: 2 };
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0026, E0027.
+Some errors have detailed explanations: E0026, E0027, E0797.
 For more information about an error, try `rustc --explain E0026`.