Remove option_payload_ptr; redundant to offset_of
The `option_payload_ptr` intrinsic is no longer required as `offset_of` supports traversing enums (#114208). This PR removes it in order to dogfood offset_of (as suggested at https://github.com/rust-lang/rust/issues/106655#issuecomment-1790907626). However, it will not build until those changes reach beta (which I think is within the next 8 days?) so I've opened it as a draft.
document ABI compatibility
I don't think we have any central place where we document our ABI compatibility rules, so let's create one. The `fn()` pointer type seems like a good place since ABI questions can only become relevant when invoking a function through a function pointer.
This will likely need T-lang FCP.
Guarantee representation of None in NPO
This allows users to soundly transmute zeroes into `Option` types subject to the null pointer optimization (NPO). It unblocks https://github.com/google/zerocopy/issues/293.
LLVM still has trouble re-using discriminants sometimes when rebuilding a two-variant enum, so when we have the correct variant already built, just use it.
That's simpler in LLVM *and* in MIR, so might as well: <https://rust.godbolt.org/z/KhdE8eToW>
add `#[doc(alias="flatmap")]` to `Option::and_then`
I keep forgetting that rust calls this `and_then` and trying to search for `flatmap`. `and_then`'s docs even mention "Some languages call this operation flatmap", but it doesn't show up as a result in the search at `https://doc.rust-lang.org/std/?search=flatmap`
Add #[inline] to as_deref
While working on https://github.com/rust-lang/rust/pull/109247 I found an `as_deref` call in the compiler that should have been inlined. This fixes the missing inlining (but doesn't address the perf issues I was chasing).
r? `@thomcc`
I keep forgetting that rust calls this `and_then` and trying to search for `flatmap`.
`and_then`'s docs even mention "Some languages call this operation flatmap",
but it doesn't show up as a result in the search at `https://doc.rust-lang.org/std/?search=flatmap`
This approach depends on CSE to not have any branches or selects when the guessed offset is correct -- which it always will be right now -- but to also be *sound* (just less efficient) if the layout algorithms change such that the guess is incorrect.
This adds the following functions:
* `Option<T>::as_slice(&self) -> &[T]`
* `Option<T>::as_slice_mut(&mut self) -> &[T]`
The `as_slice` and `as_slice_mut` functions benefit from an
optimization that makes them completely branch-free.
Note that the optimization's soundness hinges on the fact that either
the niche optimization makes the offset of the `Some(_)` contents zero
or the mempory layout of `Option<T>` is equal to that of
`Option<MaybeUninit<T>>`.
reword Option::as_ref and Option::map examples
The description for the examples of `Option::as_ref` and `Option::map` imply that the example is only doing type conversion, when it is actually finding the length of a string.
Changes the wording to imply that some operation is being run on the value contained in the `Option`
closes#104476
Manually implement PartialEq for Option<T> and specialize non-nullable types
This PR manually implements `PartialEq` and `StructuralPartialEq` for `Option`, which seems to produce slightly better codegen than the automatically derived implementation.
It also allows specializing on the `core::num::NonZero*` and `core::ptr::NonNull` types, taking advantage of the niche optimization by transmuting the `Option<T>` to `T` to be compared directly, which can be done in just two instructions.
A comparison of the original, new and specialized code generation is available [here](https://godbolt.org/z/dE4jxdYsa).