offset: allow zero-byte offset on arbitrary pointers
As per prior `@rust-lang/opsem` [discussion](https://github.com/rust-lang/opsem-team/issues/10) and [FCP](https://github.com/rust-lang/unsafe-code-guidelines/issues/472#issuecomment-1793409130):
- Zero-sized reads and writes are allowed on all sufficiently aligned pointers, including the null pointer
- Inbounds-offset-by-zero is allowed on all pointers, including the null pointer
- `offset_from` on two pointers derived from the same allocation is always allowed when they have the same address
This removes surprising UB (in particular, even C++ allows "nullptr + 0", which we currently disallow), and it brings us one step closer to an important theoretical property for our semantics ("provenance monotonicity": if operations are valid on bytes without provenance, then adding provenance can't make them invalid).
The minimum LLVM we require (v17) includes https://reviews.llvm.org/D154051, so we can finally implement this.
The `offset_from` change is needed to maintain the equivalence with `offset`: if `let ptr2 = ptr1.offset(N)` is well-defined, then `ptr2.offset_from(ptr1)` should be well-defined and return N. Now consider the case where N is 0 and `ptr1` dangles: we want to still allow offset_from here.
I think we should change offset_from further, but that's a separate discussion.
Fixes https://github.com/rust-lang/rust/issues/65108
[Tracking issue](https://github.com/rust-lang/rust/issues/117945) | [T-lang summary](https://github.com/rust-lang/rust/pull/117329#issuecomment-1951981106)
Cc `@nikic`
Add opt-for-size core lib feature flag
Adds a feature flag to the core library that enables the possibility to have smaller implementations for certain algorithms.
So far, the core lib has traded performance for binary size. This is likely what most people want since they have big simd-capable machines. However, people on small machines, like embedded devices, don't enjoy the potential speedup of the bigger algorithms, but do have to pay for them. These microcontrollers often only have 16-1024kB of flash memory.
This PR is the result of some talks with project members like `@Amanieu` at RustNL.
There are some open questions of how this is eventually stabilized, but it's a similar question as with the existing `panic_immediate_abort` feature.
Speaking as someone from the embedded side, we'd rather have this unstable for a while as opposed to not having it at all. In the meantime we can try to use it and also add additional PRs to the core lib that uses the feature flag in areas where we find benefit.
Open questions from my side:
- Is this a good feature name?
- `panic_immediate_abort` is fairly verbose, so I went with something equally verbose
- It's easy to refactor later
- I've added the feature to `std` and `alloc` as well as they might benefit too. Do we agree?
- I expect these to get less usage out of the flag since most size-constraint projects don't use these libraries often.
Instead of having a single loop that works on utf-8 `char`s,
this splits the implementation into a loop that quickly skips over
printable ASCII, falling back to per-char iteration for other chunks.
Instead of writing each `char` of an escape sequence one by one,
this delegates to `Display`, which uses `write_str` internally
in order to write the whole escape sequence at once.
Re-add `From<f16> for f64`
This impl was originally added in #122470 before being removed in #123830 due to #123831. However, the issue only affects `f32` (which currently only has one `From<{float}>` impl, `From<f32>`) as `f64` already has two `From<{float}>` impls (`From<f32>` and `From<f64>`) and is also the float literal fallback type anyway. Therefore it is safe to re-add `From<f16> for f64`.
This PR also updates the FIXME link to point to the open issue #123831 rather than the closed issue #123824.
Tracking issue: #116909
`@rustbot` label +F-f16_and_f128 +T-libs-api
Refactor examples and enhance documentation in result.rs
- Replaced `map` with `map_err` in the error handling example for correctness
- Reordered example code to improve readability and logical flow
- Added assertions to examples to demonstrate expected outcomes
Invert comparison in `uN::checked_sub`
After #124114, LLVM no longer combines the comparison and subtraction in `uN::checked_sub` when either operand is a constant (demo: https://rust.godbolt.org/z/MaeoYbsP1). The difference is more pronounced when the expression is slightly more complex (https://rust.godbolt.org/z/4rPavsYdc).
This is due to the use of `>=` here:
ee97564e3a/library/core/src/num/uint_macros.rs (L581-L593)
For constant `C`, LLVM eagerly converts `a >= C` into `a > C - 1`, but the backend can only combine `a < C` with `a - C`, not `C - 1 < a` and `a - C`: e586556e37/llvm/lib/CodeGen/CodeGenPrepare.cpp (L1697-L1742)
This PR[^1] simply inverts the `>=` into `<` to restore the LLVM magic, and somewhat align this with the implementation of `uN::overflowing_sub` from #103299.
When the result is stored as an `Option` (rather than being branched/cmoved on), the discriminant is `self >= rhs`. This PR doesn't affect the codegen (and relevant tests) of that since LLVM will negate `self < rhs` to `self >= rhs` when necessary.
[^1]: Note to `self`: My very first contribution to publicly-used code. Hopefully like what I should learn to always be, tiny and humble.
Many, many projects use `size_of` to get the size of a type. However,
it's also often equally easy to hardcode a size (e.g. `8` instead of
`size_of::<u64>()`). Minimizing friction in the use of `size_of` helps
ensure that people use it and make code more self-documenting.
The name `size_of` is unambiguous: the name alone, without any prefix or
path, is self-explanatory and unmistakeable for any other functionality.
Adding it to the prelude cannot produce any name conflicts, as any local
definition will silently shadow the one from the prelude. Thus, we don't
need to wait for a new edition prelude to add it.
Add `size_of_val`, `align_of`, and `align_of_val` as well, with similar
justification: widely useful, self-explanatory, unmistakeable for
anything else, won't produce conflicts.
Document proper usage of `fmt::Error` and `fmt()`'s `Result`.
I've seen several newcomers wonder why `fmt::Error` doesn't have any error detail information, or propose to return it in response to an error condition found inside a `impl fmt::Display for MyType`.
That is incorrect, per [a lone paragraph of the `fmt` module's documentation](https://doc.rust-lang.org/1.78.0/std/fmt/index.html#formatting-traits). However, users looking to implement a formatting trait won't necessarily look there. Therefore, let's add the critical information (that formatting per se is infallible) to all the involved items: every `fmt()` method, and `fmt::Error`.
This PR is not intended to make any novel claims about `fmt`; only to repeat an existing one in places where it will be more visible.
Remove feature from documentation examples
Add rustc_const_stable attribute to stabilized functions
Update intra-doc link for `u8::is_ascii_whitespace` on `&[u8]` functions
from_str_radix: outline only the panic function
In the `{integer}::from_str_radix` function, the radix check is labeled as `cold` and `inline(never)`, along with its corresponding panic. It probably was intended to apply these attributes only to the panic function.
Add benchmarks for `impl Debug for str`
In order to inform future perf improvements and prevent regressions, lets add some benchmarks that stress `impl Debug for str`.
---
As I am currently working on improving the perf in https://github.com/rust-lang/rust/pull/121150, its nice to have these benchmarks.
Writing them, I also saw that escapes are written out one char at a time, even though other parts of the code are already optimizing that via `as_str`, which I intend to do as well as a followup improvement.
r? ``@cuviper``
☝🏻 as you were also assigned to https://github.com/rust-lang/rust/pull/121150, CC ``@the8472`` if you want to steal the review :-)
Documentation of these properties previously existed in a lone paragraph
in the `fmt` module's documentation:
<https://doc.rust-lang.org/1.78.0/std/fmt/index.html#formatting-traits>
However, users looking to implement a formatting trait won't necessarily
look there. Therefore, let's add the critical information (that
formatting per se is infallible) to all the involved items.
Implement `as_chunks` with `split_at_unchecked`
We were discussing various ways to do [this on Discord](https://discord.com/channels/273534239310479360/273541522815713281/1236946363120619521), and in the process I noticed that <https://rust.godbolt.org/z/1P16P37Go> is emitting a panic path inside `as_chunks`. It optimizes out in release, but we could just not do that in the first place.
We're already doing unsafe code that depends on this value being calculated correctly, so might as well call `split_at_unchecked` instead of `split_at`.
Rollup of 8 pull requests
Successful merges:
- #123344 (Remove braces when fixing a nested use tree into a single item)
- #124587 (Generic `NonZero` post-stabilization changes.)
- #124775 (crashes: add lastest batch of crash tests)
- #124869 (Make sure we don't deny macro vars w keyword names)
- #124876 (Simplify `use crate::rustc_foo::bar` occurrences.)
- #124892 (Update cc crate to v1.0.97)
- #124903 (Ignore empty RUSTC_WRAPPER in bootstrap)
- #124909 (Reapply the part of #124548 that bors forgot)
r? `@ghost`
`@rustbot` modify labels: rollup
Avoid a cast in `ptr::slice_from_raw_parts(_mut)`
Casting to `*const ()` or `*mut ()` is no longer needed after https://github.com/rust-lang/rust/pull/123840 so let's make the MIR smaller (and more inline-able, as seen in the tests).
If [ACP#362](https://github.com/rust-lang/libs-team/issues/362) goes through we can keep calling `ptr::from_raw_parts(_mut)` in these also without the cast, but that hasn't had any libs-api attention yet, so I'm not waiting on it.
Correct the const stabilization of `last_chunk` for slices
`<[T]>::last_chunk` should have become const stable as part of <https://github.com/rust-lang/rust/pull/117561>. Update the const stability gate to reflect this.
Add constants for f16 and f128
- Commit 1 adds associated constants for `f16`, excluding NaN and infinities as these are implemented using arithmetic for `f32` and `f64`.
- Commit 2 adds associated constants for `f128`, excluding NaN and infinities.
- Commit 3 adds constants in `std::f16::consts`.
- Commit 4 adds constants in `std::f128::consts`.
Casting to `*const ()` or `*mut ()` just bloats the MIR, so let's not.
If ACP#362 goes through we can keep calling `ptr::from_raw_parts(_mut)` in these also without the cast, but that hasn't had any libs-api attention yet, so I'm not waiting on it.
Document That `f16` And `f128` Hardware Support is Limited (v2)
This PR is identical to #123892, which was approved and merged but then removed from master by a force-push due to a [CI bug](https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/ci.20broken.3F).
r? ghost
Original PR description:
---
This adds a small paragraph to the recently added f16 and f128 types explaining that hardware support may be limited, and that performance may suffer as a result of that.
I mainly wrote this because I felt it may be useful to express in some form; as a launchpoint for readers of the documentation if they have issues with performance.
I tried to word the documentation in a way that doesn't create false assumptions (that f16/f128 is too slow to use, for instance), removing the software implementation part could mislead people to thinking that f16/f128 is only available on some platforms, not all, so I believe it is important to keep in.\
"not all *major* platforms" is specifically said so as to not be redundant, because not all platforms implement many things, but the average rustacean is probably going to be using x86_64 or aarch64 derived ISA's, which is who this documentation is targeted towards.
I'm not sure of the best way to word the documentation, or if it should even be added, but I feel like it may be useful to have (potentially in a reworded way, I'm not very confident in the current wording and cannot decide if that is because it is too vague to be useful or too specific to be generally correct).
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
Update library/core/src/primitive_docs.rs
Remove orphaned doc link and clean up grammar a bit
Update library/core/src/primitive_docs.rs
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
Update library/core/src/primitive_docs.rs
Rewrite f16 and f128 hw support comments to match PR feedback
I wrote RISC-V allcaps in all cases, and wrote amd64 lowercase in all
cases, im not sure if either is the more correct way for either
platform, thats just how I normally write them, if theres a precedent
elsewhere it should probably be changed to match though.
Update library/core/src/primitive_docs.rs
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
Update library/core/src/primitive_docs.rs
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
Update library/core/src/primitive_docs.rs
Use `unchecked_sub` in `split_at`
LLVM currently isn't figuring it out on its own, even in the checked version where it hypothetically could.
Before: <https://rust.godbolt.org/z/PEY38YrKs>
```llvm
bb1: ; preds = %start
%4 = getelementptr inbounds float, ptr %x.0, i64 %n
%5 = sub i64 %x.1, %n
```
After:
```llvm
bb1: ; preds = %start
%4 = getelementptr inbounds float, ptr %x.0, i64 %n
%5 = sub nuw i64 %x.1, %n
```
This is not using the wrapper because there's already a ubcheck covering it, so I don't want this to get a second one once #121571 lands.
---
This is basically the same as #108763, since `split_at` is essentially doing two `get_unchecked`s.
Docs: suggest `uN::checked_sub` instead of check-then-unchecked
As of #124114 it's exactly the same in codegen, so might as well not use `unsafe`.
Note that this is only for *unsigned*, since the overflow conditions for `iN::checked_sub` are more complicated.
Remove an unnecessary cast
Very minor thing, obviously, but I randomly saw this unnecessary cast showing up in the UbChecks, so might as well get rid of it.
As of 124114 it's exactly the same in codegen, so might as well not use `unsafe`.
Note that this is only for *unsigned*, since the overflow conditions for `iN::checked_sub` are more complicated.
Stabilize `split_at_checked`
Closes#119128
For the const version of `slice::split_at_mut_checked`, I'm reusing the `const_slice_split_at_mut` feature flag (#101804). I don't if it okay to reuse tracking issues or if it preferred to create new ones...
Describe and use CStr literals in CStr and CString docs
Mention CStr literals in the description of both types, and use them in some of the code samples for CStr. This is intended to make C string literals more discoverable.
Additionally, I don't think the orange "This example is not tested" warnings are very encouraging, so I have made the examples on `CStr` build.
Implement ptr_as_ref_unchecked
Implementation of #122034.
Prefixed the feature name with `ptr_` for clarity.
Linked const-unstability to #91822, so the post there should probably be updated to mentions the 3 new methods when/if this PR is merged.
deref patterns: impl `DerefPure` for more std types
Context: [deref patterns](https://github.com/rust-lang/rust/issues/87121). The requirements of `DerefPure` aren't precise yet, but these types unambiguously satisfy them.
Interestingly, a hypothetical `impl DerefMut for Cow` that does a `Clone` would *not* be eligible for `DerefPure` if we allow mixing deref patterns with normal patterns. If the following is exhaustive then the `DerefMut` would cause UB:
```rust
match &mut Cow::Borrowed(&()) {
Cow::Owned(_) => ..., // Doesn't match
deref!(_x) if false => ..., // Causes the variant to switch to `Owned`
Cow::Borrowed(_) => ..., // Doesn't match
// We reach unreachable
}
```
Document never type fallback in `!`'s docs
Pulled the documentation I've written for #123939.
I want a single place where never type fallback is explained, which can be referred in all the lints and migration materials.
Use `target_vendor = "apple"` instead of `target_os = "..."`
Use `target_vendor = "apple"` instead of `all(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos")`.
The apple targets are quite close to being identical, with iOS, tvOS, watchOS and visionOS being even closer, so using `target_vendor` when possible makes it clearer when something is actually OS-specific, or just Apple-specific.
Note that `target_vendor` will [be deprecated in the future](https://github.com/rust-lang/rust/issues/100343), but not before an alternative (like `target_family = "apple"`) is available.
While doing this, I found various inconsistencies and small mistakes in the standard library, see the commits for details. Will follow-up with an extra PR for a similar issue that need a bit more discussion. EDIT: https://github.com/rust-lang/rust/pull/124494
Since you've talked about using `target_vendor = "apple"` in the past:
r? workingjubilee
CC `@simlay,` `@thomcc`
`@rustbot` label O-macos O-ios O-tvos O-watchos O-visionos
Fix#124478 - offset_of! returns a temporary
This was due to the must_use() call. Adding HIR's `OffsetOf` to the must_use checking within the compiler avoids this issue while maintaining the lint output.
Fixes#124478. `@tgross35`
Update `is_val_statically_known` Docs
* Add `Type Requirements` section, listing the allowed inputs, as requested by #121115
* Add `Pointers` subsection, explaining is_val_statically_known handles pointers.
* Add `Stability concerns` section, referring to other documentation relating to consistency in `const` functions.
Fixes#121115
Sorry this took so long.
Abort a process when FD ownership is violated
When an owned FD has already been closed before it's dropped that means something else touched an FD in ways it is not allowed to. At that point things can already be arbitrarily bad, e.g. clobbered mmaps. Recovery is not possible.
All we can do is hasten the fire.
Unlike the previous attempt in #124130 this shouldn't suffer from the possibility that FUSE filesystems can return arbitrary errors.
Convert some iter macros to normal functions
With all the MIR optimization changes that have happened since these were written, let's see if they still actually matter.
\*perf comes back\*
Well, it looks like it's not longer relevant for instruction, cycle, nor wall-time perf. Looks like a bunch of things are maybe 10kb bigger in debug, but some are also 50k *smaller* in debug.
So I think they should switch to being normal functions as the "greatly improves performance" justification for them being macros seems to no longer be true -- probably thanks to us always building `core` with `-Z inline-mir` so the difference is negligible.
Add diagnostic item for `std::iter::Enumerate`
This adds a diagnostic item for `std::iter::Enumerate`. The change will be used by the clippy `unused_enumerate_index` lint to move away from type paths to using diagnostic items.
see: https://github.com/rust-lang/rust-clippy/issues/5393
Rollup of 3 pull requests
Successful merges:
- #124003 (Dellvmize some intrinsics (use `u32` instead of `Self` in some integer intrinsics))
- #124169 (Don't fatal when calling `expect_one_of` when recovering arg in `parse_seq`)
- #124286 (Subtree sync for rustc_codegen_cranelift)
r? `@ghost`
`@rustbot` modify labels: rollup
Dellvmize some intrinsics (use `u32` instead of `Self` in some integer intrinsics)
This implements https://github.com/rust-lang/compiler-team/issues/693 minus what was implemented in #123226.
Note: I decided to _not_ change `shl`/... builder methods, as it just doesn't seem worth it.
r? ``@scottmcm``
alloc::Layout: explicitly document size invariant on the type level
https://github.com/rust-lang/rust/pull/95295 added this to the constructor, but it seems worth documenting the type invariant at the type level.
panic_str only exists for the migration to 2021 panic macros
The only caller is `expect_failed`, which is already a cold inline(never) function, so inlining into that function should be fine. (And indeed `panic_str` was `#[inline]` anyway.)
The existence of panic_str risks someone calling it when they should call `panic` instead, and I can't see a reason why this footgun should exist.
I also extended the comment in `panic` to explain why it needs a `'static` string -- I know I've wondered about this in the past and it took me quite a while to understand.
Add simple async drop glue generation
This is a prototype of the async drop glue generation for some simple types. Async drop glue is intended to behave very similar to the regular drop glue except for being asynchronous. Currently it does not execute synchronous drops but only calls user implementations of `AsyncDrop::async_drop` associative function and awaits the returned future. It is not complete as it only recurses into arrays, slices, tuples, and structs and does not have same sensible restrictions as the old `Drop` trait implementation like having the same bounds as the type definition, while code assumes their existence (requires a future work).
This current design uses a workaround as it does not create any custom async destructor state machine types for ADTs, but instead uses types defined in the std library called future combinators (deferred_async_drop, chain, ready_unit).
Also I recommend reading my [explainer](https://zetanumbers.github.io/book/async-drop-design.html).
This is a part of the [MCP: Low level components for async drop](https://github.com/rust-lang/compiler-team/issues/727) work.
Feature completeness:
- [x] `AsyncDrop` trait
- [ ] `async_drop_in_place_raw`/async drop glue generation support for
- [x] Trivially destructible types (integers, bools, floats, string slices, pointers, references, etc.)
- [x] Arrays and slices (array pointer is unsized into slice pointer)
- [x] ADTs (enums, structs, unions)
- [x] tuple-like types (tuples, closures)
- [ ] Dynamic types (`dyn Trait`, see explainer's [proposed design](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#async-drop-glue-for-dyn-trait))
- [ ] coroutines (https://github.com/rust-lang/rust/pull/123948)
- [x] Async drop glue includes sync drop glue code
- [x] Cleanup branch generation for `async_drop_in_place_raw`
- [ ] Union rejects non-trivially async destructible fields
- [ ] `AsyncDrop` implementation requires same bounds as type definition
- [ ] Skip trivially destructible fields (optimization)
- [ ] New [`TyKind::AdtAsyncDestructor`](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#adt-async-destructor-types) and get rid of combinators
- [ ] [Synchronously undroppable types](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#exclusively-async-drop)
- [ ] Automatic async drop at the end of the scope in async context
checked_ilog: improve performance
Addresses #115874.
(This PR replicates the original #115875, which I accidentally closed by deleting my forked repository...)