From 25c44f4d89ce39f82ae941b0e9e38f6049d76e90 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 14 Mar 2023 14:56:05 +0000 Subject: [PATCH 1/3] Constified `array::from_fn` --- library/core/src/array/mod.rs | 30 ++++++++++++++++++------------ library/core/src/lib.rs | 6 +++++- library/core/src/ops/try_trait.rs | 7 +++++-- library/core/src/ptr/mod.rs | 4 +++- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 1643842d60756..42b6c48b684d3 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -11,6 +11,7 @@ use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; use crate::iter::UncheckedIterator; +use crate::marker::Destruct; use crate::mem::{self, MaybeUninit}; use crate::ops::{ ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try, @@ -55,9 +56,11 @@ pub use iter::IntoIter; /// ``` #[inline] #[stable(feature = "array_from_fn", since = "1.63.0")] -pub fn from_fn(cb: F) -> [T; N] +#[rustc_const_unstable(feature = "const_array_from_fn", issue = "none")] +pub const fn from_fn(cb: F) -> [T; N] where - F: FnMut(usize) -> T, + F: ~const FnMut(usize) -> T + ~const Destruct, + T: ~const Destruct, { try_from_fn(NeverShortCircuit::wrap_mut_1(cb)).0 } @@ -93,11 +96,12 @@ where /// ``` #[inline] #[unstable(feature = "array_try_from_fn", issue = "89379")] -pub fn try_from_fn(cb: F) -> ChangeOutputType +pub const fn try_from_fn(cb: F) -> ChangeOutputType where - F: FnMut(usize) -> R, - R: Try, - R::Residual: Residual<[R::Output; N]>, + F: ~const FnMut(usize) -> R + ~const Destruct, + R: ~const Try, + R::Residual: ~const Residual<[R::Output; N]>, + R::Output: ~const Destruct, { let mut array = MaybeUninit::uninit_array::(); match try_from_fn_erased(&mut array, cb) { @@ -835,12 +839,14 @@ where /// not optimizing away. So if you give it a shot, make sure to watch what /// happens in the codegen tests. #[inline] -fn try_from_fn_erased( +#[rustc_const_unstable(feature = "const_array_from_fn", issue = "none")] +const fn try_from_fn_erased( buffer: &mut [MaybeUninit], - mut generator: impl FnMut(usize) -> R, + mut generator: impl ~const FnMut(usize) -> R + ~const Destruct, ) -> ControlFlow where - R: Try, + R: ~const Try, + R::Output: ~const Destruct, { let mut guard = Guard { array_mut: buffer, initialized: 0 }; @@ -866,7 +872,7 @@ where /// /// To minimize indirection fields are still pub but callers should at least use /// `push_unchecked` to signal that something unsafe is going on. -struct Guard<'a, T> { +struct Guard<'a, T: ~const Destruct> { /// The array to be initialized. pub array_mut: &'a mut [MaybeUninit], /// The number of items that have been initialized so far. @@ -880,7 +886,7 @@ impl Guard<'_, T> { /// /// No more than N elements must be initialized. #[inline] - pub unsafe fn push_unchecked(&mut self, item: T) { + pub const unsafe fn push_unchecked(&mut self, item: T) { // SAFETY: If `initialized` was correct before and the caller does not // invoke this method more than N times then writes will be in-bounds // and slots will not be initialized more than once. @@ -891,7 +897,7 @@ impl Guard<'_, T> { } } -impl Drop for Guard<'_, T> { +impl const Drop for Guard<'_, T> { fn drop(&mut self) { debug_assert!(self.initialized <= self.array_mut.len()); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1076d357070ef..5b66f4d8076b3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -103,6 +103,7 @@ #![feature(const_align_of_val_raw)] #![feature(const_alloc_layout)] #![feature(const_arguments_as_str)] +#![feature(const_array_from_fn)] #![feature(const_array_into_iter_constructors)] #![feature(const_bigint_helper_methods)] #![feature(const_black_box)] @@ -112,6 +113,7 @@ #![feature(const_clone)] #![feature(const_cmp)] #![feature(const_discriminant)] +#![feature(const_drop_in_place)] #![feature(const_eval_select)] #![feature(const_exact_div)] #![feature(const_float_bits_conv)] @@ -129,9 +131,11 @@ #![feature(const_ipv6)] #![feature(const_iter)] #![feature(const_likely)] -#![feature(const_maybe_uninit_uninit_array)] +#![feature(const_maybe_uninit_array_assume_init)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] +#![feature(const_maybe_uninit_write)] +#![feature(const_maybe_uninit_uninit_array)] #![feature(const_nonnull_new)] #![feature(const_num_from_num)] #![feature(const_ops)] diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index c254803fbf650..916b366d5013c 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -1,3 +1,4 @@ +use crate::marker::Destruct; use crate::ops::ControlFlow; /// The `?` operator and `try {}` blocks. @@ -384,8 +385,10 @@ impl NeverShortCircuit { /// This is useful for implementing infallible functions in terms of the `try_` ones, /// without accidentally capturing extra generic parameters in a closure. #[inline] - pub fn wrap_mut_1(mut f: impl FnMut(A) -> T) -> impl FnMut(A) -> NeverShortCircuit { - move |a| NeverShortCircuit(f(a)) + pub const fn wrap_mut_1( + mut f: impl ~const FnMut(A) -> T + ~const Destruct, + ) -> impl ~const FnMut(A) -> NeverShortCircuit + ~const Destruct { + const move |a| NeverShortCircuit(f(a)) } #[inline] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5884a8ca30807..dd60a8afc2b8b 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -374,6 +374,7 @@ use crate::hash; use crate::intrinsics::{ self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping, }; +use crate::marker::Destruct; use crate::mem::{self, MaybeUninit}; @@ -485,9 +486,10 @@ mod mut_ptr; /// assert!(weak.upgrade().is_none()); /// ``` #[stable(feature = "drop_in_place", since = "1.8.0")] +#[rustc_const_unstable(feature = "const_drop_in_place", issue = "none")] #[lang = "drop_in_place"] #[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { +pub const unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. From 8f3ff87b4e7ba4b63b5b83140b815fbfd3cf15f7 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 17 Mar 2023 04:52:34 +0000 Subject: [PATCH 2/3] update ui test --- .../drop_in_place_retag.stderr | 4 +- .../unaligned_pointers/drop_in_place.stderr | 4 +- ...place.Test.SimplifyCfg-make_shim.after.mir | 18 +++---- ...[String].AddMovesForPackedDrops.before.mir | 48 +++++++++---------- ...Vec_i32_.AddMovesForPackedDrops.before.mir | 22 ++++----- tests/ui/consts/issue-102117.rs | 3 +- tests/ui/consts/issue-102117.stderr | 34 ++++++------- 7 files changed, 64 insertions(+), 69 deletions(-) diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr index 7f2917e795053..8e71a41d5d73f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: trying to retag from for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub const unsafe fn drop_in_place(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | trying to retag from for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location | this error occurs as part of retag at ALLOC[0x0..0x1] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index ef20b43c118ff..17fe05a78cce4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +LL | pub const unsafe fn drop_in_place(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir index f495f147be3df..55a9adb1b2308 100644 --- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir @@ -1,22 +1,22 @@ // MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim fn std::ptr::drop_in_place(_1: *mut Test) -> () { - let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _3: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _3: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 bb0: { - _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _4 = ::drop(move _3) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _4 = ::drop(move _3) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 // mir::Constant // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL // + literal: Const { ty: for<'a> fn(&'a mut Test) {::drop}, val: Value() } } bb1: { - return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } } diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir index 3884d29db4177..394a4fd3e5fb7 100644 --- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir +++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir @@ -1,55 +1,55 @@ // MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops fn std::ptr::drop_in_place(_1: *mut [String]) -> () { - let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _4: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _5: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _6: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _7: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _4: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _5: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _6: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _7: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 bb0: { - goto -> bb8; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb8; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb1: { - return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb2 (cleanup): { - resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb3 (cleanup): { - _4 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - drop((*_4)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + drop((*_4)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb4 (cleanup): { - _5 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _5) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _5 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + switchInt(move _5) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb5: { - _6 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - drop((*_6)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _6 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + drop((*_6)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb6: { - _7 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _7) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _7 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + switchInt(move _7) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb7: { - _2 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _2 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _3 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb8: { - goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } } diff --git a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir index ed9f3bdbdf4d6..916e5a2746aab 100644 --- a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir +++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir @@ -1,37 +1,37 @@ // MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops fn std::ptr::drop_in_place(_1: *mut Vec) -> () { - let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _2: &mut std::vec::Vec; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _2: &mut std::vec::Vec; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 bb0: { - goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb1: { - return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb2 (cleanup): { - resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb3: { - goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb4 (cleanup): { - drop(((*_1).0: alloc::raw_vec::RawVec)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop(((*_1).0: alloc::raw_vec::RawVec)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb5: { - drop(((*_1).0: alloc::raw_vec::RawVec)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop(((*_1).0: alloc::raw_vec::RawVec)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 } bb6: { - _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 + _3 = as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:80 // mir::Constant // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL // + literal: Const { ty: for<'a> fn(&'a mut Vec) { as Drop>::drop}, val: Value() } diff --git a/tests/ui/consts/issue-102117.rs b/tests/ui/consts/issue-102117.rs index 3ed90aed2350d..39ee4be129f26 100644 --- a/tests/ui/consts/issue-102117.rs +++ b/tests/ui/consts/issue-102117.rs @@ -17,10 +17,9 @@ impl VTable { &VTable { layout: Layout::new::(), type_id: TypeId::of::(), - //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough drop_in_place: unsafe { transmute::(drop_in_place::) + //~^ ERROR can't drop `T` in const contexts }, } } diff --git a/tests/ui/consts/issue-102117.stderr b/tests/ui/consts/issue-102117.stderr index f42bcf90fb756..ef01863d1cb26 100644 --- a/tests/ui/consts/issue-102117.stderr +++ b/tests/ui/consts/issue-102117.stderr @@ -1,25 +1,21 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/issue-102117.rs:19:26 +error[E0277]: can't drop `T` in const contexts + --> $DIR/issue-102117.rs:21:88 | -LL | type_id: TypeId::of::(), - | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds +LL | transmute::(drop_in_place::) + | ^ the trait `~const Destruct` is not implemented for `T` | -help: consider adding an explicit lifetime bound... +note: the trait `Destruct` is implemented for `T`, but that implementation is not `const` + --> $DIR/issue-102117.rs:21:88 | -LL | pub fn new() -> &'static Self { - | +++++++++ - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/issue-102117.rs:19:26 - | -LL | type_id: TypeId::of::(), - | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound... +LL | transmute::(drop_in_place::) + | ^ +note: required by a bound in `std::ptr::drop_in_place` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +help: consider restricting type parameter `T` | -LL | pub fn new() -> &'static Self { - | +++++++++ +LL | pub fn new() -> &'static Self { + | ++++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0310`. +For more information about this error, try `rustc --explain E0277`. From 8300869a2d7bec4769b8663cac497903effe52d0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 19 Mar 2023 08:05:45 +0000 Subject: [PATCH 3/3] add tracking issue and unit testt --- library/core/src/array/mod.rs | 4 ++-- library/core/src/ptr/mod.rs | 2 +- library/core/tests/array.rs | 3 +++ library/core/tests/lib.rs | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 42b6c48b684d3..6c90979cce44c 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -56,7 +56,7 @@ pub use iter::IntoIter; /// ``` #[inline] #[stable(feature = "array_from_fn", since = "1.63.0")] -#[rustc_const_unstable(feature = "const_array_from_fn", issue = "none")] +#[rustc_const_unstable(feature = "const_array_from_fn", issue = "109341")] pub const fn from_fn(cb: F) -> [T; N] where F: ~const FnMut(usize) -> T + ~const Destruct, @@ -839,7 +839,7 @@ where /// not optimizing away. So if you give it a shot, make sure to watch what /// happens in the codegen tests. #[inline] -#[rustc_const_unstable(feature = "const_array_from_fn", issue = "none")] +#[rustc_const_unstable(feature = "const_array_from_fn", issue = "109341")] const fn try_from_fn_erased( buffer: &mut [MaybeUninit], mut generator: impl ~const FnMut(usize) -> R + ~const Destruct, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index dd60a8afc2b8b..1d182ddef22bb 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -486,7 +486,7 @@ mod mut_ptr; /// assert!(weak.upgrade().is_none()); /// ``` #[stable(feature = "drop_in_place", since = "1.8.0")] -#[rustc_const_unstable(feature = "const_drop_in_place", issue = "none")] +#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")] #[lang = "drop_in_place"] #[allow(unconditional_recursion)] pub const unsafe fn drop_in_place(to_drop: *mut T) { diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 5327e4f813925..e5bc0628c5cf5 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -376,6 +376,9 @@ fn cell_allows_array_cycle() { fn array_from_fn() { let array = core::array::from_fn(|idx| idx); assert_eq!(array, [0, 1, 2, 3, 4]); + + const ARR: [usize; 5] = core::array::from_fn(const |idx| idx); + assert_eq!(ARR, [0, 1, 2, 3, 4]); } #[test] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 637cc6e9f629b..2cc9ca7709f0a 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -5,12 +5,14 @@ #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(const_align_offset)] +#![feature(const_array_from_fn)] #![feature(const_assume)] #![feature(const_align_of_val_raw)] #![feature(const_black_box)] #![feature(const_bool_to_option)] #![feature(const_caller_location)] #![feature(const_cell_into_inner)] +#![feature(const_closures)] #![feature(const_convert)] #![feature(const_for)] #![feature(const_hash)] @@ -116,6 +118,7 @@ #![feature(utf8_chunks)] #![feature(is_ascii_octdigit)] #![feature(get_many_mut)] +#![allow(incomplete_features)] #![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)]