vec::Splice can invalidate the slice::Iter inside vec::Drain.
So we replace them with dangling pointers which, unlike ones to
deallocated memory, are allowed.
Leak amplification for peek_mut() to ensure BinaryHeap's invariant is always met
In the libs-api team's discussion around #104210, some of the team had hesitations around exposing malformed BinaryHeaps of an element type whose Ord and Drop impls are trusted, and which does not contain interior mutability.
For example in the context of this kind of code:
```rust
use std::collections::BinaryHeap;
use std::ops::Range;
use std::slice;
fn main() {
let slice = &mut ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let cut_points = BinaryHeap::from(vec![4, 2, 7]);
println!("{:?}", chop(slice, cut_points));
}
// This is a souped up slice::split_at_mut to split in arbitrary many places.
//
// usize's Ord impl is trusted, so 1 single bounds check guarantees all those
// output slices are non-overlapping and in-bounds
fn chop<T>(slice: &mut [T], mut cut_points: BinaryHeap<usize>) -> Vec<&mut [T]> {
let mut vec = Vec::with_capacity(cut_points.len() + 1);
let max = match cut_points.pop() {
Some(max) => max,
None => {
vec.push(slice);
return vec;
}
};
assert!(max <= slice.len());
let len = slice.len();
let ptr: *mut T = slice.as_mut_ptr();
let get_unchecked_mut = unsafe {
|range: Range<usize>| &mut *slice::from_raw_parts_mut(ptr.add(range.start), range.len())
};
vec.push(get_unchecked_mut(max..len));
let mut end = max;
while let Some(start) = cut_points.pop() {
vec.push(get_unchecked_mut(start..end));
end = start;
}
vec.push(get_unchecked_mut(0..end));
vec
}
```
```console
[['7', '8', '9'], ['4', '5', '6'], ['2', '3'], ['0', '1']]
```
In the current BinaryHeap API, `peek_mut()` is the only thing that makes the above function unsound.
```rust
let slice = &mut ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let mut cut_points = BinaryHeap::from(vec![4, 2, 7]);
{
let mut max = cut_points.peek_mut().unwrap();
*max = 0;
std::mem::forget(max);
}
println!("{:?}", chop(slice, cut_points));
```
```console
[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], [], ['2', '3'], ['0', '1']]
```
Or worse:
```rust
let slice = &mut ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let mut cut_points = BinaryHeap::from(vec![100, 100]);
{
let mut max = cut_points.peek_mut().unwrap();
*max = 0;
std::mem::forget(max);
}
println!("{:?}", chop(slice, cut_points));
```
```console
[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], [], ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\u{1}', '\0', '?', '翾', '?', '翾', '\0', '\0', '?', '翾', '?', '翾', '?', '啿', '?', '啿', '?', '啿', '?', '啿', '?', '啿', '?', '翾', '\0', '\0', '', '啿', '\u{5}', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\u{8}', '\0', '`@',` '\0', '\u{1}', '\0', '?', '翾', '?', '翾', '?', '翾', '
thread 'main' panicked at 'index out of bounds: the len is 33 but the index is 33', library/core/src/unicode/unicode_data.rs:319:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
---
This PR makes `peek_mut()` use leak amplification (https://doc.rust-lang.org/1.66.0/nomicon/leaking.html#drain) to preserve the heap's invariant even in the situation that `PeekMut` gets leaked.
I'll also follow up in the tracking issue of unstable `drain_sorted()` (#59278) and `retain()` (#71503).
mv binary_heap.rs binary_heap/mod.rs
I confess this request is somewhat selfish, as it's made in order to ease synchronisation with my [copse](https://crates.io/crates/copse) crate (see eggyal/copse#6 for explanation). I wholly understand that such grounds may be insufficient to justify merging this request—but no harm in asking, right?
Document that `Vec::from_raw_parts[_in]` must be given a pointer from the correct allocator.
Currently, the documentation of `Vec::from_raw_parts` and `Vec::from_raw_parts_in` says nothing about what allocator the pointer must come from. This PR adds that missing information explicitly.
Loosen the bound on the Debug implementation of Weak.
Both `rc::Weak<T>` and `sync::Weak<T>` currently require `T: Debug` in their own `Debug` implementations, but they don't currently use it; they only ever print a fixed string.
A general implementation of Debug for Weak that actually attempts to upgrade and rely on the contents is unlikely in the future because it may have unbounded recursion in the presence of reference cycles, which Weak is commonly used in. (This was the justification for why the current implementation [was implemented the way it is](f0976e2cf3)).
When I brought it up [on the forum](https://internals.rust-lang.org/t/could-the-bound-on-weak-debug-be-relaxed/15504), it was suggested that, even if an implementation is specialized in the future that relies on the data stored within the Weak, it would likely rely on specialization anyway, and could therefore easily specialize on the Debug bound as well.
Update `rand` in the stdlib tests, and remove the `getrandom` feature from it.
The main goal is actually removing `getrandom`, so that eventually we can allow running the stdlib test suite on tier3 targets which don't have `getrandom` support. Currently those targets can only run the subset of stdlib tests that exist in uitests, and (generally speaking), we prefer not to test libstd functionality in uitests, which came up recently in https://github.com/rust-lang/rust/pull/104095 and https://github.com/rust-lang/rust/pull/104185. Additionally, the fact that we can't update `rand`/`getrandom` means we're stuck with the old set of tier3 targets, so can't test new ones.
~~Anyway, I haven't checked that this actually does allow use on tier3 targets (I think it does not, as some work is needed in stdlib submodules) but it moves us slightly closer to this, and seems to allow at least finally updating our `rand` dep, which definitely improves the status quo.~~ Checked and works now.
For the most part, our tests and benchmarks are fine using hard-coded seeds. A couple tests seem to fail with this (stuff manipulating the environment expecting no collisions, for example), or become pointless (all inputs to a function become equivalent). In these cases I've done a (gross) dance (ab)using `RandomState` and `Location::caller()` for some extra "entropy".
Trying to share that code seems *way* more painful than it's worth given that the duplication is a 7-line function, even if the lines are quite gross. (Keeping in mind that sharing it would require adding `rand` as a non-dev dep to std, and exposing a type from it publicly, all of which sounds truly awful, even if done behind a perma-unstable feature).
See also some previous attempts:
- https://github.com/rust-lang/rust/pull/86963 (in particular https://github.com/rust-lang/rust/pull/86963#issuecomment-885438936 which explains why this is non-trivial)
- https://github.com/rust-lang/rust/pull/89131
- https://github.com/rust-lang/rust/pull/96626#issuecomment-1114562857 (I tried in that PR at the same time, but settled for just removing the usage of `thread_rng()` from the benchmarks, since that was the main goal).
- https://github.com/rust-lang/rust/pull/104185
- Probably more. It's very tempting of a thing to "just update".
r? `@Mark-Simulacrum`
default OOM handler: use non-unwinding panic, to match std handler
The OOM handler in std will by default abort. This adjusts the default in liballoc to do the same, using the `can_unwind` flag on the panic info to indicate a non-unwinding panic.
In practice this probably makes little difference since the liballoc default will only come into play in no-std situations where people write a custom panic handler, which most likely will not implement unwinding. But still, this seems more consistent.
Cc `@rust-lang/wg-allocators,` https://github.com/rust-lang/rust/issues/66741
Revert "Implement allow-by-default `multiple_supertrait_upcastable` lint"
This is a clean revert of #105484.
I confirmed that reverting that PR fixes the regression reported in #106247. ~~I can't say I understand what this code is doing, but maybe it can be re-landed with a different implementation.~~ **Edit:** https://github.com/rust-lang/rust/issues/106247#issuecomment-1367174384 has an explanation of why #105484 ends up surfacing spurious `where_clause_object_safety` errors. The implementation of `where_clause_object_safety` assumes we only check whether a trait is object safe when somebody actually uses that trait with `dyn`. However the implementation of `multiple_supertrait_upcastable` added in the problematic PR involves checking *every* trait for whether it is object-safe.
FYI `@nbdd0121` `@compiler-errors`
Implement allow-by-default `multiple_supertrait_upcastable` lint
The lint detects when an object-safe trait has multiple supertraits.
Enabled in libcore and liballoc as they are low-level enough that many embedded programs will use them.
r? `@nikomatsakis`
Test leaking of BinaryHeap Drain iterators
Add test cases about forgetting the `BinaryHeap::Drain` iterator, and slightly fortifies some other test cases.
Consists of separate commits that I don't think are relevant on their own (but I'll happily turn these into more PRs if desired).
The lint "clippy::uninlined_format_args" recommends inline
variables in format strings. Fix two places in the docs that do
not do this. I noticed this because I copy/pasted one example in
to my project, then noticed this lint error. This fixes:
error: variables can be used directly in the `format!` string
--> src/main.rs:30:22
|
30 | let string = format!("{:.*}", decimals, magnitude);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: variables can be used directly in the `format!` string
--> src/main.rs:39:2
|
39 | write!(&mut io::stdout(), "{}", args).unwrap();
Send `VecDeque::from_iter` via `Vec::from_iter`
Since it's O(1) to convert between them now, might as well reuse the logic.
Mostly for the various specializations it does, but might also save some monomorphization work if, say, people collect slice iterators into both `Vec`s and `VecDeque`s.
improve doc of into_boxed_slice and impl From<Vec<T>> for Box<[T]>
Improves description of `into_boxed_slice`, and adds example to `impl From<Vec<T>> for Box<[T]>`.
Fixes#98908
Since it's O(1) to convert between them now, might as well reuse the logic.
Mostly for the various specializations it does, but might also save some monomorphization work if, say, people collect slice iterators into both `Vec`s and `VecDeque`s.
Update VecDeque implementation to use head+len instead of head+tail
(See #99805)
This changes `alloc::collections::VecDeque`'s internal representation from using head and tail indices to using a head index and a length field. It has a few advantages over the current design:
* It allows the buffer to be of length 0, which means the `VecDeque::new` new longer has to allocate and could be changed to a `const fn`
* It allows the `VecDeque` to fill the buffer completely, unlike the old implementation, which always had to leave a free space
* It removes the restriction for the size to be a power of two, allowing it to properly `shrink_to_fit`, unlike the old `VecDeque`
* The above points also combine to allow the `Vec<T> -> VecDeque<T>` conversion to be very cheap and guaranteed O(1). I mention this in the `From<Vec<T>>` impl, but it's not a strong guarantee just yet, as that would likely need some form of API change proposal.
All the tests seem to pass for the new `VecDeque`, with some slight adjustments.
r? `@scottmcm`
Stop peeling the last iteration of the loop in `Vec::resize_with`
`resize_with` uses the `ExtendWith` code that peels the last iteration:
341d8b8a2c/library/alloc/src/vec/mod.rs (L2525-L2529)
But that's kinda weird for `ExtendFunc` because it does the same thing on the last iteration anyway:
341d8b8a2c/library/alloc/src/vec/mod.rs (L2494-L2502)
So this just has it use the normal `extend`-from-`TrustedLen` code instead.
r? `@ghost`
Clarify and restrict when `{Arc,Rc}::get_unchecked_mut` is allowed.
(Tracking issue for `{Arc,Rc}::get_unchecked_mut`: #63292)
(I'm using `Rc` in this comment, but it applies for `Arc` all the same).
As currently documented, `Rc::get_unchecked_mut` can lead to unsoundness when multiple `Rc`/`Weak` pointers to the same allocation exist. The current documentation only requires that other `Rc`/`Weak` pointers to the same allocation "must not be dereferenced for the duration of the returned borrow". This can lead to unsoundness in (at least) two ways: variance, and `Rc<str>`/`Rc<[u8]>` aliasing. ([playground link](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d7e2d091c389f463d121630ab0a37320)).
This PR changes the documentation of `Rc::get_unchecked_mut` to restrict usage to when all `Rc<T>`/`Weak<T>` have the exact same `T` (including lifetimes). I believe this is sufficient to prevent unsoundness, while still allowing `get_unchecked_mut` to be called on an aliased `Rc` as long as the safety contract is upheld by the caller.
## Alternatives
* A less strict, but still sound alternative would be to say that the caller must only write values which are valid for all aliased `Rc`/`Weak` inner types. (This was [mentioned](https://github.com/rust-lang/rust/issues/63292#issuecomment-568284090) in the tracking issue). This may be too complicated to clearly express in the documentation.
* A more strict alternative would be to say that there must not be any aliased `Rc`/`Weak` pointers, i.e. it is required that get_mut would return `Some(_)`. (This was also mentioned in the tracking issue). There is at least one codebase that this would cause to become unsound ([here](be5a164d77/src/memtable.rs (L166)), where additional locking is used to ensure unique access to an aliased `Rc<T>`; I saw this because it was linked on the tracking issue).
This moves the stable sort implementation to the core::slice::sort module. By
virtue of being in core it can't access `Vec`. The two `Vec` used by merge sort,
`buf` and `runs`, are modelled as custom types that implement the very limited
required `Vec` interface with the help of provided allocation and free
functions. This is done to allow future re-use of functions and logic between
stable and unstable sort. Such as `insert_head`.
`VecDeque::resize` should re-use the buffer in the passed-in element
Today it always copies it for *every* appended element, but one of those clones is avoidable.
This adds `iter::repeat_n` (https://github.com/rust-lang/rust/issues/104434) as the primitive needed to do this. If this PR is acceptable, I'll also use this in `Vec` rather than its custom `ExtendElement` type & infrastructure that is harder to share between multiple different containers:
101e1822c3/library/alloc/src/vec/mod.rs (L2479-L2492)
Attempt to reuse `Vec<T>` backing storage for `Rc/Arc<[T]>`
If a `Vec<T>` has sufficient capacity to store the inner `RcBox<[T]>`, we can just reuse the existing allocation and shift the elements up, instead of making a new allocation.
run alloc benchmarks in Miri and fix UB
Miri since recently has a "fake monotonic clock" that works even with isolation. Its measurements are not very meaningful but it means we can run these benches and check them for UB.
And that's a good thing since there was UB here: fixes https://github.com/rust-lang/rust/issues/104096.
r? ``@thomcc``
disable btree size tests on Miri
Seems fine not to run these in Miri, they can't have UB anyway. And this lets us do layout randomization in Miri.
r? ``@thomcc``
The new implementation doesn't use weak lang items and instead changes
`#[alloc_error_handler]` to an attribute macro just like
`#[global_allocator]`.
The attribute will generate the `__rg_oom` function which is called by
the compiler-generated `__rust_alloc_error_handler`. If no `__rg_oom`
function is defined in any crate then the compiler shim will call
`__rdl_oom` in the alloc crate which will simply panic.
This also fixes link errors with `-C link-dead-code` with
`default_alloc_error_handler`: `__rg_oom` was previously defined in the
alloc crate and would attempt to reference the `oom` lang item, even if
it didn't exist. This worked as long as `__rg_oom` was excluded from
linking since it was not called.
This is a prerequisite for the stabilization of
`default_alloc_error_handler` (#102318).
Remove redundant lifetime bound from `impl Borrow for Cow`
The lifetime bound `B::Owned: 'a` is redundant and doesn't make a difference,
because `Cow<'a, B>` comes with an implicit `B: 'a`, and associated types
will outlive lifetimes outlived by the `Self` type (and all the trait's
generic parameters, of which there are none in this case), so the implicit `B: 'a`
implies `B::Owned: 'a` anyway.
The explicit lifetime bound here does however [end up in documentation](https://doc.rust-lang.org/std/borrow/enum.Cow.html#impl-Borrow%3CB%3E),
and that's confusing in my opinion, so let's remove it ^^
_(Documentation right now, compare to `AsRef`, too:)_
![Screenshot_20220722_014055](https://user-images.githubusercontent.com/3986214/180332665-424d0c05-afb3-40d8-a330-a57a2c9a494b.png)
Adjust argument type for mutable with_metadata_of (#75091)
The method takes two pointer arguments: one `self` supplying the pointer value, and a second pointer supplying the metadata.
The new parameter type more clearly reflects the actual requirements. The provenance of the metadata parameter is disregarded completely. Using a mutable pointer in the call site can be coerced to a const pointer while the reverse is not true.
In some cases, the current parameter type can thus lead to a very slightly confusing additional cast. [Example](cad93775eb).
```rust
// Manually taking an unsized object from a `ManuallyDrop` into another allocation.
let val: &core::mem::ManuallyDrop<T> = …;
let ptr = val as *const _ as *mut T;
let ptr = uninit.as_ptr().with_metadata_of(ptr);
```
This could then instead be simplified to:
```rust
// Manually taking an unsized object from a `ManuallyDrop` into another allocation.
let val: &core::mem::ManuallyDrop<T> = …;
let ptr = uninit.as_ptr().with_metadata_of(&**val);
```
Tracking issue: https://github.com/rust-lang/rust/issues/75091
``@dtolnay`` you're reviewed #95249, would you mind chiming in?
Remove incorrect comment in `Vec::drain`
r? ``@scottmcm``
Turns out this comment wasn't correct for 6 years, since #34951, which switched from using `slice::IterMut` into using `slice::Iter`.
Add `Box<[T; N]>: TryFrom<Vec<T>>`
We have `[T; N]: TryFrom<Vec<T>>` (#76310) and `Box<[T; N]>: TryFrom<Box<[T]>>`, but not this combination.
`vec.into_boxed_slice().try_into()` isn't quite a replacement for this, as that'll reallocate unnecessarily in the error case.
**Insta-stable, so needs an FCP**
(I tried to make this work with `, A`, but that's disallowed because of `#[fundamental]` https://github.com/rust-lang/rust/issues/29635#issuecomment-1247598385)
Detect and reject out-of-range integers in format string literals
Until now out-of-range integers in format string literals were silently ignored. They wrapped around to zero at usize::MAX, producing unexpected results.
When using debug builds of rustc, such integers in format string literals even cause an 'attempt to add with overflow' panic in rustc.
Fix this by producing an error diagnostic for integers in format string literals which do not fit into usize.
Fixes#102528
add Vec::push_within_capacity - fallible, does not allocate
This method can serve several purposes. It
* is fallible
* guarantees that items in Vec aren't moved
* allows loops that do `reserve` and `push` separately to avoid pulling in the allocation machinery a second time in the `push` part which should make things easier on the optimizer
* eases the path towards `ArrayVec` a bit since - compared to `push()` - there are fewer questions around how it should be implemented
I haven't named it `try_push` because that should probably occupy a middle ground that will still try to reserve and only return an error in the unlikely OOM case.
resolves#84649
Previously "bare\r" was split into ["bare"] even though the
documentation said that only LF and CRLF count as newlines.
This fix is a behavioural change, even though it brings the behaviour
into line with the documentation, and into line with that of
`std::io::BufRead::lines()`.
This is an alternative to #91051, which proposes to document rather
than fix the behaviour.
Fixes#94435.
Co-authored-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Currently pretty much all of the btree_map and btree_set ones fail, as
well as linked_list::DrainFilter.
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:38:5
|
38 | / require_send_sync(async {
39 | | let _v = None::<alloc::collections::btree_map::Iter<'_, &u32, &u32>>;
40 | | async {}.await;
41 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:56:5
|
56 | / require_send_sync(async {
57 | | let _v = None::<
58 | | alloc::collections::btree_map::DrainFilter<
59 | | '_,
... |
65 | | async {}.await;
66 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:68:5
|
68 | / require_send_sync(async {
69 | | let _v = None::<alloc::collections::btree_map::Entry<'_, &u32, &u32>>;
70 | | async {}.await;
71 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:88:5
|
88 | / require_send_sync(async {
89 | | let _v = None::<alloc::collections::btree_map::Iter<'_, &u32, &u32>>;
90 | | async {}.await;
91 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:93:5
|
93 | / require_send_sync(async {
94 | | let _v = None::<alloc::collections::btree_map::IterMut<'_, &u32, &u32>>;
95 | | async {}.await;
96 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:98:5
|
98 | / require_send_sync(async {
99 | | let _v = None::<alloc::collections::btree_map::Keys<'_, &u32, &u32>>;
100 | | async {}.await;
101 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:103:5
|
103 | / require_send_sync(async {
104 | | let _v = None::<alloc::collections::btree_map::OccupiedEntry<'_, &u32, &u32>>;
105 | | async {}.await;
106 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:108:5
|
108 | / require_send_sync(async {
109 | | let _v = None::<alloc::collections::btree_map::OccupiedError<'_, &u32, &u32>>;
110 | | async {}.await;
111 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:113:5
|
113 | / require_send_sync(async {
114 | | let _v = None::<alloc::collections::btree_map::Range<'_, &u32, &u32>>;
115 | | async {}.await;
116 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:118:5
|
118 | / require_send_sync(async {
119 | | let _v = None::<alloc::collections::btree_map::RangeMut<'_, &u32, &u32>>;
120 | | async {}.await;
121 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:123:5
|
123 | / require_send_sync(async {
124 | | let _v = None::<alloc::collections::btree_map::VacantEntry<'_, &u32, &u32>>;
125 | | async {}.await;
126 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:128:5
|
128 | / require_send_sync(async {
129 | | let _v = None::<alloc::collections::btree_map::Values<'_, &u32, &u32>>;
130 | | async {}.await;
131 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:133:5
|
133 | / require_send_sync(async {
134 | | let _v = None::<alloc::collections::btree_map::ValuesMut<'_, &u32, &u32>>;
135 | | async {}.await;
136 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:146:5
|
146 | / require_send_sync(async {
147 | | let _v = None::<alloc::collections::btree_set::Difference<'_, &u32>>;
148 | | async {}.await;
149 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: implementation of `Send` is not general enough
--> library/alloc/tests/autotraits.rs:151:5
|
151 | / require_send_sync(async {
152 | | let _v = None::<alloc::collections::btree_set::DrainFilter<'_, &u32, fn(&&u32) -> bool>>;
153 | | async {}.await;
154 | | });
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Send` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:156:5
|
156 | / require_send_sync(async {
157 | | let _v = None::<alloc::collections::btree_set::Intersection<'_, &u32>>;
158 | | async {}.await;
159 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:166:5
|
166 | / require_send_sync(async {
167 | | let _v = None::<alloc::collections::btree_set::Iter<'_, &u32>>;
168 | | async {}.await;
169 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:171:5
|
171 | / require_send_sync(async {
172 | | let _v = None::<alloc::collections::btree_set::Range<'_, &u32>>;
173 | | async {}.await;
174 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:176:5
|
176 | / require_send_sync(async {
177 | | let _v = None::<alloc::collections::btree_set::SymmetricDifference<'_, &u32>>;
178 | | async {}.await;
179 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: higher-ranked lifetime error
--> library/alloc/tests/autotraits.rs:181:5
|
181 | / require_send_sync(async {
182 | | let _v = None::<alloc::collections::btree_set::Union<'_, &u32>>;
183 | | async {}.await;
184 | | });
| |______^
|
= note: could not prove `impl Future<Output = ()>: Send`
error: future cannot be sent between threads safely
--> library/alloc/tests/autotraits.rs:243:23
|
243 | require_send_sync(async {
| _______________________^
244 | | let _v =
245 | | None::<alloc::collections::linked_list::DrainFilter<'_, &u32, fn(&mut &u32) -> bool>>;
246 | | async {}.await;
247 | | });
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NonNull<std::collections::linked_list::Node<&u32>>`
note: future is not `Send` as this value is used across an await
--> library/alloc/tests/autotraits.rs:246:17
|
244 | let _v =
| -- has type `Option<std::collections::linked_list::DrainFilter<'_, &u32, for<'a, 'b> fn(&'a mut &'b u32) -> bool>>` which is not `Send`
245 | None::<alloc::collections::linked_list::DrainFilter<'_, &u32, fn(&mut &u32) -> bool>>;
246 | async {}.await;
| ^^^^^^ await occurs here, with `_v` maybe used later
247 | });
| - `_v` is later dropped here
note: required by a bound in `require_send_sync`
--> library/alloc/tests/autotraits.rs:3:25
|
3 | fn require_send_sync<T: Send + Sync>(_: T) {}
| ^^^^ required by this bound in `require_send_sync`
error: future cannot be shared between threads safely
--> library/alloc/tests/autotraits.rs:243:23
|
243 | require_send_sync(async {
| _______________________^
244 | | let _v =
245 | | None::<alloc::collections::linked_list::DrainFilter<'_, &u32, fn(&mut &u32) -> bool>>;
246 | | async {}.await;
247 | | });
| |_____^ future created by async block is not `Sync`
|
= help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `NonNull<std::collections::linked_list::Node<&u32>>`
note: future is not `Sync` as this value is used across an await
--> library/alloc/tests/autotraits.rs:246:17
|
244 | let _v =
| -- has type `Option<std::collections::linked_list::DrainFilter<'_, &u32, for<'a, 'b> fn(&'a mut &'b u32) -> bool>>` which is not `Sync`
245 | None::<alloc::collections::linked_list::DrainFilter<'_, &u32, fn(&mut &u32) -> bool>>;
246 | async {}.await;
| ^^^^^^ await occurs here, with `_v` maybe used later
247 | });
| - `_v` is later dropped here
note: required by a bound in `require_send_sync`
--> library/alloc/tests/autotraits.rs:3:32
|
3 | fn require_send_sync<T: Send + Sync>(_: T) {}
| ^^^^ required by this bound in `require_send_sync`
Fix in-place collection leak when remaining element destructor panic
Fixes#101628
cc `@the8472`
I went for the drop guard route, placing it immediately before the `forget_allocation_drop_remaining` call and after the comment, as to signal they are closely related.
I also updated the test to check for the leak, though the only change really needed was removing the leak clean up for miri since now that's no longer leaked.
docs: be less harsh in wording for Vec::from_raw_parts
In particular, be clear that it is sound to specify memory not
originating from a previous `Vec` allocation. That is already suggested
in other parts of the documentation about zero-alloc conversions to Box<[T]>.
Incorporate a constraint from `slice::from_raw_parts` that was missing
but needs to be fulfilled, since a `Vec` can be converted into a slice.
Fixes https://github.com/rust-lang/rust/issues/98780.
Document the conditional existence of `alloc::sync` and `alloc::task`.
`alloc` declares
```rust
#[cfg(target_has_atomic = "ptr")]
pub mod sync;
```
but there is no public documentation of this condition. This PR fixes that, so that users of `alloc` can understand how to make their code compile everywhere `alloc` does, if they are writing a library with impls for `Arc`.
The wording is copied from `std::sync::atomic::AtomicPtr`, with additional advice on how to `#[cfg]` for it.
I feel quite uncertain about whether the paragraph I added to `Arc`'s documentation should actually be there, as it is a distraction for anyone using `std`. On the other hand, maybe more reminders that no_std exists would benefit the ecosystem.
Note: `target_has_atomic` is [stabilized](https://github.com/rust-lang/rust/issues/32976) but [not yet documented in the reference](https://github.com/rust-lang/reference/pull/1171).
Make `feature(const_btree_len)` implied by `feature(const_btree_new)`
...this should fix code that used the old feature that was changed in #102197
cc ```@davidtwco``` it seems like tidy doesn't check `implied_by`, should it?
Until now out-of-range integers in format string literals
were silently ignored. They wrapped around to zero at
usize::MAX, producing unexpected results.
When using debug builds of rustc, such integers in format string
literals even cause an 'attempt to add with overflow' panic in
rustc.
Fix this by producing an error diagnostic for integers in format
string literals which do not fit into usize.
Fixes#102528