Start using pattern types in libcore (NonZero and friends)
part of rust-lang/rust#136006
This PR only changes the internal representation of `NonZero`, `NonMax`, ... and other integral range types in libcore. This subsequently affects other types made up of it, but nothing really changes except that the field of `NonZero` is now accessible safely in contrast to the `rustc_layout_scalar_range_start` attribute, which has all kinds of obscure rules on how to properly access its field.
Support ADT types in type info reflection
Tracking issue: rust-lang/rust#146922 `#![feature(type_info)]`
This PR supports ADT types for feature `type_info` reflection.
(It's still a draft PR, with implementation in progress)
Note that this PR does not take SemVer into consideration (I left a FIXME comment). As discussed earlier ([comment](https://github.com/rust-lang/rust/pull/146923#discussion_r2372249477)), this requires further discussion. However, I hope we could get an initial implementation to land first, so we can start playing with it.
### Progress / Checklist
- [x] Struct support.
- [x] Enum
- [x] Union
- [x] Generics
- [ ] ~Methods~ Implemented and to be implemented in other PRs
- [ ] ~Traits~ Implemented and to be implemented in other PRs
- [x] Rebasing PR to `main` branch
~~(It's currently based on PR rust-lang/rust#151123, so here's an extra commit)~~
- [x] Cleanup and Rebase.
- [x] Fix field info for references. (see [comment](https://github.com/rust-lang/rust/pull/151142#discussion_r2777920512))
r? @oli-obk
Align `ArrayWindows` trait impls with `Windows`
With `slice::ArrayWindows` getting ready to stabilize in 1.94, I noticed that it currently has some differences in trait implementations compared to `slice::Windows`, and I think we should align these.
- Remove `derive(Copy)` -- we generally don't want `Copy` for iterators at all, as this is seen as a footgun (e.g. rust-lang/rust#21809). This is obviously a breaking change though, so we should only remove this if we also backport the removal before it's stable. Otherwise, it should at least be replaced by a manual impl without requiring `T: Copy`.
- Manually `impl Clone`, simply to avoid requiring `T: Clone`.
- `impl FusedIterator`, because it is trivially so. The `since = "1.94.0"` assumes we'll backport this, otherwise we should change that to the "current" placeholder.
- `impl TrustedLen`, because we can trust our implementation.
- `impl TrustedRandomAccess`, because the required `__iterator_get_unchecked` method is straightforward.
r? libs-api
@rustbot label beta-nominated
(at least for the `Copy` removal, but we could be more selective about the rest).
Stop having two different alignment constants
Now that there's a `<T as SizedTypeProperties>::ALIGNMENT` constant, `Alignment::of` can use that instead of an inline constant, like how `Layout::new` uses the constant from `SizedTypeProperties`.
Reword the caveats on `array::map`
Thanks to #107634 and some improvements in LLVM (particularly [`dead_on_unwind`](https://llvm.org/docs/LangRef.html#parameter-attributes)), the method actually optimizes reasonably well now.
So focus the discussion on the fundamental ordering differences where the optimizer might never be able to fix it because of the different behaviour, and keep encouraging `Iterator::map` where an array wasn't actually ever needed.
Stabilize `core::hint::cold_path`
`cold_path` has been around unstably for a while and is a rather useful tool to have. It does what it is supposed to and there are no known remaining issues, so stabilize it here (including const).
Newly stable API:
```rust
// in core::hint
pub const fn cold_path();
```
I have opted to exclude `likely` and `unlikely` for now since they have had some concerns about ease of use that `cold_path` doesn't suffer from. `cold_path` is also significantly more flexible; in addition to working with boolean `if` conditions, it can be used in `match` arms, `if let`, closures, and other control flow blocks. `likely` and `unlikely` are also possible to implement in user code via `cold_path`, if desired.
Closes: https://github.com/rust-lang/rust/issues/136873 (tracking issue)
---
There has been some design and implementation work for making `#[cold]` function in more places, such as `if` arms, `match` arms, and closure bodies. Considering a stable `cold_path` will cover all of these usecases, it does not seem worth pursuing a more powerful `#[cold]` as an alternative way to do the same thing. If the lang team agrees, then:
Closes: https://github.com/rust-lang/rust/issues/26179
Closes: https://github.com/rust-lang/rust/pull/120193
feat: Implement `int_from_ascii` for `NonZero<T>`
- Tracking issue: rust-lang/rust#134821
This pull request adds `from_ascii` and `from_ascii_radix` methods to `NonZero<T>` that parses a non-zero integer from an ASCII-byte slice (`&[u8]`) with decimal digits or digits in a given base.
When using the combination of `int::from_ascii` or `int::from_ascii_radix` and `NonZero::<T>::new`, [`IntErrorKind::Zero`](https://doc.rust-lang.org/core/num/enum.IntErrorKind.html#variant.Zero) cannot be returned as an error.
`NonZero::<T>::from_str_radix` and `NonZero::<T>::from_str` require a string (`&str`) as a parameter.
```rust
// Cannot return `IntErrorKind::Zero` as an error.
assert_eq!(NonZero::new(u8::from_ascii(b"0").unwrap()), None);
// Can return `IntErrorKind::Zero` as an error.
let err = NonZero::<u8>::from_ascii(b"0").unwrap_err();
assert_eq!(err.kind(), &IntErrorKind::Zero);
```
See also rust-lang/rust#152193
Stabilize new inclusive range type and iterator type
Part 1 of stabilizing the new range types for rust-lang/rust#125687
stabilizes `core::range::RangeInclusive` and `core::range::RangeInclusiveIter`. Newly stable API:
```rust
// in core and std
pub mod range;
// in core::range
pub struct RangeInclusive<Idx> {
pub start: Idx,
pub last: Idx,
}
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { /* ... */ }
impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
pub const fn contains<U>(&self, item: &U) -> bool
where
Idx: [const] PartialOrd<U>,
U: ?Sized + [const] PartialOrd<Idx>;
pub const fn is_empty(&self) -> bool
where
Idx: [const] PartialOrd;
}
impl<Idx: Step> RangeInclusive<Idx> {
pub fn iter(&self) -> RangeInclusiveIter<Idx>;
}
impl<T> const RangeBounds<T> for RangeInclusive<T> { /* ... */ }
impl<T> const RangeBounds<T> for RangeInclusive<&T> { /* ... */ }
impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> { /* ... */ }
impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> { /* ... */ }
pub struct RangeInclusiveIter<A>(/* ... */);
impl<A: Step> RangeInclusiveIter<A> {
pub fn remainder(self) -> Option<RangeInclusive<A>>;
}
impl<A: Step> Iterator for RangeInclusiveIter<A> {
type Item = A;
/* ... */
}
impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> { /* ... */ }
impl<A: Step> FusedIterator for RangeInclusiveIter<A> { }
impl<A: Step> IntoIterator for RangeInclusive<A> {
type Item = A;
type IntoIter = RangeInclusiveIter<A>;
/* ... */
}
impl ExactSizeIterator for RangeInclusiveIter<u8> { }
impl ExactSizeIterator for RangeInclusiveIter<i8> { }
unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
type Output = [T];
/* ... */
}
unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
type Output = str;
/* ... */
}
```
I've removed the re-exports temporarily because from what I can tell, there's no way to make re-exports of stable items unstable. They will be added back and stabilized in a separate PR.
fN::BITS constants for feature float_bits_const
Also enables the feature for compiler_builtins as otherwise this causes a warning and conflicts with the Float extension trait.
---
Implementation for rust-lang/rust#151073
Feature flag: `#![feature(float_bits_const)]`
Note that this is likely to conflict with some extension traits, as it has with compiler builtins. However, assuming correct values for the constants, they are either `u32`, the same type, which should not cause a problem (as shown by enabling the feature for compiler_builtins), or a different type (e.g. `usize`), which should cause a compiler error. Either way this should never change behaviour unless the extension trait implemented an incorrect value.
Also note that it doesn't seem to be possible to put multiple unstable attributes on an item, so `f128::BITS` and `f16::BITS` are gated behind the feature flags for those primitives, rather than `#![feature(float_bits_const)]`
GVN: Elide more intermediate transmutes
We already skipped intermediate steps like `u32` or `i32` that support any (initialized) value.
This extends that to also allow skipping intermediate steps whose values are a superset of either the source or destination type. Most importantly, that means that `usize` → `NonZeroUsize` → `ptr::Alignment` and `ptr::Alignment` → `NonZeroUsize` → `usize` can skip the middle because `NonZeroUsize` is a superset of `Alignment`.
Then `Alignment::as_usize` is updated to take advantage of that and let us remove some more locals in a few places.
r? cjgillot
Remove duplicated code in `slice/index.rs`
Looks like `const fn` is far enough along now that we can just not have these two copies any more, and have one call the other.