ptr::invalid is not equivalent to a int2ptr cast
I just realized I forgot to update these docs when adding `from_exposed_addr`.
Right now the docs say `invalid` and `from_exposed_addr` are both equivalent to a cast, and that is clearly not what we want.
Cc ``@Gankra``
Partially stabilize `(const_)slice_ptr_len` feature by stabilizing `NonNull::len`
This PR partially stabilizes features `const_slice_ptr_len` and `slice_ptr_len` by only stabilizing `NonNull::len`. This partial stabilization is tracked under features `slice_ptr_len_nonnull` and `const_slice_ptr_len_nonnull`, for which this PR can serve as the tracking issue.
To summarize the discussion from #71146 leading up to this partial stabilization request:
It's currently a bit footgunny to obtain the length of a raw slice pointer, stabilization of `NonNull:len` will help with removing these footguns. Some example footguns are:
```rust
/// # Safety
/// The caller must ensure that `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. is within the bounds of a single allocated object;
/// 3. does not to point to a slice for which the length exceeds `isize::MAX` bytes;
/// 4. points to a properly aligned address;
/// 5. does not point to uninitialized memory;
/// 6. does not point to a mutably borrowed memory location.
pub unsafe fn ptr_len<T>(ptr: core::ptr::NonNull<[T]>) -> usize {
(&*ptr.as_ptr()).len()
}
```
A slightly less complicated version (but still more complicated than it needs to be):
```rust
/// # Safety
/// The caller must ensure that the start of `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. must be within the bounds of a single allocated object.
pub unsafe fn ptr_len<T>(ptr: NonNull<[T]>) -> usize {
(&*(ptr.as_ptr() as *const [()])).len()
}
```
This PR does not stabilize `<*const [T]>::len` and `<*mut [T]>::len` because the tracking issue #71146 list a potential blocker for these methods, but this blocker [does not apply](https://github.com/rust-lang/rust/issues/71146#issuecomment-808735714) to `NonNull::len`.
We should probably also ping the [Constant Evaluation WG](https://github.com/rust-lang/const-eval) since this PR includes a `#[rustc_allow_const_fn_unstable(const_slice_ptr_len)]`. My instinct here is that this will probably be okay because the pointer is not actually dereferenced and `len()` does not touch the address component of the pointer, but would be best to double check :)
One potential down-side was raised that stabilizing `NonNull::len` could lead to encouragement of coding patterns like:
```
pub fn ptr_len<T>(ptr: *mut [T]) -> usize {
NonNull::new(ptr).unwrap().len()
}
```
which unnecessarily assert non-nullness. However, these are much less of a footgun than the above examples and this should be resolved when `slice_ptr_len` fully stabilizes eventually.
Add section on common message styles for Result::expect
Based on a question from https://github.com/rust-lang/project-error-handling/issues/50#issuecomment-1092339937
~~One thing I haven't decided on yet, should I duplicate this section on `Option::expect`, link to this section, or move it somewhere else and link to that location from both docs?~~: I ended up moving the section to `std::error` and referencing it from both `Result::expect` and `Option::expect`'s docs.
I think this section, when combined with the similar update I made on [`std::panic!`](https://doc.rust-lang.org/nightly/std/macro.panic.html#when-to-use-panic-vs-result) implies that we should possibly more aggressively encourage and support the "expect as precondition" style described in this section. The consensus among the libs team seems to be that panic should be used for bugs, not expected potential failure modes. The "expect as error message" style seems to align better with the panic for unrecoverable errors style where they're seen as normal errors where the only difference is a desire to kill the current execution unit (aka erlang style error handling). I'm wondering if we should be providing a panic hook similar to `human-panic` or more strongly recommending the "expect as precondition" style of expect message.
Extend ptr::null and null_mut to all thin (including extern) types
Fixes https://github.com/rust-lang/rust/issues/93959
This change was accepted in https://rust-lang.github.io/rfcs/2580-ptr-meta.html
Note that this changes the signature of **stable** functions. The change should be backward-compatible, but it is **insta-stable** since it cannot (easily, at all?) be made available only through a `#![feature(…)]` opt-in.
The RFC also proposed the same change for `NonNull::dangling`, which makes sense it terms of its signature but not in terms of its implementation. `dangling` uses `align_of()` as an address. But what `align_of()` should be for extern types or whether it should be allowed at all remains an open question.
This commit depends on https://github.com/rust-lang/rust/pull/93977, which is not yet part of the bootstrap compiler. So `#[cfg]` is used to only apply the change in stage 1+. As far a I know bounds cannot be made conditional with `#[cfg]`, so the entire functions are duplicated. This is unfortunate but temporary.
Since this duplication makes it less obvious in the diff, the new definitions differ in:
* More permissive bounds (`Thin` instead of implied `Sized`)
* Different implementation
* Having `rustc_allow_const_fn_unstable(const_fn_trait_bound)`
* Having `rustc_allow_const_fn_unstable(ptr_metadata)`
[RFC 2011] Library code
CC https://github.com/rust-lang/rust/pull/96496
Based on https://github.com/dtolnay/case-studies/tree/master/autoref-specialization.
Basically creates two traits with the same method name. One trait is generic over any `T` and the other is specialized to any `T: Printable`.
The compiler will then call the corresponding trait method through auto reference.
```rust
fn main() {
let mut a = Capture::new();
let mut b = Capture::new();
(&Wrapper(&1i32)).try_capture(&mut a); // `try_capture` from `TryCapturePrintable`
(&Wrapper(&vec![1i32])).try_capture(&mut b); // `try_capture` from `TryCaptureGeneric`
assert_eq!(format!("{:?}", a), "1");
assert_eq!(format!("{:?}", b), "N/A");
}
```
r? `@scottmcm`
Change orderings of `Debug` for the Atomic types to `Relaxed`.
This reduces synchronization between threads when debugging the atomic types. Reducing the synchronization means that executions with and without the debug calls will be more consistent, making it easier to debug.
We discussed this on the Rust Community Discord with `@ibraheemdev` before.
explain how to turn integers into fn ptrs
(with an intermediate raw ptr, not a direct transmute)
Direct int2ptr transmute, under the semantics I am imagining, will produce a ptr with "invalid" provenance that is invalid to deref or call. We cannot give it the same semantics as int2ptr casts since those do [something complicated](https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html).
To my great surprise, that is already what the example in the `transmute` docs does. :) I still added a comment to say that that part is important, and I added a section explicitly talking about this to the `fn()` type docs.
With https://github.com/rust-lang/miri/pull/2151, Miri will start complaining about direct int-to-fnptr transmutes (in the sense that it is UB to call the resulting pointer).
Document rounding for floating-point primitive operations and string parsing
The docs for floating point don't have much to say at present about either the precision of their results or rounding behaviour.
As I understand it[^1][^2], Rust doesn't support operating with non-default rounding directions, so we need only describe roundTiesToEven.
[^1]: https://github.com/rust-lang/rust/issues/41753#issuecomment-299322887
[^2]: https://github.com/llvm/llvm-project/issues/8472#issuecomment-980888781
This PR makes a start by documenting that for primitive operations and `from_str()`.
Clarify slice and Vec iteration order
While already being inferable from the doc examples, it wasn't fully specified. This is the only logical way to do a slice iterator, so I think this should be uncontroversial. It also improves the `Vec::into_iter` example to better show the order and that the iterator returns owned values.
Change `NonNull::as_uninit_*` to take self by value (as opposed to reference), matching primitive pointers.
Copied from my comment on [#75402](https://github.com/rust-lang/rust/issues/75402#issuecomment-1100496823):
> I noticed that `as_uninit_*` on pointers take `self` by value (and pointers are `Copy`), e.g. see [`as_uninit_mut`](https://doc.rust-lang.org/core/primitive.pointer.html#method.as_uninit_mut).
>
> However, on `NonNull`, these functions take `self` by reference, e.g. see the function with the same name by for `NonNull`: [`as_uninit_mut`](https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_uninit_mut) takes `self` by mutable reference. Even more inconsistent, [`as_uninit_slice_mut`](https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_uninit_slice_mut) returns a mutable reference, but takes `self` by immutable reference.
>
> I think these methods should take `self` by value for consistency. The returned lifetime is unbounded anyways and not tied to the pointer/NonNull value anyways
I realized the change is trivial (if desired) so here I am creating my first PR. I think it's not a breaking change since (it's on nightly and) `NonNull` is `Copy`; all previous usages of these methods taking `self` by reference should continue to compile. However, it might cause warnings to appear on usages of `NonNull::as_uninit_mut`, which used to require the the `NonNull` variable be declared `mut`, but now it's not necessary.
Fix `Display` for `cell::{Ref,RefMut}`
These guards changed to pointers in #97027, but their `Display` was
formatting that field directly, which made it show the raw pointer
value. Now we go through `Deref` to display the real value again.
Miri noticed this change, #97204, so hopefully that will be fixed.
Stabilize `array_from_fn`
## Overall
Stabilizes `core::array::from_fn` ~~and `core::array::try_from_fn`~~ to allow the creation of custom infallible ~~and fallible~~ arrays.
Signature proposed for stabilization here, tweaked as requested in the meeting:
```rust
// in core::array
pub fn from_fn<T, const N: usize, F>(_: F) -> [T; N];
```
Examples in https://doc.rust-lang.org/nightly/std/array/fn.from_fn.html
## History
* On 2020-08-17, implementation was [proposed](https://github.com/rust-lang/rust/pull/75644).
* On 2021-09-29, tracking issue was [created](https://github.com/rust-lang/rust/issues/89379).
* On 2021-10-09, the proposed implementation was [merged](bc8ad24020).
* On 2021-12-03, the return type of `try_from_fn` was [changed](https://github.com/rust-lang/rust/pull/91286#issuecomment-985513407).
## Considerations
* It is being assumed that indices are useful and shouldn't be removed from the callbacks
* The fact that `try_from_fn` returns an unstable type `R: Try` does not prevent stabilization. Although I'm honestly not sure about it.
* The addition or not of repeat-like variants is orthogonal to this PR.
These considerations are not ways of saying what is better or what is worse. In reality, they are an attempt to move things forward, anything really.
cc https://github.com/rust-lang/rust/issues/89379
Implement Copy, Clone, PartialEq and Eq for core::fmt::Alignment
Alignment is a fieldless exhaustive enum, so it is already possible to
clone and compare it by matching, but it is inconvenient to do so. For
example, if one would like to create a struct describing a formatter
configuration and provide a clone implementation:
```rust
pub struct Format {
fill: char,
width: Option<usize>,
align: fmt::Alignment,
}
impl Clone for Format {
fn clone(&self) -> Self {
Format {
align: match self.align {
fmt::Alignment::Left => fmt::Alignment::Left,
fmt::Alignment::Right => fmt::Alignment::Right,
fmt::Alignment::Center => fmt::Alignment::Center,
},
.. *self
}
}
}
```
Derive Copy, Clone, PartialEq, and Eq for Alignment for convenience.
make ptr::invalid not the same as a regular int2ptr cast
In Miri, we would like to distinguish `ptr::invalid` from `ptr::from_exposed_provenance`, so that we can provide better diagnostics issues like https://github.com/rust-lang/miri/issues/2134, and so that we can detect the UB in programs like
```rust
fn main() {
let x = 0u8;
let original_ptr = &x as *const u8;
let addr = original_ptr.expose_addr();
let new_ptr: *const u8 = core::ptr::invalid(addr);
unsafe {
dbg!(*new_ptr);
}
}
```
To achieve that, the two functions need to have different implementations. Currently, both are just `as` casts. We *could* add an intrinsic for this, but it turns out `transmute` already has the right behavior, at least as far as Miri is concerned. So I propose we just use that.
Cc `@Gankra`
Add implicit call to from_str via parse in documentation
The documentation mentions "FromStr’s from_str method is often used implicitly,
through str’s parse method. See parse’s documentation for examples.".
It may be nicer to show that in the code example as well.
These guards changed to pointers in #97027, but their `Display` was
formatting that field directly, which made it show the raw pointer
value. Now we go through `Deref` to display the real value again.
Say "last" instead of "rightmost" in the documentation for `std::str:rfind`
In the documentation comment for `std::str::rfind`, say "last" instead
of "rightmost" to describe the match that `rfind` finds. This follows the
spirit of #30459, for which `trim_left` and `trim_right` were replaced by
`trim_start` and `trim_end` to be more clear about how they work on
text which is displayed right-to-left.
Use pointers in `cell::{Ref,RefMut}` to avoid `noalias`
When `Ref` and `RefMut` were based on references, they would get LLVM `noalias` attributes that were incorrect, because that alias guarantee is only true until the guard drops. A `&RefCell` on the same value can get a new borrow that aliases the previous guard, possibly leading to miscompilation. Using `NonNull` pointers in `Ref` and `RefCell` avoids `noalias`.
Fixes the library side of #63787, but we still might want to explore language solutions there.
In the documentation comment for `std::str::rfind`, say "last" instead
of "rightmost" to describe the match that `rfind` finds. This follows the
spirit of #30459, for which `trim_left` and `trim_right` were replaced by
`trim_start` and `trim_end` to be more clear about how they work on
text which is displayed right-to-left.
The documentation mentions "FromStr’s from_str method is often used implicitly,
through str’s parse method. See parse’s documentation for examples.".
It may be nicer to show that in the code example as well.