about summary refs log tree commit diff
path: root/library/alloc/src
AgeCommit message (Collapse)AuthorLines
2024-11-10split up the first paragraph of doc comments for better summariesbinarycat-5/+11
2024-11-06Inline str::repeatKornel-0/+1
2024-11-04btree: don't leak value if destructor of key panicsLukas Markeffsky-2/+64
2024-11-03Rollup merge of #132393 - zedddie16:issue-131865-fix, r=tgross35Matthias Krüger-0/+10
Docs: added brief colon explanation https://github.com/rust-lang/rust/issues/131865 (this is my first attempt at contributing, feedback is welcome)
2024-11-03Rollup merge of #129329 - eduardosm:rc-from-mut-slice, r=dtolnayMatthias Krüger-0/+156
Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>` ACP: https://github.com/rust-lang/libs-team/issues/424 New API: ```rust impl<T: Clone> From<&mut [T]> for Box<[T]> impl From<&mut str> for Box<str> impl From<&mut CStr> for Box<CStr> impl From<&mut OsStr> for Box<OsStr> impl From<&mut Path> for Box<Path> impl<T: Clone> From<&mut [T]> for Rc<[T]> impl From<&mut str> for Rc<str> impl From<&mut CStr> for Rc<CStr> impl From<&mut OsStr> for Rc<OsStr> impl From<&mut Path> for Rc<Path> impl<T: Clone> From<&mut [T]> for Arc<[T]> impl From<&mut str> for Arc<str> impl From<&mut CStr> for Arc<CStr> impl From<&mut OsStr> for Arc<OsStr> impl From<&mut Path> for Arc<Path> ``` Since they are trait implementations, I think these are insta-stable. As mentioned in https://github.com/rust-lang/libs-team/issues/424#issuecomment-2299415749, a crater run might be needed.
2024-11-02Rustdoc: added brief colon explanationtuturuu-0/+10
2024-10-30rustdoc-search: simplify rules for generics and type paramsMichael Howell-0/+3
This commit is a response to feedback on the displayed type signatures results, by making generics act stricter. Generics are tightened by making order significant. This means `Vec<Allocator>` now matches only with a true vector of allocators, instead of matching the second type param. It also makes unboxing within generics stricter, so `Result<A, B>` only matches if `B` is in the error type and `A` is in the success type. The top level of the function search is unaffected. Find the discussion on: * <https://rust-lang.zulipchat.com/#narrow/stream/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449965149> * <https://github.com/rust-lang/rust/pull/124544#issuecomment-2204272265> * <https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/deciding.20on.20semantics.20of.20generics.20in.20rustdoc.20search/near/476841363>
2024-10-29Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>`Eduardo Sánchez Muñoz-0/+156
2024-10-29Auto merge of #132231 - lukas-code:rc-plug-leaks, r=tgross35bors-18/+26
Rc/Arc: don't leak the allocation if drop panics Currently, when the last `Rc<T>` or `Arc<T>` is dropped and the destructor of `T` panics, the allocation will be leaked. This leak is unnecessary since the data cannot be (safely) accessed again and `Box` already deallocates in this case, so let's do the same for `Rc` and `Arc`, too.
2024-10-28Rc destructor: tweak inliningLukas Markeffsky-8/+17
2024-10-28Split `boxed.rs` into a few modulesMaybe Lapkin-970/+1003
+ some minor style changes
2024-10-28Impl TryFrom<Vec<u8>> for StringElichai Turkel-0/+18
2024-10-27Rc/Arc: don't leak the allocation if drop panicsLukas Markeffsky-18/+17
2024-10-25Auto merge of #131349 - RalfJung:const-stability-checks, r=compiler-errorsbors-3/+3
Const stability checks v2 The const stability system has served us well ever since `const fn` were first stabilized. It's main feature is that it enforces *recursive* validity -- a stable const fn cannot internally make use of unstable const features without an explicit marker in the form of `#[rustc_allow_const_fn_unstable]`. This is done to make sure that we don't accidentally expose unstable const features on stable in a way that would be hard to take back. As part of this, it is enforced that a `#[rustc_const_stable]` can only call `#[rustc_const_stable]` functions. However, some problems have been coming up with increased usage: - It is baffling that we have to mark private or even unstable functions as `#[rustc_const_stable]` when they are used as helpers in regular stable `const fn`, and often people will rather add `#[rustc_allow_const_fn_unstable]` instead which was not our intention. - The system has several gaping holes: a private `const fn` without stability attributes whose inherited stability (walking up parent modules) is `#[stable]` is allowed to call *arbitrary* unstable const operations, but can itself be called from stable `const fn`. Similarly, `#[allow_internal_unstable]` on a macro completely bypasses the recursive nature of the check. Fundamentally, the problem is that we have *three* disjoint categories of functions, and not enough attributes to distinguish them: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features Functions in the first two categories cannot use unstable const features and they can only call functions from the first two categories. This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, all the holes mentioned above have been closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to be manually marked `#[rustc_const_stable_indirect]` to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required. Also see the updated dev-guide at https://github.com/rust-lang/rustc-dev-guide/pull/2098. I think in the future we may want to tweak this further, so that in the hopefully common case where a public function's const-stability just exactly mirrors its regular stability, we never have to add any attribute. But right now, once the function is stable this requires `#[rustc_const_stable]`. ### Open question There is one point I could see we might want to do differently, and that is putting `#[rustc_const_unstable]` functions (but not intrinsics) in category 2 by default, and requiring an extra attribute for `#[rustc_const_not_exposed_on_stable]` or so. This would require a bunch of extra annotations, but would have the advantage that turning a `#[rustc_const_unstable]` into `#[rustc_const_stable]` will never change the way the function is const-checked. Currently, we often discover in the const stabilization PR that a function needs some other unstable const things, and then we rush to quickly deal with that. In this alternative universe, we'd work towards getting rid of the `rustc_const_not_exposed_on_stable` before stabilization, and once that is done stabilization becomes a trivial matter. `#[rustc_const_stable_indirect]` would then only be used for intrinsics. I think I like this idea, but might want to do it in a follow-up PR, as it will need a whole bunch of annotations in the standard library. Also, we probably want to convert all const intrinsics to the "new" form (`#[rustc_intrinsic]` instead of an `extern` block) before doing this to avoid having to deal with two different ways of declaring intrinsics. Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api` Part of https://github.com/rust-lang/rust/issues/129815 (but not finished since this is not yet sufficient to safely let us expose `const fn` from hashbrown) Fixes https://github.com/rust-lang/rust/issues/131073 by making it so that const-stable functions are always stable try-job: test-various
2024-10-25Re-do recursive const stability checksRalf Jung-3/+3
Fundamentally, we have *three* disjoint categories of functions: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, several holes in recursive const stability checking are being closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to *not* be `rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
2024-10-25library: consistently use American spelling for 'behavior'Ralf Jung-7/+7
2024-10-24Rollup merge of #130225 - adetaylor:rename-old-receiver, r=wesleywiserStuart Cook-10/+10
Rename Receiver -> LegacyReceiver As part of the "arbitrary self types v2" project, we are going to replace the current `Receiver` trait with a new mechanism based on a new, different `Receiver` trait. This PR renames the old trait to get it out the way. Naming is hard. Options considered included: * HardCodedReceiver (because it should only be used for things in the standard library, and hence is sort-of hard coded) * LegacyReceiver * TargetLessReceiver * OldReceiver These are all bad names, but fortunately this will be temporary. Assuming the new mechanism proceeds to stabilization as intended, the legacy trait will be removed altogether. Although we expect this trait to be used only in the standard library, we suspect it may be in use elsehwere, so we're landing this change separately to identify any surprising breakages. It's known that this trait is used within the Rust for Linux project; a patch is in progress to remove their dependency. This is a part of the arbitrary self types v2 project, https://github.com/rust-lang/rfcs/pull/3519 https://github.com/rust-lang/rust/issues/44874 r? `@wesleywiser`
2024-10-23"innermost", "outermost", "leftmost", and "rightmost" don't need hyphensJosh Triplett-4/+4
These are all standard dictionary words and don't require hyphenation.
2024-10-23Rollup merge of #132031 - slanterns:rc_default, r=ibraheemdevMatthias Krüger-8/+20
Optimize `Rc<T>::default` The missing piece of https://github.com/rust-lang/rust/pull/131460. Also refactored `Arc<T>::default` by using a safe `NonNull::from(Box::leak(_))` to replace the unnecessarily unsafe call to `NonNull::new_unchecked(Box::into_raw(_))`. The remaining unsafety is coming from `[Rc|Arc]::from_inner`, which is safe from the construction of `[Rc|Arc]Inner`.
2024-10-23Auto merge of #131929 - LaihoE:replace_default_capacity, r=joboetbors-4/+8
better default capacity for str::replace Adds smarter capacity for str::replace in cases where we know that the output will be at least as long as the original string.
2024-10-22better default capacity for str::replaceLaiho-4/+8
2024-10-22Rename Receiver -> LegacyReceiverAdrian Taylor-10/+10
As part of the "arbitrary self types v2" project, we are going to replace the current `Receiver` trait with a new mechanism based on a new, different `Receiver` trait. This PR renames the old trait to get it out the way. Naming is hard. Options considered included: * HardCodedReceiver (because it should only be used for things in the standard library, and hence is sort-of hard coded) * LegacyReceiver * TargetLessReceiver * OldReceiver These are all bad names, but fortunately this will be temporary. Assuming the new mechanism proceeds to stabilization as intended, the legacy trait will be removed altogether. Although we expect this trait to be used only in the standard library, we suspect it may be in use elsehwere, so we're landing this change separately to identify any surprising breakages. It's known that this trait is used within the Rust for Linux project; a patch is in progress to remove their dependency. This is a part of the arbitrary self types v2 project, https://github.com/rust-lang/rfcs/pull/3519 https://github.com/rust-lang/rust/issues/44874 r? @wesleywiser
2024-10-22refactor `Arc<T>::default`Slanterns-7/+10
2024-10-22optimize `Rc<T>::default`Slanterns-1/+10
2024-10-21move strict provenance lints to new feature gate, remove old feature gatesRalf Jung-1/+2
2024-10-18Rollup merge of #131809 - collinoc:fix-retain-mut-docs, r=jhpratt许杰友 Jieyou Xu (Joe)-2/+2
Fix predicate signatures in retain_mut docs This is my first PR here so let me know if I'm doing anything wrong. The docs for `retain_mut` in `LinkedList` and `VecDeque` say the predicate takes `&e`, but it should be `&mut e` to match the actual signature. `Vec` [has it documented](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain_mut) correctly already.
2024-10-18Rollup merge of #130136 - GKFX:stabilize-const-pin, r=dtolnay许杰友 Jieyou Xu (Joe)-1/+0
Partially stabilize const_pin Tracking issue #76654. Eight of these methods can be made const-stable. The remainder are blocked on #73255.
2024-10-17Auto merge of #130223 - LaihoE:faster_str_replace, r=thomccbors-2/+30
optimize str.replace Adds a fast path for str.replace for the ascii to ascii case. This allows for autovectorizing the code. Also should this instead be done with specialization? This way we could remove one branch. I think it is the kind of branch that is easy to predict though. Benchmark for the fast path (replace all "a" with "b" in the rust wikipedia article, using criterion) : | N | Speedup | Time New (ns) | Time Old (ns) | |----------|---------|---------------|---------------| | 2 | 2.03 | 13.567 | 27.576 | | 8 | 1.73 | 17.478 | 30.259 | | 11 | 2.46 | 18.296 | 45.055 | | 16 | 2.71 | 17.181 | 46.526 | | 37 | 4.43 | 18.526 | 81.997 | | 64 | 8.54 | 18.670 | 159.470 | | 200 | 9.82 | 29.634 | 291.010 | | 2000 | 24.34 | 81.114 | 1974.300 | | 20000 | 30.61 | 598.520 | 18318.000 | | 1000000 | 29.31 | 33458.000 | 980540.000 |
2024-10-16Fix predicate signatures in retain_mut docsCollin O'Connor-2/+2
2024-10-16Partially stabilize const_pinGeorge Bateman-1/+0
2024-10-16Auto merge of #131767 - cuviper:bump-stage0, r=Mark-Simulacrumbors-2/+0
Bump bootstrap compiler to 1.83.0-beta.1 https://forge.rust-lang.org/release/process.html#master-bootstrap-update-tuesday
2024-10-16Auto merge of #131460 - jwong101:default-placement-new, r=ibraheemdevbors-2/+9
Optimize `Box::default` and `Arc::default` to construct more types in place Both the `Arc` and `Box` `Default` impls currently call `T::default()` before allocating, and then moving the resulting `T` into the allocation. Most `Default` impls are trivial, which should in theory allow LLVM to construct `T: Default` directly in the `Box` allocation when calling `<Box<T>>::default()`. However, the allocation may fail, which necessitates calling `T`'s destructor if it has one. If the destructor is non-trivial, then LLVM has a hard time proving that it's sound to elide, which makes it construct `T` on the stack first, and then copy it into the allocation. Change both of these impls to allocate first, and then call `T::default` into the uninitialized allocation, so that LLVM doesn't have to prove that it's sound to elide the destructor/initial stack copy. For example, given the following Rust code: ```rust #[derive(Default, Clone)] struct Foo { x: Vec<u8>, z: String, y: Vec<u8>, } #[no_mangle] pub fn src() -> Box<Foo> { Box::default() } ``` <details open> <summary>Before this PR:</summary> ```llvm `@__rust_no_alloc_shim_is_unstable` = external global i8 ; drop_in_place() generated in case the allocation fails ; core::ptr::drop_in_place<playground::Foo> ; Function Attrs: nounwind nonlazybind uwtable define internal fastcc void `@"_ZN4core3ptr36drop_in_place$LT$playground..Foo$GT$17hff376aece491233bE"(ptr` noalias nocapture noundef readonly align 8 dereferenceable(72) %_1) unnamed_addr #0 personality ptr `@rust_eh_personality` { start: %_1.val = load i64, ptr %_1, align 8 %0 = icmp eq i64 %_1.val, 0 br i1 %0, label %bb6, label %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i" "_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i": ; preds = %start %1 = getelementptr inbounds i8, ptr %_1, i64 8 %_1.val6 = load ptr, ptr %1, align 8, !nonnull !3, !noundef !3 tail call void `@__rust_dealloc(ptr` noundef nonnull %_1.val6, i64 noundef %_1.val, i64 noundef 1) #8 br label %bb6 bb6: ; preds = %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i", %start %2 = getelementptr inbounds i8, ptr %_1, i64 24 %.val9 = load i64, ptr %2, align 8 %3 = icmp eq i64 %.val9, 0 br i1 %3, label %bb5, label %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i.i11" "_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i.i11": ; preds = %bb6 %4 = getelementptr inbounds i8, ptr %_1, i64 32 %.val10 = load ptr, ptr %4, align 8, !nonnull !3, !noundef !3 tail call void `@__rust_dealloc(ptr` noundef nonnull %.val10, i64 noundef %.val9, i64 noundef 1) #8 br label %bb5 bb5: ; preds = %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i.i11", %bb6 %5 = getelementptr inbounds i8, ptr %_1, i64 48 %.val4 = load i64, ptr %5, align 8 %6 = icmp eq i64 %.val4, 0 br i1 %6, label %"_ZN4core3ptr46drop_in_place$LT$alloc..vec..Vec$LT$u8$GT$$GT$17hb5ca95423e113cf7E.exit16", label %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i15" "_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i15": ; preds = %bb5 %7 = getelementptr inbounds i8, ptr %_1, i64 56 %.val5 = load ptr, ptr %7, align 8, !nonnull !3, !noundef !3 tail call void `@__rust_dealloc(ptr` noundef nonnull %.val5, i64 noundef %.val4, i64 noundef 1) #8 br label %"_ZN4core3ptr46drop_in_place$LT$alloc..vec..Vec$LT$u8$GT$$GT$17hb5ca95423e113cf7E.exit16" "_ZN4core3ptr46drop_in_place$LT$alloc..vec..Vec$LT$u8$GT$$GT$17hb5ca95423e113cf7E.exit16": ; preds = %bb5, %"_ZN63_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$10deallocate17heaa87468709346b1E.exit.i.i.i4.i15" ret void } ; Function Attrs: nonlazybind uwtable define noalias noundef nonnull align 8 ptr `@src()` unnamed_addr #1 personality ptr `@rust_eh_personality` { start: ; alloca to place `Foo` in. %_1 = alloca [72 x i8], align 8 call void `@llvm.lifetime.start.p0(i64` 72, ptr nonnull %_1) store i64 0, ptr %_1, align 8 %_2.sroa.4.0._1.sroa_idx = getelementptr inbounds i8, ptr %_1, i64 8 store ptr inttoptr (i64 1 to ptr), ptr %_2.sroa.4.0._1.sroa_idx, align 8 %_2.sroa.5.0._1.sroa_idx = getelementptr inbounds i8, ptr %_1, i64 16 %_3.sroa.4.0..sroa_idx = getelementptr inbounds i8, ptr %_1, i64 32 call void `@llvm.memset.p0.i64(ptr` noundef nonnull align 8 dereferenceable(16) %_2.sroa.5.0._1.sroa_idx, i8 0, i64 16, i1 false) store ptr inttoptr (i64 1 to ptr), ptr %_3.sroa.4.0..sroa_idx, align 8 %_3.sroa.5.0..sroa_idx = getelementptr inbounds i8, ptr %_1, i64 40 %_4.sroa.4.0..sroa_idx = getelementptr inbounds i8, ptr %_1, i64 56 call void `@llvm.memset.p0.i64(ptr` noundef nonnull align 8 dereferenceable(16) %_3.sroa.5.0..sroa_idx, i8 0, i64 16, i1 false) store ptr inttoptr (i64 1 to ptr), ptr %_4.sroa.4.0..sroa_idx, align 8 %_4.sroa.5.0..sroa_idx = getelementptr inbounds i8, ptr %_1, i64 64 store i64 0, ptr %_4.sroa.5.0..sroa_idx, align 8 %0 = load volatile i8, ptr `@__rust_no_alloc_shim_is_unstable,` align 1, !noalias !4 %_0.i.i.i = tail call noalias noundef align 8 dereferenceable_or_null(72) ptr `@__rust_alloc(i64` noundef 72, i64 noundef 8) #8, !noalias !4 %1 = icmp eq ptr %_0.i.i.i, null br i1 %1, label %bb2.i, label %"_ZN5alloc5boxed12Box$LT$T$GT$3new17h0864de14f863a27aE.exit" bb2.i: ; preds = %start ; invoke alloc::alloc::handle_alloc_error invoke void `@_ZN5alloc5alloc18handle_alloc_error17h98142d0d8d74161bE(i64` noundef 8, i64 noundef 72) #9 to label %.noexc unwind label %cleanup.i .noexc: ; preds = %bb2.i unreachable cleanup.i: ; preds = %bb2.i %2 = landingpad { ptr, i32 } cleanup ; call core::ptr::drop_in_place<playground::Foo> call fastcc void `@"_ZN4core3ptr36drop_in_place$LT$playground..Foo$GT$17hff376aece491233bE"(ptr` noalias noundef nonnull align 8 dereferenceable(72) %_1) #10 resume { ptr, i32 } %2 "_ZN5alloc5boxed12Box$LT$T$GT$3new17h0864de14f863a27aE.exit": ; preds = %start ; Copy from stack to heap if allocation is successful call void `@llvm.memcpy.p0.p0.i64(ptr` noundef nonnull align 8 dereferenceable(72) %_0.i.i.i, ptr noundef nonnull align 8 dereferenceable(72) %_1, i64 72, i1 false) call void `@llvm.lifetime.end.p0(i64` 72, ptr nonnull %_1) ret ptr %_0.i.i.i } ``` </details> <details> <summary>After this PR</summary> ```llvm ; Notice how there's no `drop_in_place()` generated as well define noalias noundef nonnull align 8 ptr `@src()` unnamed_addr #0 personality ptr `@rust_eh_personality` { start: ; no stack allocation %0 = load volatile i8, ptr `@__rust_no_alloc_shim_is_unstable,` align 1 %_0.i.i.i.i.i = tail call noalias noundef align 8 dereferenceable_or_null(72) ptr `@__rust_alloc(i64` noundef 72, i64 noundef 8) #5 %1 = icmp eq ptr %_0.i.i.i.i.i, null br i1 %1, label %bb3.i, label %"_ZN5alloc5boxed16Box$LT$T$C$A$GT$13new_uninit_in17h80d6355ef4b73ea3E.exit" bb3.i: ; preds = %start ; call alloc::alloc::handle_alloc_error tail call void `@_ZN5alloc5alloc18handle_alloc_error17h98142d0d8d74161bE(i64` noundef 8, i64 noundef 72) #6 unreachable "_ZN5alloc5boxed16Box$LT$T$C$A$GT$13new_uninit_in17h80d6355ef4b73ea3E.exit": ; preds = %start ; construct `Foo` directly into the allocation if successful store i64 0, ptr %_0.i.i.i.i.i, align 8 %_8.sroa.4.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 8 store ptr inttoptr (i64 1 to ptr), ptr %_8.sroa.4.0._1.sroa_idx, align 8 %_8.sroa.5.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 16 %_8.sroa.7.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 32 tail call void `@llvm.memset.p0.i64(ptr` noundef nonnull align 8 dereferenceable(16) %_8.sroa.5.0._1.sroa_idx, i8 0, i64 16, i1 false) store ptr inttoptr (i64 1 to ptr), ptr %_8.sroa.7.0._1.sroa_idx, align 8 %_8.sroa.8.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 40 %_8.sroa.10.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 56 tail call void `@llvm.memset.p0.i64(ptr` noundef nonnull align 8 dereferenceable(16) %_8.sroa.8.0._1.sroa_idx, i8 0, i64 16, i1 false) store ptr inttoptr (i64 1 to ptr), ptr %_8.sroa.10.0._1.sroa_idx, align 8 %_8.sroa.11.0._1.sroa_idx = getelementptr inbounds i8, ptr %_0.i.i.i.i.i, i64 64 store i64 0, ptr %_8.sroa.11.0._1.sroa_idx, align 8 ret ptr %_0.i.i.i.i.i } ``` </details>
2024-10-15update bootstrap configsJosh Stone-2/+0
2024-10-15Rollup merge of #131521 - jdonszelmann:rc, r=joboetMichael Goulet-83/+87
rename RcBox to RcInner for consistency Arc uses ArcInner too (created in collaboration with `@aDotInTheVoid` and `@WaffleLapkin` )
2024-10-15Rollup merge of #130608 - YohDeadfall:cstr-from-into-str, r=workingjubileeMatthias Krüger-1/+25
Implemented `FromStr` for `CString` and `TryFrom<CString>` for `String` The motivation of this change is making it possible to use `CString` in generic methods with `FromStr` and `TryInto<String>` trait bounds. The same traits are already implemented for `OsString` which is an FFI type too.
2024-10-14Auto merge of #126557 - GrigorenkoPV:vec_track_caller, r=joboetbors-0/+105
Add `#[track_caller]` to allocating methods of `Vec` & `VecDeque` Part 4 in a lengthy saga. r? `@joshtriplett` because they were the reviewer the last 3 times. `@bors` rollup=never "[just in case this has perf effects, Vec is hot](https://github.com/rust-lang/rust/pull/79323#issuecomment-731866746)" This was first attempted in #79323 by `@nvzqz.` It got approval from `@joshtriplett,` but rotted with merge conflicts and got closed. Then it got picked up by `@Dylan-DPC-zz` in #83359. A benchmark was run[^perf], the results (after a bit of thinking[^thinking]) were deemed ok[^ok], but there was a typo[^typo] and the PR was made from a wrong remote in the first place[^remote], so #83909 was opened instead. By the time #83909 rolled around, the methods in question had received some optimizations[^optimizations], so another perf run was conducted[^perf2]. The results were ok[^ok2]. There was a suggestion to add regression tests for panic behavior [^tests], but before it could be addressed, the PR fell victim to merge conflicts[^conflicts] and died again[^rip]. 3 years have passed, and (from what I can tell) this has not been tried again, so here I am now, reviving this old effort. Given how much time has passed and the fact that I've also touched `VecDeque` this time, it probably makes sense to `@bors` try `@rust-timer` [^perf]: https://github.com/rust-lang/rust/pull/83359#issuecomment-804450095 [^thinking]: https://github.com/rust-lang/rust/pull/83359#issuecomment-805286704 [^ok]: https://github.com/rust-lang/rust/pull/83359#issuecomment-812739031 [^typo]: https://github.com/rust-lang/rust/pull/83359#issuecomment-812750205 [^remote]: https://github.com/rust-lang/rust/pull/83359#issuecomment-814067119 [^optimizations]: https://github.com/rust-lang/rust/pull/83909#issuecomment-813736593 [^perf2]: https://github.com/rust-lang/rust/pull/83909#issuecomment-813825552 [^ok2]: https://github.com/rust-lang/rust/pull/83909#issuecomment-813831341 [^tests]: https://github.com/rust-lang/rust/pull/83909#issuecomment-825788964 [^conflicts]: https://github.com/rust-lang/rust/pull/83909#issuecomment-851173480 [^rip]: https://github.com/rust-lang/rust/pull/83909#issuecomment-873569771
2024-10-13rename rcbox in other places as per review commentsJonathan Dönszelmann-14/+14
2024-10-12Rollup merge of #131120 - tgross35:stabilize-const_option, r=RalfJungTrevor Gross-1/+0
Stabilize `const_option` This makes the following API stable in const contexts: ```rust impl<T> Option<T> { pub const fn as_mut(&mut self) -> Option<&mut T>; pub const fn expect(self, msg: &str) -> T; pub const fn unwrap(self) -> T; pub const unsafe fn unwrap_unchecked(self) -> T; pub const fn take(&mut self) -> Option<T>; pub const fn replace(&mut self, value: T) -> Option<T>; } impl<T> Option<&T> { pub const fn copied(self) -> Option<T> where T: Copy; } impl<T> Option<&mut T> { pub const fn copied(self) -> Option<T> where T: Copy; } impl<T, E> Option<Result<T, E>> { pub const fn transpose(self) -> Result<Option<T>, E> } impl<T> Option<Option<T>> { pub const fn flatten(self) -> Option<T>; } ``` The following functions make use of the unstable `const_precise_live_drops` feature: - `expect` - `unwrap` - `unwrap_unchecked` - `transpose` - `flatten` Fixes: <https://github.com/rust-lang/rust/issues/67441>
2024-10-12Stabilize `const_option`Trevor Gross-1/+0
This makes the following API stable in const contexts: impl<T> Option<T> { pub const fn as_mut(&mut self) -> Option<&mut T>; pub const fn expect(self, msg: &str) -> T; pub const fn unwrap(self) -> T; pub const unsafe fn unwrap_unchecked(self) -> T; pub const fn take(&mut self) -> Option<T>; pub const fn replace(&mut self, value: T) -> Option<T>; } impl<T> Option<&T> { pub const fn copied(self) -> Option<T> where T: Copy; } impl<T> Option<&mut T> { pub const fn copied(self) -> Option<T> where T: Copy; } impl<T, E> Option<Result<T, E>> { pub const fn transpose(self) -> Result<Option<T>, E> } impl<T> Option<Option<T>> { pub const fn flatten(self) -> Option<T>; } The following functions make use of the unstable `const_precise_live_drops` feature: - `expect` - `unwrap` - `unwrap_unchecked` - `transpose` - `flatten` Fixes: <https://github.com/rust-lang/rust/issues/67441>
2024-10-12Rollup merge of #131617 - RalfJung:const_cow_is_borrowed, r=tgross35Matthias Krüger-3/+0
remove const_cow_is_borrowed feature gate The two functions guarded by this are still unstable, and there's no reason to require a separate feature gate for their const-ness -- we can just have `cow_is_borrowed` cover both kinds of stability. Cc #65143
2024-10-12remove const_cow_is_borrowed feature gateRalf Jung-3/+0
2024-10-12library: Stabilize `const_ptr_write`Jubilee Young-1/+0
Const-stabilizes: - `write` - `write_bytes` - `write_unaligned` In the following paths: - `core::ptr` - `core::ptr::NonNull` - pointer `<*mut T>` Const-stabilizes the internal `core::intrinsics`: - `write_bytes` - `write_via_move`
2024-10-11Rollup merge of #131065 - Voultapher:port-sort-test-suite, r=thomccTrevor Gross-383/+10
Port sort-research-rs test suite to Rust stdlib tests This PR is a followup to https://github.com/rust-lang/rust/pull/124032. It replaces the tests that test the various sort functions in the standard library with a test-suite developed as part of https://github.com/Voultapher/sort-research-rs. The current tests suffer a couple of problems: - They don't cover important real world patterns that the implementations take advantage of and execute special code for. - The input lengths tested miss out on code paths. For example, important safety property tests never reach the quicksort part of the implementation. - The miri side is often limited to `len <= 20` which means it very thoroughly tests the insertion sort, which accounts for 19 out of 1.5k LoC. - They are split into to core and alloc, causing code duplication and uneven coverage. - ~~The randomness is tied to a caller location, wasting the space exploration capabilities of randomized testing.~~ The randomness is not repeatable, as it relies on `std::hash::RandomState::new().build_hasher()`. Most of these issues existed before https://github.com/rust-lang/rust/pull/124032, but they are intensified by it. One thing that is new and requires additional testing, is that the new sort implementations specialize based on type properties. For example `Freeze` and non `Freeze` execute different code paths. Effectively there are three dimensions that matter: - Input type - Input length - Input pattern The ported test-suite tests various properties along all three dimensions, greatly improving test coverage. It side-steps the miri issue by preferring sampled approaches. For example the test that checks if after a panic the set of elements is still the original one, doesn't do so for every single possible panic opportunity but rather it picks one at random, and performs this test across a range of input length, which varies the panic point across them. This allows regular execution to easily test inputs of length 10k, and miri execution up to 100 which covers significantly more code. The randomness used is tied to a fixed - but random per process execution - seed. This allows for fully repeatable tests and fuzzer like exploration across multiple runs. Structure wise, the tests are previously found in the core integration tests for `sort_unstable` and alloc unit tests for `sort`. The new test-suite was developed to be a purely black-box approach, which makes integration testing the better place, because it can't accidentally rely on internal access. Because unwinding support is required the tests can't be in core, even if the implementation is, so they are now part of the alloc integration tests. Are there architectures that can only build and test core and not alloc? If so, do such platforms require sort testing? For what it's worth the current implementation state passes miri `--target mips64-unknown-linux-gnuabi64` which is big endian. The test-suite also contains tests for properties that were and are given by the current and previous implementations, and likely relied upon by users but weren't tested. For example `self_cmp` tests that the two parameters `a` and `b` passed into the comparison function are never references to the same object, which if the user is sorting for example a `&mut [Mutex<i32>]` could lead to a deadlock. Instead of using the hashed caller location as rand seed, it uses seconds since unix epoch / 10, which given timestamps in the CI should be reasonably easy to reproduce, but also allows fuzzer like space exploration. --- Test run-time changes: Setup: ``` Linux 6.10 rustc 1.83.0-nightly (f79a912d9 2024-09-18) AMD Ryzen 9 5900X 12-Core Processor (Zen 3 micro-architecture) CPU boost enabled. ``` master: e9df22f Before core integration tests: ``` $ LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/coretests-219cbd0308a49e2f Time (mean ± σ): 869.6 ms ± 21.1 ms [User: 1327.6 ms, System: 95.1 ms] Range (min … max): 845.4 ms … 917.0 ms 10 runs # MIRIFLAGS="-Zmiri-disable-isolation" to get real time $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/core finished in 738.44s ``` After core integration tests: ``` $ LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/coretests-219cbd0308a49e2f Time (mean ± σ): 865.1 ms ± 14.7 ms [User: 1283.5 ms, System: 88.4 ms] Range (min … max): 836.2 ms … 885.7 ms 10 runs $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/core finished in 752.35s ``` Before alloc unit tests: ``` LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/alloc-19c15e6e8565aa54 Time (mean ± σ): 295.0 ms ± 9.9 ms [User: 719.6 ms, System: 35.3 ms] Range (min … max): 284.9 ms … 319.3 ms 10 runs $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/alloc finished in 322.75s ``` After alloc unit tests: ``` LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/alloc-19c15e6e8565aa54 Time (mean ± σ): 97.4 ms ± 4.1 ms [User: 297.7 ms, System: 28.6 ms] Range (min … max): 92.3 ms … 109.2 ms 27 runs $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/alloc finished in 309.18s ``` Before alloc integration tests: ``` $ LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/alloctests-439e7300c61a8046 Time (mean ± σ): 103.2 ms ± 1.7 ms [User: 135.7 ms, System: 39.4 ms] Range (min … max): 99.7 ms … 107.3 ms 28 runs $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/alloc finished in 231.35s ``` After alloc integration tests: ``` $ LD_LIBRARY_PATH=build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/ hyperfine build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/alloctests-439e7300c61a8046 Time (mean ± σ): 379.8 ms ± 4.7 ms [User: 4620.5 ms, System: 1157.2 ms] Range (min … max): 373.6 ms … 386.9 ms 10 runs $ MIRIFLAGS="-Zmiri-disable-isolation" ./x.py miri library/alloc finished in 449.24s ``` In my opinion the results don't change iterative library development or CI execution in meaningful ways. For example currently the library doc-tests take ~66s and incremental compilation takes 10+ seconds. However I only have limited knowledge of the various local development workflows that exist, and might be missing one that is significantly impacted by this change.
2024-10-11rename RcBox in other places tooJonathan Dönszelmann-4/+4
2024-10-11rename RcBox to RcInner for consistencyJonathan Dönszelmann-67/+71
2024-10-10allocate before calling T::default in <Arc<T>>::default()Joshua Wong-1/+8
Same rationale as in the previous commit.
2024-10-10allocate before calling T::default in <Box<T>>::default()Joshua Wong-1/+1
The `Box<T: Default>` impl currently calls `T::default()` before allocating the `Box`. Most `Default` impls are trivial, which should in theory allow LLVM to construct `T: Default` directly in the `Box` allocation when calling `<Box<T>>::default()`. However, the allocation may fail, which necessitates calling `T's` destructor if it has one. If the destructor is non-trivial, then LLVM has a hard time proving that it's sound to elide, which makes it construct `T` on the stack first, and then copy it into the allocation. Create an uninit `Box` first, and then write `T::default` into it, so that LLVM now only needs to prove that the `T::default` can't panic, which should be trivial for most `Default` impls.
2024-10-07Rollup merge of #128399 - mammothbane:master, r=Amanieu,tgross35Stuart Cook-30/+76
liballoc: introduce String, Vec const-slicing This change `const`-qualifies many methods on `Vec` and `String`, notably `as_slice`, `as_str`, `len`. These changes are made behind the unstable feature flag `const_vec_string_slice`. ## Motivation This is to support simultaneous variance over ownership and constness. I have an enum type that may contain either `String` or `&str`, and I want to produce a `&str` from it in a possibly-`const` context. ```rust enum StrOrString<'s> { Str(&'s str), String(String), } impl<'s> StrOrString<'s> { const fn as_str(&self) -> &str { match self { // In a const-context, I really only expect to see this variant, but I can't switch the implementation // in some mode like #[cfg(const)] -- there has to be a single body Self::Str(s) => s, // so this is a problem, since it's not `const` Self::String(s) => s.as_str(), } } } ``` Currently `String` and `Vec` don't support this, but can without functional changes. Similar logic applies for `len`, `capacity`, `is_empty`. ## Changes The essential thing enabling this change is that `Unique::as_ptr` is `const`. This lets us convert `RawVec::ptr` -> `Vec::as_ptr` -> `Vec::as_slice` -> `String::as_str`. I had to move the `Deref` implementations into `as_{str,slice}` because `Deref` isn't `#[const_trait]`, but I would expect this change to be invisible up to inlining. I moved the `DerefMut` implementations as well for uniformity.
2024-10-06liballoc: introduce String, Vec const-slicingNathan Perry-30/+76
This change `const`-qualifies many methods on Vec and String, notably `as_slice`, `as_str`, `len`. These changes are made behind the unstable feature flag `const_vec_string_slice` with the following tracking issue: https://github.com/rust-lang/rust/issues/129041
2024-10-03Avoid emptiness check in `PeekMut::pop`EFanZh-1/+4