Make ptr::write const
~~The code in this PR as of right now is not much more than an experiment.~~
~~This should, if I am not mistaken, in theory compile and pass the tests once the bootstraping compiler is updated. Thus the PR is blocked on that which should happen some time after the February the 9th. Also we might want to wait for #79989 to avoid regressing performance due to using `mem::forget` over `intrinsics::forget`~~.
Add tests for Atomic*::fetch_{min,max}
This ensures that all atomic operations except for fences are tested. This has been useful to test my work on using atomic instructions for atomic operations in cg_clif instead of a global lock.
Implement RFC 2580: Pointer metadata & VTable
RFC: https://github.com/rust-lang/rfcs/pull/2580
~~Before merging this PR:~~
* [x] Wait for the end of the RFC’s [FCP to merge](https://github.com/rust-lang/rfcs/pull/2580#issuecomment-759145278).
* [x] Open a tracking issue: https://github.com/rust-lang/rust/issues/81513
* [x] Update `#[unstable]` attributes in the PR with the tracking issue number
----
This PR extends the language with a new lang item for the `Pointee` trait which is special-cased in trait resolution to implement it for all types. Even in generic contexts, parameters can be assumed to implement it without a corresponding bound.
For this I mostly imitated what the compiler was already doing for the `DiscriminantKind` trait. I’m very unfamiliar with compiler internals, so careful review is appreciated.
This PR also extends the standard library with new unstable APIs in `core::ptr` and `std::ptr`:
```rust
pub trait Pointee {
/// One of `()`, `usize`, or `DynMetadata<dyn SomeTrait>`
type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
}
pub trait Thin = Pointee<Metadata = ()>;
pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {}
pub const fn from_raw_parts<T: ?Sized>(*const (), <T as Pointee>::Metadata) -> *const T {}
pub const fn from_raw_parts_mut<T: ?Sized>(*mut (),<T as Pointee>::Metadata) -> *mut T {}
impl<T: ?Sized> NonNull<T> {
pub const fn from_raw_parts(NonNull<()>, <T as Pointee>::Metadata) -> NonNull<T> {}
/// Convenience for `(ptr.cast(), metadata(ptr))`
pub const fn to_raw_parts(self) -> (NonNull<()>, <T as Pointee>::Metadata) {}
}
impl<T: ?Sized> *const T {
pub const fn to_raw_parts(self) -> (*const (), <T as Pointee>::Metadata) {}
}
impl<T: ?Sized> *mut T {
pub const fn to_raw_parts(self) -> (*mut (), <T as Pointee>::Metadata) {}
}
/// `<dyn SomeTrait as Pointee>::Metadata == DynMetadata<dyn SomeTrait>`
pub struct DynMetadata<Dyn: ?Sized> {
// Private pointer to vtable
}
impl<Dyn: ?Sized> DynMetadata<Dyn> {
pub fn size_of(self) -> usize {}
pub fn align_of(self) -> usize {}
pub fn layout(self) -> crate::alloc::Layout {}
}
unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {}
unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Debug for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {}
impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {}
```
API differences from the RFC, in areas noted as unresolved questions in the RFC:
* Module-level functions instead of associated `from_raw_parts` functions on `*const T` and `*mut T`, following the precedent of `null`, `slice_from_raw_parts`, etc.
* Added `to_raw_parts`
The use of module-level functions instead of associated functions
on `<*const T>` or `<*mut T>` follows the precedent of
`ptr::slice_from_raw_parts` and `ptr::slice_from_raw_parts_mut`.
Stabilize by-value `[T; N]` iterator `core::array::IntoIter`
Tracking issue: https://github.com/rust-lang/rust/issues/65798
This is unblocked now that `min_const_generics` has been stabilized in https://github.com/rust-lang/rust/pull/79135.
This PR does *not* include the corresponding `IntoIterator` impl, which is https://github.com/rust-lang/rust/pull/65819. Instead, an iterator can be constructed through the `new` method.
`new` would become unnecessary when `IntoIterator` is implemented and might be deprecated then, although it will stay stable.
Add `unwrap_unchecked()` methods for `Option` and `Result`
In particular:
- `unwrap_unchecked()` for `Option`.
- `unwrap_unchecked()` and `unwrap_err_unchecked()` for `Result`.
These complement other `*_unchecked()` methods in `core` etc.
Currently there are a couple of places it may be used inside rustc (`LinkedList`, `BTree`). It is also easy to find other repositories with similar functionality.
Fixes#48278.
TrustedRandomAaccess specialization composes incorrectly for nested iter::Zips
I found this while working on improvements for TRA.
After partially consuming a Zip adapter and then wrapping it into another Zip where the adapters use their `TrustedRandomAccess` specializations leads to the outer adapter returning elements which should have already been consumed.
If the optimizer gets tripped up by the addition this might affect performance for chained `zip()` iterators even when the inner one is not partially advanced but it would require more extensive fixes to `TrustedRandomAccess` to communicate those offsets earlier.
Included test fails on nightly, [playground link](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=24fa1edf8a104ff31f5a24830593b01f)
Add Iterator::intersperse_with
This is a follow-up to #79479, tracking in #79524, as discussed https://github.com/rust-lang/rust/pull/79479#issuecomment-752671731.
~~Note that I had to manually implement `Clone` and `Debug` because `derive` insists on placing a `Clone`-bound on the struct-definition, which is too narrow. There is a long-standing issue # for this somewhere around here :-)~~
Also, note that I refactored the guts of `Intersperse` into private functions and re-used them in `IntersperseWith`, so I also went light on duplicating all the tests.
If this is suitable to be merged, the tracking issue should be updated, since it only mentions `intersperse`.
Happy New Year!
r? ``@m-ou-se``
These tests invoke the various op traits using all accepted types they
are implemented for as well as for references to those types.
This fixes#49660 and ensures the following implementations exist:
* `Add`, `Sub`, `Mul`, `Div`, `Rem`
* `T op T`, `T op &T`, `&T op T` and `&T op &T`
* for all integer and floating point types
* `AddAssign`, `SubAssign`, `MulAssign`, `DivAssign`, `RemAssign`
* `&mut T op T` and `&mut T op &T`
* for all integer and floating point types
* `Neg`
* `op T` and `op &T`
* for all signed integer and floating point types
* `Not`
* `op T` and `op &T`
* for `bool`
* `BitAnd`, `BitOr`, `BitXor`
* `T op T`, `T op &T`, `&T op T` and `&T op &T`
* for all integer types and bool
* `BitAndAssign`, `BitOrAssign`, `BitXorAssign`
* `&mut T op T` and `&mut T op &T`
* for all integer types and bool
* `Shl`, `Shr`
* `L op R`, `L op &R`, `&L op R` and `&L op &R`
* for all pairs of integer types
* `ShlAssign`, `ShrAssign`
* `&mut L op R`, `&mut L op &R`
* for all pairs of integer types
In particular:
- `unwrap_unchecked()` for `Option`.
- `unwrap_unchecked()` and `unwrap_err_unchecked()` for `Result`.
These complement other `*_unchecked()` methods in `core` etc.
Currently there are a couple of places it may be used inside rustc
(`LinkedList`, `BTree`). It is also easy to find other repositories
with similar functionality.
Fixes#48278.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
After partially consuming a Zip adapter and then wrapping it into
another Zip where the adapters use their TrustedRandomAccess specializations
leads to the outer adapter returning elements which should have already been
consumed.
The return of the GroupBy and GroupByMut iterators on slice
According to https://github.com/rust-lang/rfcs/pull/2477#issuecomment-742034372, I am opening this PR again, this time I implemented it in safe Rust only, it is therefore much easier to read and is completely safe.
This PR proposes to add two new methods to the slice, the `group_by` and `group_by_mut`. These two methods provide a way to iterate over non-overlapping sub-slices of a base slice that are separated by the predicate given by the user (e.g. `Partial::eq`, `|a, b| a.abs() < b.abs()`).
```rust
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
let mut iter = slice.group_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);
```
[An RFC](https://github.com/rust-lang/rfcs/pull/2477) was open 2 years ago but wasn't necessary.
Rollup of 9 pull requests
Successful merges:
- #78934 (refactor: removing library/alloc/src/vec/mod.rs ignore-tidy-filelength)
- #79479 (Add `Iterator::intersperse`)
- #80128 (Edit rustc_ast::ast::FieldPat docs)
- #80424 (Don't give an error when creating a file for the first time)
- #80458 (Some Promotion Refactoring)
- #80488 (Do not create dangling &T in Weak<T>::drop)
- #80491 (Miri: make size/align_of_val work for dangling raw ptrs)
- #80495 (Rename kw::Invalid -> kw::Empty)
- #80513 (Add regression test for #80062)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Add `impl Div<NonZeroU{0}> for u{0}` which cannot panic
Dividing an unsigned int by a `NonZeroUxx` requires a user to write (for example, in [this SO question](https://stackoverflow.com/questions/64855738/how-to-inform-the-optimizer-that-nonzerou32get-will-never-return-zero)):
```
pub fn safe_div(x: u32, y: std::num::NonZeroU32) -> u32 {
x / y.get()
}
```
which generates a panicking-checked-div [assembly](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,j:1,lang:rust,selection:(endColumn:2,endLineNumber:6,positionColumn:2,positionLineNumber:6,selectionStartColumn:2,selectionStartLineNumber:6,startColumn:2,startLineNumber:6),source:%27pub+fn+div(x:+u32,+y:+u32)+-%3E+u32+%7B%0A++++x+/+y%0A%7D%0Apub+fn+safe_div(x:+u32,+y:+std::num::NonZeroU32)+-%3E+u32+%7B%0A++++x+/+y.get()+//+an+unchecked+division+expected%0A%7D%27),l:%275%27,n:%270%27,o:%27Rust+source+%231%27,t:%270%27)),k:50,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:compiler,i:(compiler:r1470,filters:(b:%270%27,binary:%271%27,commentOnly:%270%27,demangle:%270%27,directives:%270%27,execute:%271%27,intel:%270%27,libraryCode:%271%27,trim:%271%27),fontScale:14,j:1,lang:rust,libs:!(),options:%27-O%27,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:%275%27,n:%270%27,o:%27rustc+1.47.0+(Editor+%231,+Compiler+%231)+Rust%27,t:%270%27)),k:50,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4).
Avoiding the `panic` currently requires `unsafe` code.
This PR adds an `impl Div<NonZeroU{0}> for u{0}` (and `impl Rem<NonZeroU{0}> for u{0}`) which calls the `unchecked_div` (and `unchecked_rem`) intrinsic without any additional checks,
making the following code compile:
```
pub fn safe_div(x: u32, y: std::num::NonZeroU32) -> u32 {
x / y
}
pub fn safe_rem(x: u32, y: std::num::NonZeroU32) -> u32 {
x % y
}
```
The doc is set to match the regular div impl [docs](https://doc.rust-lang.org/beta/src/core/ops/arith.rs.html#460).
I've marked these as stable because (as I understand it) trait impls are automatically stable. I'm happy to change it to unstable if needed.
Following `@dtolnay` template from a similar issue:
this adds the following **stable** impls, which rely on dividing unsigned integers by nonzero integers being well defined and previously would have involved unsafe code to encode that knowledge:
```
impl Div<NonZeroU8> for u8 {
type Output = u8;
}
impl Rem<NonZeroU8> for u8 {
type Output = u8;
}
```
and equivalent for u16, u32, u64, u128, usize, but **not** for i8, i16, i32, i64, i128, isize (since -1/MIN is undefined).
r? `@dtolnay`
Part of #68490.
Care has been taken to leave the old consts where appropriate, for testing backcompat regressions, module shadowing, etc. The intrinsics docs were accidentally referring to some methods on f64 as std::f64, which I changed due to being contrary with how we normally disambiguate the shadow module from the primitive. In one other place I changed std::u8 to std::ops since it was just testing path handling in macros.
For places which have legitimate uses of the old consts, deprecated attributes have been optimistically inserted. Although currently unnecessary, they exist to emphasize to any future deprecation effort the necessity of these specific symbols and prevent them from being accidentally removed.
Add lint for panic!("{}")
This adds a lint that warns about `panic!("{}")`.
`panic!(msg)` invocations with a single argument use their argument as panic payload literally, without using it as a format string. The same holds for `assert!(expr, msg)`.
This lints checks if `msg` is a string literal (after expansion), and warns in case it contained braces. It suggests to insert `"{}", ` to use the message literally, or to add arguments to use it as a format string.
![image](https://user-images.githubusercontent.com/783247/96643867-79eb1080-1328-11eb-8d4e-a5586837c70a.png)
This lint is also a good starting point for adding warnings about `panic!(not_a_string)` later, once [`panic_any()`](https://github.com/rust-lang/rust/pull/74622) becomes a stable alternative.
add trailing_zeros and leading_zeros to non zero types
as a way towards being able to use the optimized intrinsics ctlz_nonzero and cttz_nonzero from stable.
have not crated any tracking issue if this is not a solution that is wanted
Test structural matching for all range types
As of #70166 all range types (`core::ops::Range` etc.) can be structurally matched upon, and by extension used in const generics. In reference to the fact that this is a publicly observable property of these types, and thus falls under the Rust stability guarantees of the standard library, a regression test was added in #70283.
This regression test was implemented by me by testing for the ability to use the range types within const generics, but that is not the actual property the std guarantees now (const generics is still unstable). This PR addresses that situation by adding extra tests for the range types that directly test whether they can be structurally matched upon.
Note: also adds the otherwise unrelated test `test_range_to_inclusive` for completeness with the other range unit tests
Duration::zero() -> Duration::ZERO
In review for #72790, whether or not a constant or a function should be favored for `#![feature(duration_zero)]` was seen as an open question. In https://github.com/rust-lang/rust/issues/73544#issuecomment-691701670 an invitation was opened to either stabilize the methods or propose a switch to the constant value, supplemented with reasoning. Followup comments suggested community preference leans towards the const ZERO, which would be reason enough.
ZERO also "makes sense" beside existing associated consts for Duration. It is ever so slightly awkward to have a series of constants specifying 1 of various units but leave 0 as a method, especially when they are side-by-side in code. It seems unintuitive for the one non-dynamic value (that isn't from Default) to be not-a-const, which could hurt discoverability of the associated constants overall. Elsewhere in `std`, methods for obtaining a constant value were even deprecated, as seen with [std::u32::min_value](https://doc.rust-lang.org/std/primitive.u32.html#method.min_value).
Most importantly, ZERO costs less to use. A match supports a const pattern, but const fn can only be used if evaluated through a const context such as an inline `const { const_fn() }` or a `const NAME: T = const_fn()` declaration elsewhere. Likewise, while https://github.com/rust-lang/rust/issues/73544#issuecomment-691949373 notes `Duration::zero()` can optimize to a constant value, "can" is not "will". Only const contexts have a strong promise of such. Even without that in mind, the comment in question still leans in favor of the constant for simplicity. As it costs less for a developer to use, may cost less to optimize, and seems to have more of a community consensus for it, the associated const seems best.
r? ```@LukasKalbertodt```
Refactor IntErrorKind to avoid "underflow" terminology
This PR is a continuation of #76455
# Changes
- `Overflow` renamed to `PosOverflow` and `Underflow` renamed to `NegOverflow` after discussion in #76455
- Changed some of the parsing code to return `InvalidDigit` rather than `Empty` for strings "+" and "-". https://users.rust-lang.org/t/misleading-error-in-str-parse-for-int-types/49178
- Carry the problem `char` with the `InvalidDigit` variant.
- Necessary changes were made to the compiler as it depends on `int_error_matching`.
- Redid tests to match on specific errors.
r? ```@KodrAus```
Stabilize `Poll::is_ready` and `is_pending` as const
Insta-stabilize the methods `is_ready` and `is_pending` of `std::task::Poll` as const, in the same way as [PR#76198](https://github.com/rust-lang/rust/pull/76198).
Possible because of the recent stabilization of const control flow.
Part of #76225.
Duration::ZERO composes better with match and various other things,
at the cost of an occasional parens, and results in less work for the
optimizer, so let's use that instead.
This expands time's test suite to use more and in more places the
range of methods and constants added to Duration in recent
proposals for the sake of testing more API surface area and
improving legibility.
Replace absolute paths with relative ones
Modern compilers allow reaching external crates
like std or core via relative paths in modules
outside of lib.rs and main.rs.