1. Fix the sections in the book to have the correct signatures. I've
also marked them as `ignore`; there's no way to set the `no_std`
feature for libc, so it pulls in the stdlib, so this wasn't even
testing the actual thing it was testing. Better to just ignore.
2. Correcting libcore's docs for factual inaccuracy, and add a note
about language items.
Fixes#33677
prefer `if let` to match with `None => {}` arm in some places
This is a spiritual succesor to #34268 / 8531d581, in which we replaced a
number of matches of None to the unit value with `if let` conditionals
where it was judged that this made for clearer/simpler code (as would be
recommended by Manishearth/rust-clippy's `single_match` lint). The same
rationale applies to matches of None to the empty block.
----
r? @jseyfried
This is a spiritual succesor to #34268/8531d581, in which we replaced a
number of matches of None to the unit value with `if let` conditionals
where it was judged that this made for clearer/simpler code (as would be
recommended by Manishearth/rust-clippy's `single_match` lint). The same
rationale applies to matches of None to the empty block.
std: Stabilize APIs for the 1.11.0 release
Although the set of APIs being stabilized this release is relatively small, the
trains keep going! Listed below are the APIs in the standard library which have
either transitioned from unstable to stable or those from unstable to
deprecated.
Stable
* `BTreeMap::{append, split_off}`
* `BTreeSet::{append, split_off}`
* `Cell::get_mut`
* `RefCell::get_mut`
* `BinaryHeap::append`
* `{f32, f64}::{to_degrees, to_radians}` - libcore stabilizations mirroring past
libstd stabilizations
* `Iterator::sum`
* `Iterator::product`
Deprecated
* `{f32, f64}::next_after`
* `{f32, f64}::integer_decode`
* `{f32, f64}::ldexp`
* `{f32, f64}::frexp`
* `num::One`
* `num::Zero`
Added APIs (all unstable)
* `iter::Sum`
* `iter::Product`
* `iter::Step` - a few methods were added to accomodate deprecation of One/Zero
Removed APIs
* `From<Range<T>> for RangeInclusive<T>` - everything about `RangeInclusive` is
unstable
Closes#27739Closes#27752Closes#32526Closes#33444Closes#34152
cc #34529 (new tracking issue)
Although the set of APIs being stabilized this release is relatively small, the
trains keep going! Listed below are the APIs in the standard library which have
either transitioned from unstable to stable or those from unstable to
deprecated.
Stable
* `BTreeMap::{append, split_off}`
* `BTreeSet::{append, split_off}`
* `Cell::get_mut`
* `RefCell::get_mut`
* `BinaryHeap::append`
* `{f32, f64}::{to_degrees, to_radians}` - libcore stabilizations mirroring past
libstd stabilizations
* `Iterator::sum`
* `Iterator::product`
Deprecated
* `{f32, f64}::next_after`
* `{f32, f64}::integer_decode`
* `{f32, f64}::ldexp`
* `{f32, f64}::frexp`
* `num::One`
* `num::Zero`
Added APIs (all unstable)
* `iter::Sum`
* `iter::Product`
* `iter::Step` - a few methods were added to accomodate deprecation of One/Zero
Removed APIs
* `From<Range<T>> for RangeInclusive<T>` - everything about `RangeInclusive` is
unstable
Closes#27739Closes#27752Closes#32526Closes#33444Closes#34152
cc #34529 (new tracking issue)
Improve code example for try!
This change improves the code example for try!,
avoiding to use try! in the example code that shows
what code constructs try! can replace.
Revert "Remove the return_address intrinsic."
This reverts commit b30134dbc3.
Servo might want this merged if they don't merge servo/servo#11872 soon.
cc @pnkfelix @jdm
Use `len` instead of `size_hint` where appropiate
This makes it clearer that we're not just looking for a lower bound but
rather know that the iterator is an `ExactSizeIterator`.
std: Fix up stabilization discrepancies
* Remove the deprecated `CharRange` type which was forgotten to be removed
awhile back.
* Stabilize the `os::$platform::raw::pthread_t` type which was intended to be
stabilized as part of #32804
* Remove the deprecated `CharRange` type which was forgotten to be removed
awhile back.
* Stabilize the `os::$platform::raw::pthread_t` type which was intended to be
stabilized as part of #32804
Add custom message parameter to `assert_eq!`
`assert!` macro accepts a custom message parameter and it's sometimes useful. But `assert_eq!` doesn't have it and users need to use `assert!` instead of `assert_eq!` when they want to output a custom message even if the assertion just compares two values. This pull request will resolve those cases.
Remove unzip() SizeHint hack
This was using an invalid iterator so is likely to end with buggy
behaviour.
It also doesn't even benefit many type in std including Vec so removing it
shouldn't cause any problems.
Fixes: #33468
Specialize .zip() for efficient slice and slice iteration
The idea is to introduce a private trait TrustedRandomAccess and specialize .zip() for random access iterators into a counted loop.
The implementation in the PR is internal and has no visible effect in the API
Why a counted loop? To have each slice iterator compile to just a pointer, and both pointers are indexed with the same loop counter value in the generated code. When this succeeds, copying loops are readily recognized and replaced with memcpy and addition loops autovectorize well.
The TrustedRandomAccess approach works very well on the surface. Microbenchmarks optimize well, following the ideas above, and that is a dramatic improvement of .zip()'s codegen.
```rust
// old zip before this PR: bad, byte-for-byte loop
// with specialized zip: memcpy
pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
for (a, b) in ys.iter_mut().zip(xs) {
*a = *b;
}
}
// old zip before this PR: single addition per iteration
// with specialized zip: vectorized
pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
for (a, b) in ys.iter_mut().zip(xs) { *a += *b; }
}
// old zip before this PR: single addition per iteration
// with specialized zip: vectorized (!!)
pub fn add_zip3(xs: &[f32], ys: &[f32], zs: &mut [f32]) {
for ((a, b), c) in zs.iter_mut().zip(xs).zip(ys) { *a += *b * *c; }
}
```
Yet in more complex situations, the .zip() loop can still fall back to its old behavior where phantom null checks throw in fake premature end of the loop conditionals. Remember that a NULL inside
Option<(&T, &T)> makes it a `None` value and a premature (in this case)
end of the loop.
So even if we have 1) an explicit `Some` in the code and 2) the types of the pointers are `&T` or `&mut T` which are nonnull, we can still get a phantom null check at that point.
One example that illustrates the difference is `copy_zip` with slice versus Vec arguments. The involved iterator types are exactly the same, but the Vec version doesn't compile down to memcpy. Investigating into this, the function argument metadata emitted to llvm plays the biggest role. As eddyb summarized, we need nonnull for the loop to autovectorize and noalias for it to replace with memcpy.
There was an experiment to use `assume` to add a non-null assumption on each of the two elements in the specialized zip iterator, but this only helped in some of the test cases and regressed others. Instead I think the nonnull/noalias metadata issue is something we need to solve separately anyway.
These have conditionally implemented TrustedRandomAccess
- Enumerate
- Zip
These have not implemented it
- Map is sideeffectful. The forward case would be workable, but the double ended case is complicated.
- Chain, exact length semantics unclear
- Filter, FilterMap, FlatMap and many others don't offer random access and/or exact length
derive Hash (and not Copy) for ranges
Fixes#34170.
Also, `RangeInclusive` was `Copy` by mistake -- fix that, which is a [breaking-change] to that unstable type.
docs: simplify wording
It took me more then a moment to decipher "with no non-`'static`" thing :)
"`'static` type" should say the same thing more clearly.
r? @steveklabnik
Fix wrong statement in compare_exchange doc
The documentation for `core::sync::atomic::AtomicSomething::compare_exchange` contains a wrong, or imprecise, statement about the return value. It goes:
The return value is a result indicating whether the new value was written and containing
the previous value. On success this value is guaranteed to be equal to `new`.
In the second sentence, `this value` is gramatically understood as referring to `return value` from the first sentence. Due to how CAS works, the returned value is always what was in the atomic variable _before_ the operation occurred, not what was written into it during the operation. Hence, the fixed doc should say:
The return value is a result indicating whether the new value was written and containing
the previous value. On success this value is guaranteed to be equal to `current`.
This version is confirmed by the runnable examples in variants of `AtomicSomething`, e.g.
assert_eq!(some_bool.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed),
Ok(true));
where the returned value is `Ok(current)`. This PR fixes all occurrences of this bug I could find.
An alternative solution would be to modify the second sentence so that it refers to the value _written_ into the Atomic rather than what was there before, in which case it would be correct. Example alternative formulation:
On success the value written into the `bool`/`usize`/`whatever` is guaranteed to be equal to `new`.
r? @steveklabnik
This was using an invalid iterator so is likely to end with buggy
behaviour.
It also doesn't even benefit many type in std including Vec so removing it
shouldn't cause any problems.
Support 16-bit pointers as well as i/usize
I'm opening this pull request to get some feedback from the community.
Although Rust doesn't support any platforms with a native 16-bit pointer at the moment, the [AVR-Rust][ar] fork is working towards that goal. Keeping this forked logic up-to-date with the changes in master has been onerous so I'd like to merge these changes so that they get carried along when refactoring happens. I do not believe this should increase the maintenance burden.
This is based on the original work of Dylan McKay (@dylanmckay).
[ar]: https://github.com/avr-rust/rust
core: check pointer equality when comparing byte slices
If pointer address and length are the same, it should be the same slice.
In experiments, I've seen that this doesn't happen as often in debug builds, but release builds seem to optimize to using a single pointer more often.