about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-08 16:40:14 +0000
committerbors <bors@rust-lang.org>2021-08-08 16:40:14 +0000
commit442e627beef1c582b81b241bd862fea185937585 (patch)
tree4e341d194019a77c8ccc94d83e893eb2314d9106
parent4e886d68766719a7fc1714c52a0e7e81929e8b8e (diff)
parente500cd214011449a1954d7aa4445d4e65a49ea76 (diff)
downloadrust-442e627beef1c582b81b241bd862fea185937585.tar.gz
rust-442e627beef1c582b81b241bd862fea185937585.zip
Auto merge of #87697 - GuillaumeGomez:add-e0784, r=nagisa
Assign E0784 error code for union expression errors
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs3
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0784.md32
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs8
-rw-r--r--src/test/ui/union/union-fields-2.mirunsafeck.stderr10
-rw-r--r--src/test/ui/union/union-fields-2.thirunsafeck.stderr10
5 files changed, 51 insertions, 12 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 719c2c6768b..c2e62328cb1 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -479,6 +479,7 @@ E0780: include_str!("./error_codes/E0780.md"),
 E0781: include_str!("./error_codes/E0781.md"),
 E0782: include_str!("./error_codes/E0782.md"),
 E0783: include_str!("./error_codes/E0783.md"),
+E0784: include_str!("./error_codes/E0784.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
@@ -636,7 +637,7 @@ E0783: include_str!("./error_codes/E0783.md"),
     E0711, // a feature has been declared with conflicting stability attributes
     E0717, // rustc_promotable without stability attribute
 //  E0721, // `await` keyword
-//    E0723, unstable feature in `const` context
+//  E0723, unstable feature in `const` context
     E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
     E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0784.md b/compiler/rustc_error_codes/src/error_codes/E0784.md
new file mode 100644
index 00000000000..b20b7039bf4
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0784.md
@@ -0,0 +1,32 @@
+A union expression does not have exactly one field.
+
+Erroneous code example:
+
+```compile_fail,E0784
+union Bird {
+    pigeon: u8,
+    turtledove: u16,
+}
+
+let bird = Bird {}; // error
+let bird = Bird { pigeon: 0, turtledove: 1 }; // error
+```
+
+The key property of unions is that all fields of a union share common storage.
+As a result, writes to one field of a union can overwrite its other fields, and
+size of a union is determined by the size of its largest field.
+
+You can find more information about the union types in the [Rust reference].
+
+Working example:
+
+```
+union Bird {
+    pigeon: u8,
+    turtledove: u16,
+}
+
+let bird = Bird { pigeon: 0 }; // OK
+```
+
+[Rust reference]: https://doc.rust-lang.org/reference/items/unions.html
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index e95884ae23b..831b573e156 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1304,7 +1304,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Make sure the programmer specified correct number of fields.
         if kind_name == "union" {
             if ast_fields.len() != 1 {
-                tcx.sess.span_err(span, "union expressions should have exactly one field");
+                struct_span_err!(
+                    tcx.sess,
+                    span,
+                    E0784,
+                    "union expressions should have exactly one field",
+                )
+                .emit();
             }
         } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
             let no_accessible_remaining_fields = remaining_fields
diff --git a/src/test/ui/union/union-fields-2.mirunsafeck.stderr b/src/test/ui/union/union-fields-2.mirunsafeck.stderr
index 867bf75dfdc..90ad16402f7 100644
--- a/src/test/ui/union/union-fields-2.mirunsafeck.stderr
+++ b/src/test/ui/union/union-fields-2.mirunsafeck.stderr
@@ -1,10 +1,10 @@
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:10:13
    |
 LL |     let u = U {};
    |             ^
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:12:13
    |
 LL |     let u = U { a: 0, b: 1 };
@@ -18,13 +18,13 @@ LL |     let u = U { a: 0, b: 1, c: 2 };
    |
    = note: available fields are: `a`, `b`
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:13:13
    |
 LL |     let u = U { a: 0, b: 1, c: 2 };
    |             ^
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:15:13
    |
 LL |     let u = U { ..u };
@@ -80,5 +80,5 @@ LL |     let U { a, .. } = u;
 
 error: aborting due to 13 previous errors
 
-Some errors have detailed explanations: E0026, E0436, E0560.
+Some errors have detailed explanations: E0026, E0436, E0560, E0784.
 For more information about an error, try `rustc --explain E0026`.
diff --git a/src/test/ui/union/union-fields-2.thirunsafeck.stderr b/src/test/ui/union/union-fields-2.thirunsafeck.stderr
index 867bf75dfdc..90ad16402f7 100644
--- a/src/test/ui/union/union-fields-2.thirunsafeck.stderr
+++ b/src/test/ui/union/union-fields-2.thirunsafeck.stderr
@@ -1,10 +1,10 @@
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:10:13
    |
 LL |     let u = U {};
    |             ^
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:12:13
    |
 LL |     let u = U { a: 0, b: 1 };
@@ -18,13 +18,13 @@ LL |     let u = U { a: 0, b: 1, c: 2 };
    |
    = note: available fields are: `a`, `b`
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:13:13
    |
 LL |     let u = U { a: 0, b: 1, c: 2 };
    |             ^
 
-error: union expressions should have exactly one field
+error[E0784]: union expressions should have exactly one field
   --> $DIR/union-fields-2.rs:15:13
    |
 LL |     let u = U { ..u };
@@ -80,5 +80,5 @@ LL |     let U { a, .. } = u;
 
 error: aborting due to 13 previous errors
 
-Some errors have detailed explanations: E0026, E0436, E0560.
+Some errors have detailed explanations: E0026, E0436, E0560, E0784.
 For more information about an error, try `rustc --explain E0026`.