Add `FRAC_1_SQRT_2PI` constant to f16/f32/f64/f128
This adds the `FRAC_1_SQRT_2PI` to the `f16`, `f32`, `f64` and `f128` as [`1/√(2π)`](https://www.wolframalpha.com/input?i=1%2Fsqrt%282*pi%29). The rationale is that while `FRAC_1_SQRT_PI` already exists, [Gaussian calculations](https://en.wikipedia.org/wiki/Gaussian_function) for random normal distributions require a `1/(σ√(2π))` term, which could then be directly expressed e.g. as `f32::FRAC_1_SQRT_2PI / sigma`.
The actual value is approximately `1/√(2π) = 0.3989422804014326779399460599343818684758586311649346576659258296…`. Truncated/rounded forms were used for the individual types.
---
~~I did not any of the `#[unstable]` attributes since I am not aware of their implications.~~
**Edit:** I applied the stability attributes from the surrounding types according to what seemed most likely correct. I believe the `more_float_constants` feature marker is incorrectly applied, but I wasn't sure how to proceed.
Size optimize int formatting
Let's use the new feature flag!
This uses a simpler algorithm to format integers.
It is slower, but also smaller.
It also saves having to import the 200 byte rodata lookup table.
In a test of mine this saves ~300 bytes total of a cortex-m binary that does integer formatting.
For a 16KB device, that's almost 2%.
Note though that for opt-level 3 the text size actually grows by 116 bytes.
Still a win in total. I'm not sure why the generated code is bigger than the more fancy algo. Maybe the smaller algo lends itself more to inlining and duplicating?
Use inline const blocks to create arrays of `MaybeUninit`.
This PR contains 2 changes enabled by the fact that [`inline_const` is now stable](https://github.com/rust-lang/rust/pull/104087), and was split out of #125082.
1. Use inline const instead of `unsafe` to construct arrays in `MaybeUninit` examples.
Rationale: Demonstrate good practice of avoiding `unsafe` code where it is not strictly necessary.
4. Use inline const instead of `unsafe` to implement `MaybeUninit::uninit_array()`.
This is arguably giving the compiler more work to do, in exchange for eliminating just one single internal unsafe block, so it's less certain that this is good on net.
r? `@Nilstrieb`
Add `size_of` and `size_of_val` and `align_of` and `align_of_val` to the prelude
(Note: need to update the PR to add `align_of` and `align_of_val`, and remove the second commit with the myriad changes to appease the lint.)
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.
Explain differences between `{Once,Lazy}{Cell,Lock}` types
The question of "which once-ish cell-ish type should I use?" has been raised multiple times, and is especially important now that we have stabilized the `LazyCell` and `LazyLock` types. The answer for the `Lazy*` types is that you would be better off using them if you want to use what is by far the most common pattern: initialize it with a single nullary function that you would call at every `get_or_init` site. For everything else there's the `Once*` types.
"For everything else" is a somewhat weak motivation, as it only describes by negation. While contrasting them is inevitable, I feel positive motivations are more understandable. For this, I now offer a distinct example that helps explain why `OnceLock` can be useful, despite `LazyLock` existing: you can do some cool stuff with it that `LazyLock` simply can't support due to its mere definition.
The pair of `std::sync::*Lock`s are usable inside a `static`, and can serve roles in async or multithreaded (or asynchronously multithreaded) programs that `*Cell`s cannot. Because of this, they received most of my attention.
Fixes#124696Fixes#125615
Add function `core::iter::chain`
The addition of `core::iter::zip` (#82917) set a precedent for adding plain functions for iterator adaptors. Adding `chain` makes it a little easier to `chain` two iterators.
```rust
for (x, y) in chain(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().chain(ys) {}
```
There is prior art for the utility of this in [`itertools::chain`](https://docs.rs/itertools/latest/itertools/fn.chain.html).
Approved ACP https://github.com/rust-lang/libs-team/issues/154
The addition of `core::iter::zip` (#82917) set a precedent for adding
plain functions for iterator adaptors. Adding `chain` makes it a little
easier to `chain` two iterators.
```
for (x, y) in chain(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().chain(ys) {}
```
Change pedantically incorrect OnceCell/OnceLock wording
While the semantic intent of a OnceCell/OnceLock is that it can only be written to once (upon init), the fact of the matter is that both these types offer a `take(&mut self) -> Option<T>` mechanism that, when successful, resets the cell to its initial state, thereby [technically allowing it to be written to again](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=415c023a6ae1ef35f371a2d3bb1aa735)
Despite the fact that this can only happen with a mutable reference (generally only used during the construction of the OnceCell/OnceLock), it would be incorrect to say that the type itself as a whole *categorically* prevents being initialized or written to more than once (since it is possible to imagine an identical type only without the `take()` method that actually fulfills that contract).
To clarify, change "that cannot be.." to "that nominally cannot.." and add a note to OnceCell about what can be done with an `&mut Self` reference.
```@rustbot``` label +A-rustdocs
The `mir!` macro has multiple parts:
- An optional return type annotation.
- A sequence of zero or more local declarations.
- A mandatory starting anonymous basic block, which is brace-delimited.
- A sequence of zero of more additional named basic blocks.
Some `mir!` invocations use braces with a "block" style, like so:
```
mir! {
let _unit: ();
{
let non_copy = S(42);
let ptr = std::ptr::addr_of_mut!(non_copy);
// Inside `callee`, the first argument and `*ptr` are basically
// aliasing places!
Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue())
}
after_call = {
Return()
}
}
```
Some invocations use parens with a "block" style, like so:
```
mir!(
let x: [i32; 2];
let one: i32;
{
x = [42, 43];
one = 1;
x = [one, 2];
RET = Move(x);
Return()
}
)
```
And some invocations uses parens with a "tighter" style, like so:
```
mir!({
SetDiscriminant(*b, 0);
Return()
})
```
This last style is generally used for cases where just the mandatory
starting basic block is present. Its braces are placed next to the
parens.
This commit changes all `mir!` invocations to use braces with a "block"
style. Why?
- Consistency is good.
- The contents of the invocation is a block of code, so it's odd to use
parens. They are more normally used for function-like macros.
- Most importantly, the next commit will enable rustfmt for
`tests/mir-opt/`. rustfmt is more aggressive about formatting macros
that use parens than macros that use braces. Without this commit's
changes, rustfmt would break a couple of `mir!` macro invocations that
use braces within `tests/mir-opt` by inserting an extraneous comma.
E.g.:
```
mir!(type RET = (i32, bool);, { // extraneous comma after ';'
RET.0 = 1;
RET.1 = true;
Return()
})
```
Switching those `mir!` invocations to use braces avoids that problem,
resulting in this, which is nicer to read as well as being valid
syntax:
```
mir! {
type RET = (i32, bool);
{
RET.0 = 1;
RET.1 = true;
Return()
}
}
```
Implement feature `integer_sign_cast`
Tracking issue: https://github.com/rust-lang/rust/issues/125882
Since this is my first time making a library addition I wasn't sure where to place the new code relative to existing code. I decided to place it near the top where there are already some other basic bitwise manipulation functions. If there is an official guideline for the ordering of functions, please let me know.
Change f32::midpoint to upcast to f64
This has been verified by kani as a correct optimization
see: https://github.com/rust-lang/rust/issues/110840#issuecomment-1942587398
The new implementation is branchless and only differs in which NaN values are produced (if any are produced at all), which is fine to change. Aside from NaN handling, this implementation produces bitwise identical results to the original implementation.
Question: do we need a codegen test for this? I didn't add one, since the original PR #92048 didn't have any codegen tests.
This has been verified by kani as a correct optimization
see: https://github.com/rust-lang/rust/issues/110840#issuecomment-1942587398
The new implementation is branchless, and only differs in which NaN
values are produced (if any are produced at all). Which is fine to change.
Aside from NaN handling, this implementation produces bitwise identical
results to the original implementation.
The new implementation is gated on targets that have a fast 64-bit
floating point implementation in hardware, and on WASM.
Unroll first iteration of checked_ilog loop
This follows the optimization of #115913. As shown in https://github.com/rust-lang/rust/pull/115913#issuecomment-2066788006, the performance was improved in all important cases, but some regressions were introduced for the benchmarks `u32_log_random_small`, `u8_log_random` and `u8_log_random_small`.
Basically, #115913 changed the implementation from one division per iteration to one multiplication per iteration plus one division. When there are zero iterations, this is a regression from zero divisions to one division.
This PR avoids this by avoiding the division if we need zero iterations by returning `Some(0)` early. It also reduces the number of multiplications by one in all other cases.
Implement `needs_async_drop` in rustc and optimize async drop glue
This PR expands on #121801 and implements `Ty::needs_async_drop` which works almost exactly the same as `Ty::needs_drop`, which is needed for #123948.
Also made compiler's async drop code to look more like compiler's regular drop code, which enabled me to write an optimization where types which do not use `AsyncDrop` can simply forward async drop glue to `drop_in_place`. This made size of the async block from the [async_drop test](67980dd6fb/tests/ui/async-await/async-drop.rs) to decrease by 12%.
drop_in_place: weaken the claim of equivalence with drop(ptr.read())
The two are *not* semantically equivalent in all cases, so let's not be so definite about this.
Fixes https://github.com/rust-lang/rust/issues/112015
Add lang items for `AsyncFn*`, `Future`, `AsyncFnKindHelper`'s associated types
Adds lang items for `AsyncFnOnce::Output`, `AsyncFnOnce::CallOnceFuture`, `AsyncFnMut::CallRefFuture`, and uses them in the new solver. I'm mostly interested in doing this to help accelerate uplifting the new trait solver into a separate crate.
The old solver is kind of spaghetti, so I haven't moved that to use these lang items (i.e. it still uses `item_name`-based comparisons).
update: Also adds lang items for `Future::Output` and `AsyncFnKindHelper::Upvars`.
cc ``@lcnr``
This is create symmetry between the already existing TAU constant (2pi)
and the newly-introduced FRAC_1_SQRT_2PI, keeping the more common
name while increasing visibility.
rustfmt fixes
The `rmake.rs` entries in `rustfmt.toml` are causing major problems for `x fmt`. This PR removes them and does some minor related cleanups.
r? ``@GuillaumeGomez``
It's reasonable to want to, but in the current implementation this
causes multiple problems.
- All the `rmake.rs` files are formatted every time even when they
haven't changed. This is because they get whitelisted unconditionally
in the `OverrideBuilder`, before the changed files get added.
- The way `OverrideBuilder` works, if any files gets whitelisted then no
unmentioned files will get traversed. This is surprising, and means
that the `rmake.rs` entries broke the use of explicit paths to `x
fmt`, and also broke `GITHUB_ACTIONS=true git check --fmt`.
The commit removes the `rmake.rs` entries, fixes the formatting of a
couple of files that were misformatted (not previously caught due to the
`GITHUB_ACTIONS` breakage), and bans `!`-prefixed entries in
`rustfmt.toml` because they cause all these problems.