Commit graph

234 commits

Author SHA1 Message Date
bors
a0925fba74 Auto merge of #76790 - ssomers:btree_slice_slasher_returns, r=Mark-Simulacrum
BTreeMap: avoid slices even more

Epilogue to #73971: it seems the compiler is unable to realize that creating a slice and `get_unchecked`-ing one element is a simple fetch. So try to spell it out for the only remaining but often invoked case.

Also, the previous code doesn't seem fair game to me, using `get_unchecked` to reach beyond the end of a slice. Although the local function `slice_insert` also does that.

r? `@Mark-Simulacrum`
2020-09-18 05:47:00 +00:00
Tyler Mandry
23a677787e
Rollup merge of #75026 - JulianKnodt:array_windows, r=Amanieu
Add array_windows fn

This mimicks the functionality added by array_chunks, and implements a const-generic form of
`windows`. It makes egregious use of `unsafe`, but by necessity because the array must be
re-interpreted as a slice of arrays, and unlike array_chunks this cannot be done by casting the
original array once, since each time the index is advanced it needs to move one element, not
`N`.

I'm planning on adding more tests, but this should be good enough as a premise for the functionality.
Notably: should there be more functions overwritten for the iterator implementation/in general?

~~I've marked the issue as #74985 as there is no corresponding exact issue for `array_windows`, but it's based of off `array_chunks`.~~

Edit: See Issue #75027 created by @lcnr for tracking issue

~~Do not merge until I add more tests, please.~~

r? @lcnr
2020-09-16 12:24:03 -07:00
kadmin
f240abc1dc Add array window fn
Updated issue to #75027

Update to rm oob access

And hopefully fix docs as well

Fixed naming conflict in test

Fix test which used 1-indexing

Nth starts from 0, woops

Fix a bunch of off by 1 errors

See https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=757b311987e3fae1ca47122969acda5a

Add even more off by 1 errors

And also write `next` and `next_back` in terms of `nth` and `nth_back`.

Run fmt

Fix forgetting to change fn name in test

add nth_back test & document unsafe

Remove as_ref().unwrap()
Documented occurrences of unsafe, noting what invariants are maintained
2020-09-16 14:52:20 +00:00
Ralf Jung
9d0a265b6c
Rollup merge of #76662 - RalfJung:lib-test-miri, r=Mark-Simulacrum
Fix liballoc test suite for Miri

Mostly, fix the regression introduced by https://github.com/rust-lang/rust/pull/75207 that caused slices (i.e., references) to be created to invalid memory or memory that has aliasing pointers that we want to keep valid. @dylni  this changes the type of `check_range` to only require the length, not the full reference to the slice, which indeed is all the information this function requires.

Also reduce the size of a test introduced in https://github.com/rust-lang/rust/pull/70793 to make it not take 3 minutes in Miri.

This makes https://github.com/RalfJung/miri-test-libstd work again.
2020-09-16 08:25:02 +02:00
Ralf Jung
17015cd5af
Rollup merge of #76534 - notriddle:doc-comments, r=jyn514
Add doc comments for From impls

https://github.com/rust-lang/rust/issues/51430
2020-09-16 08:24:56 +02:00
Ralf Jung
fd86705a20
Rollup merge of #76062 - pickfire:patch-13, r=jyn514
Vec slice example fix style and show type elision
2020-09-16 08:24:46 +02:00
Ralf Jung
73858d01c3
Rollup merge of #76056 - pickfire:patch-10, r=jyn514
Add more info for Vec Drain doc

See its documentation for more
2020-09-16 08:24:40 +02:00
Stein Somers
378b64392f BTreeMap: avoid slices even more 2020-09-16 01:10:44 +02:00
Ralf Jung
c528d24196 fix slice::check_range aliasing problems 2020-09-15 23:14:41 +02:00
Ivan Tham
1f572b0349
Vec doc use elision as code rather than comment 2020-09-15 14:41:43 +08:00
bors
6cae28165f Auto merge of #76682 - richkadel:vec-take, r=Mark-Simulacrum
Optimize behavior of vec.split_off(0) (take all)

Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current behavior
of copying the entire vector.

The change honors documented behavior that the original vector's
"previous capacity unchanged".

This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:

```rust
    let mut vec = Vec::new();
    loop {
        vec.push(something);
        if condition_is_met {
            process(vec.split_off(0));
        }
    }
```

`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:

```rust
    let mut capacity = 1;
    let mut vec: Option<Vec<Stuff>> = None;
    loop {
        vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
        if condition_is_met {
            capacity = vec.capacity();
            process(vec.take().unwrap());
        }
    }
```

Directly using `mem::replace()` (instead of  calling`split_off()`) could work,
but `mem::replace()` is a more advanced tool for Rust developers, and in
this case, I believe developers would assume the standard library should
be sufficient for the purpose described here.

The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.

This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.

The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.

(Let me know if I should make that documentation update.)

Note, for future consideration:

I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):

```
    pub fn take_all(&mut self) -> Self {
        self.split_off(0)
    }
```

This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.

r? `@wesleywiser`
FYI: `@tmandry`
2020-09-15 05:01:17 +00:00
Rich Kadel
79aa9b15d7 Optimize behavior of vec.split_off(0) (take all)
Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current
behavior of copying the entire vector.

The change honors documented behavior that the method leaves the
original vector's "previous capacity unchanged".

This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:

```rust
    let mut vec = Vec::new();
    loop {
        vec.push(something);
        if condition_is_met {
            process(vec.split_off(0));
        }
    }
```

`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:

```rust
    let mut capacity = 1;
    let mut vec: Option<Vec<Stuff>> = None;
    loop {
        vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
        if condition_is_met {
            capacity = vec.capacity();
            process(vec.take().unwrap());
        }
    }
```

Directly applying `mem::replace()` could work, but `mem::` functions are
typically a last resort, when a developer is actively seeking better
performance than the standard library provides, for example.

The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.

This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.

The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.

(Let me know if I should make that documentation update.)

Note, for future consideration:

I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):

```
    pub fn take_all(&mut self) -> Self {
        self.split_off(0)
    }
```

This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.
2020-09-13 14:32:29 -07:00
Jonas Schievink
e5389a4a34
Rollup merge of #76527 - fusion-engineering-forks:cleanup-uninit, r=jonas-schievink
Remove internal and unstable MaybeUninit::UNINIT.

Looks like it is no longer necessary, as `uninit_array()` can be used instead in the few cases where it was needed.

(I wanted to just add `#[doc(hidden)]` to remove clutter from the documentation, but looks like it can just be removed entirely.)
2020-09-13 20:21:09 +02:00
bors
989190874f Auto merge of #76538 - fusion-engineering-forks:check-useless-unstable-trait-impl, r=lcnr
Warn for #[unstable] on trait impls when it has no effect.

Earlier today I sent a PR with an `#[unstable]` attribute on a trait `impl`, but was informed that this attribute has no effect there. (comment: https://github.com/rust-lang/rust/pull/76525#issuecomment-689678895, issue: https://github.com/rust-lang/rust/issues/55436)

This PR adds a warning for this situation. Trait `impl` blocks with `#[unstable]` where both the type and the trait are stable will result in a warning:

```
warning: An `#[unstable]` annotation here has no effect. See issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information.
   --> library/std/src/panic.rs:235:1
    |
235 | #[unstable(feature = "integer_atomics", issue = "32976")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

---

It detects three problems in the existing code:

1. A few `RefUnwindSafe` implementations for the atomic integer types in `library/std/src/panic.rs`. Example:
d92155bf6a/library/std/src/panic.rs (L235-L236)
2. An implementation of `Error` for `LayoutErr` in `library/std/srd/error.rs`:
d92155bf6a/library/std/src/error.rs (L392-L397)
3. `From` implementations for `Waker` and `RawWaker` in `library/alloc/src/task.rs`. Example:
d92155bf6a/library/alloc/src/task.rs (L36-L37)

Case 3 interesting: It has a bound with an `#[unstable]` trait (`W: Wake`), so appears to have much effect on stable code. It does however break similar blanket implementations. It would also have immediate effect if `Wake` was implemented for any stable type. (Which is not the case right now, but there are no warnings in place to prevent it.) Whether this case is a problem or not is not clear to me. If it isn't, adding a simple `c.visit_generics(..);` to this PR will stop the warning for this case.
2020-09-12 18:01:33 +00:00
Ralf Jung
a49451c805
Rollup merge of #76530 - carbotaniuman:fix-rc, r=RalfJung
Eliminate mut reference UB in Drop impl for Rc<T>

This changes `self.ptr.as_mut()` with `get_mut_unchecked` which
does not use an intermediate reference.  Arc<T> already handled this
case properly.

Fixes #76509
2020-09-12 10:43:18 +02:00
bors
8b6838b6e1 Auto merge of #75021 - cuviper:array_chunks_mut, r=scottmcm
Add `slice::array_chunks_mut`

This follows `array_chunks` from #74373 with a mutable version, `array_chunks_mut`. The implementation is identical apart from mutability. The new tests are adaptations of the `chunks_exact_mut` tests, plus an inference test like the one for `array_chunks`.

I reused the unstable feature `array_chunks` and tracking issue #74985, but I can separate that if desired.

r? `@withoutboats`
cc `@lcnr`
2020-09-12 03:59:46 +00:00
bors
12c10e34a4 Auto merge of #73951 - pickfire:liballoc-intoiter, r=Mark-Simulacrum
Liballoc intoiter refactor
2020-09-11 23:52:03 +00:00
carbotaniuman
b729368d4e Address review comments 2020-09-11 07:25:28 -05:00
Mara Bos
471fb622aa Allow unstable From impl for [Raw]Waker. 2020-09-11 13:36:45 +02:00
bors
ee04f9a4da Auto merge of #74437 - ssomers:btree_no_root_in_noderef, r=Mark-Simulacrum
BTreeMap: move up reference to map's root from NodeRef

Since the introduction of `NodeRef` years ago, it also contained a mutable reference to the owner of the root node of the tree (somewhat disguised as *const). Its intent is to be used only when the rest of the `NodeRef` is no longer needed. Moving this to where it's actually used, thought me 2 things:
- Some sort of "postponed mutable reference" is required in most places that it is/was used, and that's exactly where we also need to store a reference to the length (number of elements) of the tree, for the same reason. The length reference can be a normal reference, because the tree code does not care about tree length (just length per node).
- It's downright obfuscation in `from_sorted_iter` (transplanted to #75329)
- It's one of the reasons for the scary notice on `reborrow_mut`, the other one being addressed in #73971.

This does repeat the raw pointer code in a few places, but it could be bundled up with the length reference.

r? `@Mark-Simulacrum`
2020-09-10 23:29:57 +00:00
Tyler Mandry
8bf03c3f62
Rollup merge of #76543 - ssomers:btree_cleanup_4, r=Mark-Simulacrum
Document btree's unwrap_unchecked

#74693's second wind
2020-09-09 21:02:36 -07:00
Stein Somers
f42dac0ce0 Document btree's unwrap_unchecked 2020-09-10 00:25:59 +02:00
Tyler Mandry
c18fa460a4
Rollup merge of #76504 - Flying-Toast:master, r=lcnr
Capitalize safety comments
2020-09-09 15:06:00 -07:00
Tyler Mandry
0d20cf8568
Rollup merge of #76481 - moonheart08:vec_deque_constify, r=sfackler
Convert repetitive target_pointer_width checks to const solution.

Simply a quick code tidying change. Not sure if more needs to be said.
2020-09-09 15:05:56 -07:00
Stein Somers
2b54ab880c BTreeMap: pull the map's root out of NodeRef 2020-09-10 00:02:54 +02:00
Michael Howell
8b0d0a0cad Add documentation for impl<T> From<BinaryHeap<T>> for Vec<T> 2020-09-09 11:53:24 -07:00
carbotaniuman
bb57c9f91c Format 2020-09-09 13:44:22 -05:00
carbotaniuman
8f43fa0989 Add WeakInner<'_> and have Weak::inner() return it
This avoids overlapping a reference covering the data field,
which may be changed due in concurrent conditions. This fully
fixed the UB mainfested with `new_cyclic`.
2020-09-09 13:39:48 -05:00
carbotaniuman
493c037699 Eliminate mut reference UB in Drop impl for Rc<T>
This changes `self.ptr.as_mut()` with `get_mut_unchecked` which
does not use an intermediate reference.  Arc<T> already handled this
case properly.
2020-09-09 12:14:18 -05:00
Mara Bos
4506d26cf3 Remove internal and unstable MaybeUninit::UNINIT.
Looks like it is no longer necessary, as uninit_array() can be used
instead in the few cases where it was needed.
2020-09-09 18:38:10 +02:00
Stein Somers
8158d5623e BTreeMap: avoid aliasing by avoiding slices 2020-09-09 08:58:02 -04:00
Ralf Jung
7889373730 make as_leaf return a raw pointer, to reduce aliasing assumptions 2020-09-09 08:38:34 -04:00
Flying-Toast
2799aec6ab Capitalize safety comments 2020-09-08 22:37:18 -04:00
Braden Nelson
e02952c0cc
Update library/alloc/src/collections/vec_deque.rs
Replace lshift with multiply

Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2020-09-08 13:11:08 -05:00
moonheart08
c3c84ad027 Convert MAXIMUM_ZST_CAPACITY to be calculated in a
const instead of multiple target_pointer_width checks.
2020-09-08 10:35:35 -05:00
Dylan DPC
5b8f76d564
Rollup merge of #76303 - jyn514:vec-assert-doc, r=Dylan-DPC
Link to `#capacity-and-reallocation` when using with_capacity

Follow up to https://github.com/rust-lang/rust/pull/76058#discussion_r479655750.
r? @pickfire
2020-09-07 01:17:56 +02:00
bors
cdc8f0606d Auto merge of #76217 - RalfJung:maybe-uninit-slice, r=KodrAus
rename MaybeUninit slice methods

The `first` methods conceptually point to the whole slice, not just its first element, so rename them to be consistent with the raw ptr methods on ref-slices.

Also, do the equivalent of https://github.com/rust-lang/rust/pull/76047 for the slice reference getters, and make them part of https://github.com/rust-lang/rust/issues/63569 (so far they somehow had no tracking issue).

* first_ptr -> slice_as_ptr
* first_ptr_mut -> slice_as_mut_ptr
* slice_get_ref -> slice_assume_init_ref
* slice_get_mut -> slice_assume_init_mut
2020-09-05 21:02:18 +00:00
Ralf Jung
cff5f56886 rename MaybeUninit slice methods
first_ptr -> slice_as_ptr
first_ptr_mut -> slice_as_mut_ptr
slice_get_ref -> slice_assume_init_ref
slice_get_mut -> slice_assume_init_mut
2020-09-05 17:24:22 +02:00
Dylan DPC
86cf7976e2
Rollup merge of #76060 - pickfire:patch-12, r=jyn514
Link vec doc to & reference

It is not always obvious that people could see the docs for `&`
especially for beginners, it also helps learnability.
2020-09-05 16:28:24 +02:00
Dylan DPC
4bd3f266b0
Rollup merge of #75994 - mental32:impl-rc-new-cyclic, r=KodrAus
`impl Rc::new_cyclic`

References #75861

r? @Dylan-DPC
2020-09-05 16:28:22 +02:00
Josh Stone
864a28e01d Re-export ArrayChunksMut in alloc 2020-09-04 19:51:29 -07:00
bors
70c5f6efc4 Auto merge of #75200 - ssomers:btree_valmut, r=Mark-Simulacrum
BTreeMap: introduce marker::ValMut and reserve Mut for unique access

The mutable BTreeMap iterators (apart from `DrainFilter`) are double-ended, meaning they have to rely on a front and a back handle that each represent a reference into the tree. Reserve a type category `marker::ValMut` for them, so that we guarantee that they cannot reach operations on handles with borrow type `marker::Mut`and that these operations can assume unique access to the tree.

Including #75195, benchmarks report no genuine change:
```
benchcmp old new --threshold 5
 name                                 old ns/iter  new ns/iter  diff ns/iter   diff %  speedup
 btree::map::iter_100                 3,333        3,023                -310   -9.30%   x 1.10
 btree::map::range_unbounded_vs_iter  36,624       31,569             -5,055  -13.80%   x 1.16
```

r? @Mark-Simulacrum
2020-09-04 23:16:23 +00:00
bors
ef55a0a92f Auto merge of #75207 - dylni:add-slice-check-range, r=KodrAus
Add `slice::check_range`

This method is useful for [`RangeBounds`] parameters. It's even been [rewritten](22ee68dc58/src/librustc_data_structures/sorted_map.rs (L214)) [many](22ee68dc58/library/alloc/src/vec.rs (L1299)) [times](22ee68dc58/library/core/src/slice/mod.rs (L2441)) in the standard library, sometimes assuming that the bounds won't be [`usize::MAX`].

For example, [`Vec::drain`] creates an empty iterator when [`usize::MAX`] is used as an inclusive end bound:

```rust
assert!(vec![1].drain(..=usize::max_value()).eq(iter::empty()));
```

If this PR is merged, I'll create another to use it for those methods.

[`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
[`usize::MAX`]: https://doc.rust-lang.org/std/primitive.usize.html#associatedconstant.MAX
[`Vec::drain`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.drain
2020-09-04 12:21:43 +00:00
Ivan Tham
85146b9db7
Add slice primitive link to vec 2020-09-04 09:50:50 +08:00
Joshua Nelson
7b823df489 Link to #capacity-and-reallocation when using with_capacity 2020-09-03 18:08:25 -04:00
The8472
2f23a0fcca fix debug assertion
The InPlaceIterable debug assert checks that the write pointer
did not advance beyond the read pointer. But TrustedRandomAccess
never advances the read pointer, thus triggering the assert.
Skip the assert if the source pointer did not change during iteration.
2020-09-03 22:15:47 +02:00
The8472
8e5fe5569b improve comments and naming 2020-09-03 20:59:37 +02:00
The8472
6464586542 add explanation to specialization marker 2020-09-03 20:59:36 +02:00
The8472
acdd441cc3 remove separate no-drop code path since it resulted in more LLVM IR 2020-09-03 20:59:36 +02:00
The8472
435219dd82 remove empty Vec extend optimization
The optimization meant that every extend code path had to emit llvm
IR for from_iter and extend spec_extend, which likely impacts
compile times while only improving a few edge-cases
2020-09-03 20:59:35 +02:00