about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2025-06-17 00:28:17 -0700
committerGitHub <noreply@github.com>2025-06-17 00:28:17 -0700
commitd4f23cdc915a74741e301df41c5eece2d8c78c5e (patch)
treed604e1e0da31675d1cbfffd03683bc34d33e2cf9 /tests
parentf2e9e2afacb6599c2ec3b0fe00427700a24425eb (diff)
parent2dd9cc113067113453efcff722e3a5c0893a6244 (diff)
downloadrust-d4f23cdc915a74741e301df41c5eece2d8c78c5e.tar.gz
rust-d4f23cdc915a74741e301df41c5eece2d8c78c5e.zip
Rollup merge of #142570 - jieyouxu:disunion, r=estebank
Reject union default field values

Fixes rust-lang/rust#142555.

The [`default_field_values` RFC][rfc] does not specify that default field values may be used on `union`s, and it's not clear how default field values may be used with `union`s without an design extension to the RFC. So, for now, reject trying to use default field values with `union`s.

### Review notes

- The first commit adds the `union` with default field values test case to `tests/ui/structs/default-field-values/failures.rs`, where `union`s with default field values are currently accepted.
- The second commit rejects trying to supply default field values to `union` definitions.
- When `default_field_values` feature gate is disabled, we show the feature gate error when the user tries to write `union`s with default field values. When the feature gate is enabled, we reject this usage with
   > unions cannot have default field values

``@rustbot`` label: +F-default_field_values

[rfc]: https://rust-lang.github.io/rfcs/3681-default-field-values.html
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/feature-gates/feature-gate-default-field-values.rs10
-rw-r--r--tests/ui/feature-gates/feature-gate-default-field-values.stderr54
-rw-r--r--tests/ui/structs/default-field-values/failures.rs6
-rw-r--r--tests/ui/structs/default-field-values/failures.stderr30
4 files changed, 74 insertions, 26 deletions
diff --git a/tests/ui/feature-gates/feature-gate-default-field-values.rs b/tests/ui/feature-gates/feature-gate-default-field-values.rs
index d2e41a71602..4631f51b9d8 100644
--- a/tests/ui/feature-gates/feature-gate-default-field-values.rs
+++ b/tests/ui/feature-gates/feature-gate-default-field-values.rs
@@ -58,6 +58,16 @@ pub enum OptEnum {
     }
 }
 
+// Default field values may not be used on `union`s (at least, this is not described in the accepted
+// RFC, and it's not currently clear how to extend the design to do so). We emit a feature gate
+// error when the feature is not enabled, but syntactically reject default field values when used
+// with unions when the feature is enabled. This can be adjusted if there's an acceptable design
+// extension, or just unconditionally reject always.
+union U {
+    x: i32 = 0,   //~ ERROR default values on fields are experimental
+    y: f32 = 0.0, //~ ERROR default values on fields are experimental
+}
+
 fn main () {
     let x = Foo { .. }; //~ ERROR base expression required after `..`
     let y = Foo::default();
diff --git a/tests/ui/feature-gates/feature-gate-default-field-values.stderr b/tests/ui/feature-gates/feature-gate-default-field-values.stderr
index 104d72a3986..292c3899072 100644
--- a/tests/ui/feature-gates/feature-gate-default-field-values.stderr
+++ b/tests/ui/feature-gates/feature-gate-default-field-values.stderr
@@ -124,8 +124,28 @@ LL |         optional: () = (),
    = help: add `#![feature(default_field_values)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error[E0658]: default values on fields are experimental
+  --> $DIR/feature-gate-default-field-values.rs:67:11
+   |
+LL |     x: i32 = 0,
+   |           ^^^^
+   |
+   = note: see issue #132162 <https://github.com/rust-lang/rust/issues/132162> for more information
+   = help: add `#![feature(default_field_values)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: default values on fields are experimental
+  --> $DIR/feature-gate-default-field-values.rs:68:11
+   |
+LL |     y: f32 = 0.0,
+   |           ^^^^^^
+   |
+   = note: see issue #132162 <https://github.com/rust-lang/rust/issues/132162> for more information
+   = help: add `#![feature(default_field_values)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:62:21
+  --> $DIR/feature-gate-default-field-values.rs:72:21
    |
 LL |     let x = Foo { .. };
    |                     ^
@@ -140,7 +160,7 @@ LL |     let x = Foo { ../* expr */ };
    |                     ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:64:29
+  --> $DIR/feature-gate-default-field-values.rs:74:29
    |
 LL |     let z = Foo { baz: 1, .. };
    |                             ^
@@ -155,7 +175,7 @@ LL |     let z = Foo { baz: 1, ../* expr */ };
    |                             ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:70:26
+  --> $DIR/feature-gate-default-field-values.rs:80:26
    |
 LL |     let x = Bar::Foo { .. };
    |                          ^
@@ -170,7 +190,7 @@ LL |     let x = Bar::Foo { ../* expr */ };
    |                          ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:72:34
+  --> $DIR/feature-gate-default-field-values.rs:82:34
    |
 LL |     let z = Bar::Foo { baz: 1, .. };
    |                                  ^
@@ -185,7 +205,7 @@ LL |     let z = Bar::Foo { baz: 1, ../* expr */ };
    |                                  ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:78:31
+  --> $DIR/feature-gate-default-field-values.rs:88:31
    |
 LL |     let x = Qux::<i32, 4> { .. };
    |                               ^
@@ -200,7 +220,7 @@ LL |     let x = Qux::<i32, 4> { ../* expr */ };
    |                               ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:79:73
+  --> $DIR/feature-gate-default-field-values.rs:89:73
    |
 LL |     assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, bay: 4, .. }, x));
    |                                                                         ^
@@ -215,7 +235,7 @@ LL |     assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, bay: 4, ../*
    |                                                                         ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:82:38
+  --> $DIR/feature-gate-default-field-values.rs:92:38
    |
 LL |     let y = Opt { mandatory: None, .. };
    |                                      ^
@@ -230,7 +250,7 @@ LL |     let y = Opt { mandatory: None, ../* expr */ };
    |                                      ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:86:47
+  --> $DIR/feature-gate-default-field-values.rs:96:47
    |
 LL |     assert!(matches!(Opt { mandatory: None, .. }, z));
    |                                               ^
@@ -245,7 +265,7 @@ LL |     assert!(matches!(Opt { mandatory: None, ../* expr */ }, z));
    |                                               ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:88:30
+  --> $DIR/feature-gate-default-field-values.rs:98:30
    |
 LL |     assert!(matches!(Opt { .. }, z));
    |                              ^
@@ -256,7 +276,7 @@ LL |     assert!(matches!(Opt { ../* expr */ }, z));
    |                              ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:90:44
+  --> $DIR/feature-gate-default-field-values.rs:100:44
    |
 LL |     assert!(matches!(Opt { optional: (), .. }, z));
    |                                            ^
@@ -267,7 +287,7 @@ LL |     assert!(matches!(Opt { optional: (), ../* expr */ }, z));
    |                                            ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:92:61
+  --> $DIR/feature-gate-default-field-values.rs:102:61
    |
 LL |     assert!(matches!(Opt { optional: (), mandatory: None, .. }, z));
    |                                                             ^
@@ -279,7 +299,7 @@ LL +     assert!(matches!(Opt { optional: (), mandatory: None,  }, z));
    |
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:94:51
+  --> $DIR/feature-gate-default-field-values.rs:104:51
    |
 LL |     let y = OptEnum::Variant { mandatory: None, .. };
    |                                                   ^
@@ -294,7 +314,7 @@ LL |     let y = OptEnum::Variant { mandatory: None, ../* expr */ };
    |                                                   ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:98:60
+  --> $DIR/feature-gate-default-field-values.rs:108:60
    |
 LL |     assert!(matches!(OptEnum::Variant { mandatory: None, .. }, z));
    |                                                            ^
@@ -309,7 +329,7 @@ LL |     assert!(matches!(OptEnum::Variant { mandatory: None, ../* expr */ }, z)
    |                                                            ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:100:43
+  --> $DIR/feature-gate-default-field-values.rs:110:43
    |
 LL |     assert!(matches!(OptEnum::Variant { .. }, z));
    |                                           ^
@@ -320,7 +340,7 @@ LL |     assert!(matches!(OptEnum::Variant { ../* expr */ }, z));
    |                                           ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:102:57
+  --> $DIR/feature-gate-default-field-values.rs:112:57
    |
 LL |     assert!(matches!(OptEnum::Variant { optional: (), .. }, z));
    |                                                         ^
@@ -331,7 +351,7 @@ LL |     assert!(matches!(OptEnum::Variant { optional: (), ../* expr */ }, z));
    |                                                         ++++++++++
 
 error[E0797]: base expression required after `..`
-  --> $DIR/feature-gate-default-field-values.rs:104:74
+  --> $DIR/feature-gate-default-field-values.rs:114:74
    |
 LL |     assert!(matches!(OptEnum::Variant { optional: (), mandatory: None, .. }, z));
    |                                                                          ^
@@ -342,7 +362,7 @@ LL -     assert!(matches!(OptEnum::Variant { optional: (), mandatory: None, .. }
 LL +     assert!(matches!(OptEnum::Variant { optional: (), mandatory: None,  }, z));
    |
 
-error: aborting due to 29 previous errors
+error: aborting due to 31 previous errors
 
 Some errors have detailed explanations: E0658, E0797.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/structs/default-field-values/failures.rs b/tests/ui/structs/default-field-values/failures.rs
index dee6566bd0e..9c5b7172929 100644
--- a/tests/ui/structs/default-field-values/failures.rs
+++ b/tests/ui/structs/default-field-values/failures.rs
@@ -49,6 +49,12 @@ enum E {
     Variant {} //~ ERROR the `#[default]` attribute may only be used on unit enum variants
 }
 
+union U
+{
+    x: i32 = 1,  //~ ERROR unions cannot have default field values
+    y: f32 = 2., //~ ERROR unions cannot have default field values
+}
+
 fn main () {
     let _ = Foo { .. }; // ok
     let _ = Foo::default(); // ok
diff --git a/tests/ui/structs/default-field-values/failures.stderr b/tests/ui/structs/default-field-values/failures.stderr
index aaa75fd3180..5e3d4c89c2a 100644
--- a/tests/ui/structs/default-field-values/failures.stderr
+++ b/tests/ui/structs/default-field-values/failures.stderr
@@ -12,6 +12,18 @@ error: default fields are not supported in tuple structs
 LL | pub struct Rak(i32 = 42);
    |                      ^^ default fields are only supported on structs
 
+error: unions cannot have default field values
+  --> $DIR/failures.rs:54:14
+   |
+LL |     x: i32 = 1,
+   |              ^
+
+error: unions cannot have default field values
+  --> $DIR/failures.rs:55:14
+   |
+LL |     y: f32 = 2.,
+   |              ^^
+
 error[E0277]: the trait bound `S: Default` is not satisfied
   --> $DIR/failures.rs:16:5
    |
@@ -28,19 +40,19 @@ LL | pub struct S;
    |
 
 error: missing field `bar` in initializer
-  --> $DIR/failures.rs:55:19
+  --> $DIR/failures.rs:61:19
    |
 LL |     let _ = Bar { .. };
    |                   ^ fields that do not have a defaulted value must be provided explicitly
 
 error: missing field `bar` in initializer
-  --> $DIR/failures.rs:56:27
+  --> $DIR/failures.rs:62:27
    |
 LL |     let _ = Bar { baz: 0, .. };
    |                           ^ fields that do not have a defaulted value must be provided explicitly
 
 error[E0308]: mismatched types
-  --> $DIR/failures.rs:60:17
+  --> $DIR/failures.rs:66:17
    |
 LL |     let _ = Rak(..);
    |             --- ^^ expected `i32`, found `RangeFull`
@@ -53,19 +65,19 @@ note: tuple struct defined here
 LL | pub struct Rak(i32 = 42);
    |            ^^^
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:60:17
+  --> $DIR/failures.rs:66:17
    |
 LL |     let _ = Rak(..);
    |                 ^^
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/failures.rs:62:13
+  --> $DIR/failures.rs:68:13
    |
 LL |     let _ = Rak(0, ..);
    |             ^^^    -- unexpected argument #2 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:62:20
+  --> $DIR/failures.rs:68:20
    |
 LL |     let _ = Rak(0, ..);
    |                    ^^
@@ -81,13 +93,13 @@ LL +     let _ = Rak(0);
    |
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/failures.rs:64:13
+  --> $DIR/failures.rs:70:13
    |
 LL |     let _ = Rak(.., 0);
    |             ^^^ -- unexpected argument #1 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:64:17
+  --> $DIR/failures.rs:70:17
    |
 LL |     let _ = Rak(.., 0);
    |                 ^^
@@ -102,7 +114,7 @@ LL -     let _ = Rak(.., 0);
 LL +     let _ = Rak(0);
    |
 
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0061, E0277, E0308.
 For more information about an error, try `rustc --explain E0061`.