diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 3b0f9a65e07f3..2ddaf9201098e 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -182,7 +182,7 @@ declare_features! ( (removed, unsafe_no_drop_flag, "1.0.0", None, None, None), /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue. (removed, untagged_unions, "1.13.0", Some(55149), None, - Some("unions with `Copy` and `MaybeUninit` fields are stable; there is no intent to stabilize more")), + Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more")), /// Allows `#[unwind(..)]`. /// /// Permits specifying whether a function should permit unwinding or abort on unwind. diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 9c522807bf6ba..dfcd35d2178e7 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -422,7 +422,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b } _ => { // Fallback case: allow `ManuallyDrop` and things that are `Copy`. - ty.ty_adt_def().map_or(false, |adt_def| adt_def.is_manually_drop()) + ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) || ty.is_copy_modulo_regions(tcx.at(span), param_env) } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index dd712fd7ed71d..f98ae46c58730 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -72,6 +72,7 @@ This API is completely unstable and subject to change. #![feature(once_cell)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] +#![feature(is_some_with)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr index 7e9abc3ffa7e1..ae5f6b2baee40 100644 --- a/src/test/ui/consts/invalid-union.32bit.stderr +++ b/src/test/ui/consts/invalid-union.32bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-union.rs:40:1 + --> $DIR/invalid-union.rs:41:1 | LL | fn main() { | ^^^^^^^^^ constructing invalid value at ..y..0: encountered `UnsafeCell` in a `const` @@ -10,7 +10,7 @@ LL | fn main() { } error: erroneous constant used - --> $DIR/invalid-union.rs:41:25 + --> $DIR/invalid-union.rs:42:25 | LL | let _: &'static _ = &C; | ^^ referenced constant has errors @@ -24,7 +24,7 @@ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. Future incompatibility report: Future breakage diagnostic: error: erroneous constant used - --> $DIR/invalid-union.rs:41:25 + --> $DIR/invalid-union.rs:42:25 | LL | let _: &'static _ = &C; | ^^ referenced constant has errors diff --git a/src/test/ui/union/field_checks.rs b/src/test/ui/union/field_checks.rs index 216f7372a1cff..d5d1e44ac855c 100644 --- a/src/test/ui/union/field_checks.rs +++ b/src/test/ui/union/field_checks.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength use std::mem::ManuallyDrop; union U1 { // OK @@ -45,6 +44,10 @@ union U5Nested { // a nested union that drops is NOT OK nest: U5, //~ ERROR unions cannot contain fields that may need dropping } +union U5Nested2 { // for now we don't special-case empty arrays + nest: [U5; 0], //~ ERROR unions cannot contain fields that may need dropping +} + union U6 { // OK s: &'static i32, m: &'static mut i32, @@ -54,4 +57,9 @@ union U7 { // OK f: (&'static mut i32, ManuallyDrop, i32), } +union U8 { // OK + f1: [(&'static mut i32, i32); 8], + f2: [ManuallyDrop; 2], +} + fn main() {} diff --git a/src/test/ui/union/field_checks.stderr b/src/test/ui/union/field_checks.stderr index 0e0e545b01a46..1f97e97ac6ede 100644 --- a/src/test/ui/union/field_checks.stderr +++ b/src/test/ui/union/field_checks.stderr @@ -1,5 +1,5 @@ error[E0740]: unions cannot contain fields that may need dropping - --> $DIR/field_checks.rs:25:5 + --> $DIR/field_checks.rs:24:5 | LL | a: String, | ^^^^^^^^^ @@ -11,7 +11,7 @@ LL | a: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + error[E0740]: unions cannot contain fields that may need dropping - --> $DIR/field_checks.rs:29:5 + --> $DIR/field_checks.rs:28:5 | LL | a: std::cell::RefCell, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | a: std::mem::ManuallyDrop>, | +++++++++++++++++++++++ + error[E0740]: unions cannot contain fields that may need dropping - --> $DIR/field_checks.rs:33:5 + --> $DIR/field_checks.rs:32:5 | LL | a: T, | ^^^^ @@ -35,7 +35,7 @@ LL | a: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + error[E0740]: unions cannot contain fields that may need dropping - --> $DIR/field_checks.rs:45:5 + --> $DIR/field_checks.rs:44:5 | LL | nest: U5, | ^^^^^^^^ @@ -46,6 +46,18 @@ help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_> LL | nest: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + -error: aborting due to 4 previous errors +error[E0740]: unions cannot contain fields that may need dropping + --> $DIR/field_checks.rs:48:5 + | +LL | nest: [U5; 0], + | ^^^^^^^^^^^^^ + | + = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type +help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped + | +LL | nest: std::mem::ManuallyDrop<[U5; 0]>, + | +++++++++++++++++++++++ + + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0740`. diff --git a/src/test/ui/union/union-nonrepresentable.rs b/src/test/ui/union/union-nonrepresentable.rs index afa73857ac2a5..4bdf7c6872fa5 100644 --- a/src/test/ui/union/union-nonrepresentable.rs +++ b/src/test/ui/union/union-nonrepresentable.rs @@ -1,4 +1,3 @@ - union U { //~ ERROR recursive type `U` has infinite size a: u8, b: std::mem::ManuallyDrop, diff --git a/src/test/ui/union/union-nonrepresentable.stderr b/src/test/ui/union/union-nonrepresentable.stderr index a2380d8bc0e99..9804b1418b208 100644 --- a/src/test/ui/union/union-nonrepresentable.stderr +++ b/src/test/ui/union/union-nonrepresentable.stderr @@ -1,5 +1,5 @@ error[E0072]: recursive type `U` has infinite size - --> $DIR/union-nonrepresentable.rs:2:1 + --> $DIR/union-nonrepresentable.rs:1:1 | LL | union U { | ^^^^^^^ recursive type has infinite size diff --git a/src/tools/clippy/tests/ui/derive.rs b/src/tools/clippy/tests/ui/derive.rs index 4e46bf1399173..b276c384c04ea 100644 --- a/src/tools/clippy/tests/ui/derive.rs +++ b/src/tools/clippy/tests/ui/derive.rs @@ -1,7 +1,7 @@ -#![feature(untagged_unions)] #![allow(dead_code)] #![warn(clippy::expl_impl_clone_on_copy)] + #[derive(Copy)] struct Qux; diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs index 7ece66a1ccb6f..f0c59b4080be3 100644 --- a/src/tools/clippy/tests/ui/no_effect.rs +++ b/src/tools/clippy/tests/ui/no_effect.rs @@ -4,7 +4,7 @@ #![allow(path_statements)] #![allow(clippy::deref_addrof)] #![allow(clippy::redundant_field_names)] -#![feature(untagged_unions)] + struct Unit; struct Tuple(i32);