diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 65999ba707c85..6175e7a5a0844 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -478,6 +478,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 0000000000000..b20b7039bf472 --- /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 08258aac96f2f..3f3640aee4f61 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 867bf75dfdc0b..90ad16402f7db 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 867bf75dfdc0b..90ad16402f7db 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`.