Remove problematic specialization from RangeInclusive
Fixes#67194 using the approach [outlined by Mark-Simulacrum](https://github.com/rust-lang/rust/issues/67194#issuecomment-581669549).
> I believe the property we want is that if `PartialEq(&self, &other) == true`, then `self.next() == other.next()`. It is true that this is satisfied by removing the specialization and always doing `is_empty.unwrap_or_default()`; the "wrong" behavior there arises from calling `next()` having an effect on initially empty ranges, as we should be in `is_empty = true` but are not (yet) there. It might be possible to detect that the current state is always empty (i.e., `start > end`) and then not fill in the empty slot. I think this might solve the problem without regressing tests; however, this could have performance implications.
> That approach essentially states that we only use the `is_empty` slot for cases where `start <= end`. That means that `Idx: !Step` and `start > end` would both behave the same, and correctly -- we do not need the boolean if we're not ever going to emit any values from the iterator.
This is implemented here by replacing the `is_empty: Option<bool>` slot with an `exhausted: bool` slot. This flag is
- `false` upon construction,
- `false` when iteration has not yielded an element -- importantly, this means it is always `false` for an iterator empty by construction,
- `false` when iteration has yielded an element and the iterator is not exhausted, and
- only `true` when iteration has been used to exhaust the iterator.
For completeness, this also adds a note to the `Debug` representation to note when the range is exhausted.
Make `num::NonZeroX::new` an unstable `const fn`
cc #53718
These require `#[feature(const_if_match)]`, meaning they must remain unstable for the time being.
Mark several functions and methods in core::cmp as #[must_use]
These functions and methods aren't mutating functions and ignoring the result of them is likely a bug in the user's code.
Don't use the word "unwrap" to describe "unwrap" methods
It's tautological, and "unwrap" is essentially Rust-specific jargon.
I was teaching a newbie some Rust, and doing the usual hand-waving about error handling using unwrap. They asked what 'unwrap' means. I said look it up in the docs. The docs read (paraphrased) "unwrap unwraps". I was embarrassed.
This changes all the Option/Result functions with unwrapping behavior to use a variation on a single description:
> "Returns the contained `Some/Ok` value [or ...]."
It also renames the closure of `Result::unwrap_or_else` to `default` for consistency with `Option`, and perhaps makes a few other small tweaks.
Previous: https://github.com/rust-lang/rust/pull/68849
Remove some unsound specializations
This removes the unsound and exploitable specializations in the standard library
* The `PartialEq` and `Hash` implementations for `RangeInclusive` are changed to avoid specialization.
* The `PartialOrd` specialization for slices now specializes on a limited set of concrete types.
* Added some tests for the soundness problems.
It's tautological, and Rust-specific Jargon.
This changes various Option/Result methods to consistently describe unwrapping
behavior using the words "return", "contain", "consume".
It also renames the closure argument of `Return::unwrap_or_else` to `default` to
be consistent with `Option`.
Mark fn map_or() as eagerly evaluated.
In the docs for option.rs and result.rs, it is noted for all *_or()
functions that they are eagerly evaluated, except for the map_or()
function.
This commit adds this missing documentation to the two files.
Closes#68866
In the docs for option.rs and result.rs, it is noted for all *_or()
functions that they are eagerly evaluated, except for the map_or()
function.
This commit adds this missing documentation to the two files.
Make more arithmetic functions unstably const
This is a smaller version of #66884 (thanks @9999years) that constifies many of the arithmetic functions on integer primitives from #53718 that were blocked on #49146.
This makes the following things unstably const.
- `feature = const_int_unchecked_arith`
- `intrinsics::unchecked_add`
- `intrinsics::unchecked_sub`
- `intrinsics::unchecked_mul`
- `intrinsics::unchecked_div`
- `intrinsics::unchecked_rem`
- `feature = const_checked_int_methods`
- `checked_add`
- `checked_sub`
- `checked_mul`
- `checked_div` (Uses `intrinsics::unchecked_div` internally)
- `checked_rem` (Uses `intrinsics::unchecked_rem` internally)
- `checked_neg`
- `checked_shl`
- `checked_shr`
- `checked_abs`
- `feature = const_saturating_int_methods`
- `saturating_mul`
- `saturating_neg` (Uses `intrinsics::unchecked_sub` internally)
- `saturating_abs` (Uses `intrinsics::unchecked_sub` internally)
- `feature = const_wrapping_int_methods`
- `wrapping_div`
- `wrapping_rem`
- `feature = const_overflowing_int_methods`
- `overflowing_div`
- `overflowing_rem`
- `feature = const_euclidean_int_methods`
- `checked_div_euclid`
- `checked_rem_euclid`
- `wrapping_div_euclid`
- `wrapping_rem_euclid`
- `overflowing_div_euclid`
- `overflowing_rem_euclid`
Exponentiation and operations on the `NonZero` types are left to a later PR.
r? @oli-obk
cc @rust-lang/wg-const-eval @rust-lang/libs
Step stage0 to bootstrap from 1.42
This also includes a commit which fixes the rustfmt downloading logic to redownload when the rustfmt channel changes, and bumps rustfmt to a more recent version.
Add `Iterator::map_while`
In `Iterator` trait there is `*_map` version of [`filter`] — [`filter_map`], however, there is no `*_map` version of [`take_while`], that can also be useful.
### Use cases
In my code, I've found that I need to iterate through iterator of `Option`s, stopping on the first `None`. So I've written code like this:
```rust
let arr = [Some(4), Some(10), None, Some(3)];
let mut iter = arr.iter()
.take_while(|x| x.is_some())
.map(|x| x.unwrap());
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(10));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
```
Thit code
1) isn't clean
2) In theory, can generate bad bytecode (I'm actually **not** sure, but I think that `unwrap` would generate additional branches with `panic!`)
The same code, but with `map_while` (in the original PR message it was named "take_while_map"):
```rust
let arr = [Some(4), Some(10), None, Some(3)];
let mut iter = arr.iter().map_while(std::convert::identity);
```
Also, `map_while` can be useful when converting something (as in [examples]).
[`filter`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter
[`filter_map`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map
[`take_while`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.take_while
[examples]: https://github.com/rust-lang/rust/compare/master...WaffleLapkin:iter_take_while_map?expand=1#diff-7e57917f962fe6ffdfba51e4955ad6acR1042
Move numeric consts to associated consts step1
A subset of #67913. Implements the first step of RFC https://github.com/rust-lang/rfcs/pull/2700
This PR adds the new constants as unstable constants and defines the old ones in terms of the new ones. Then fix a tiny bit of code that started having naming collisions because of the new assoc consts.
Removed a test that did not seem relevant any longer. Since doing just `u8::MIN` should now indeed be valid.
Rename `Alloc` to `AllocRef`
The allocator-wg has decided to merge this change upstream in https://github.com/rust-lang/wg-allocators/issues/8#issuecomment-577122958.
This renames `Alloc` to `AllocRef` because types that implement `Alloc` are a reference, smart pointer, or ZSTs. It is not possible to have an allocator like `MyAlloc([u8; N])`, that owns the memory and also implements `Alloc`, since that would mean, that moving a `Vec<T, MyAlloc>` would need to correct the internal pointer, which is not possible as we don't have move constructors.
For further explanation please see https://github.com/rust-lang/wg-allocators/issues/8#issuecomment-489464843 and the comments after that one.
Additionally it clarifies the semantics of `Clone` on an allocator. In the case of `AllocRef`, it is clear that the cloned handle still points to the same allocator instance, and that you can free data allocated from one handle with another handle.
The initial proposal was to rename `Alloc` to `AllocHandle`, but `Ref` expresses the semantics better than `Handle`. Also, the only appearance of `Handle` in `std` are for windows specific resources, which might be confusing.
Blocked on https://github.com/rust-lang/miri/pull/1160
Stabilize ptr::slice_from_raw_parts[_mut]
Closes#36925, the tracking issue.
Initial impl: #60667
r? @rust-lang/libs
In addition to stabilizing, I've adjusted the example of `ptr::slice_from_raw_parts` to use `slice_from_raw_parts` instead of `slice_from_raw_parts_mut`, which was unnecessary for the example as written.