| Age | Commit message (Collapse) | Author | Lines |
|
Stabilize `const_float_classify`
Tracking issue: https://github.com/rust-lang/rust/issues/72505
Also reverts https://github.com/rust-lang/rust/pull/114486
Closes https://github.com/rust-lang/rust/issues/72505
Stabilized const API:
```rust
impl f32 {
pub const fn is_nan(self) -> bool;
pub const fn is_infinite(self) -> bool;
pub const fn is_finite(self) -> bool;
pub const fn is_subnormal(self) -> bool;
pub const fn is_normal(self) -> bool;
pub const fn classify(self) -> FpCategory;
pub const fn is_sign_positive(self) -> bool;
pub const fn is_sign_negative(self) -> bool;
}
impl f64 {
pub const fn is_nan(self) -> bool;
pub const fn is_infinite(self) -> bool;
pub const fn is_finite(self) -> bool;
pub const fn is_subnormal(self) -> bool;
pub const fn is_normal(self) -> bool;
pub const fn classify(self) -> FpCategory;
pub const fn is_sign_positive(self) -> bool;
pub const fn is_sign_negative(self) -> bool;
}
```
cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
|
|
|
|
Const-stabilizes:
- `slice::first_mut`
- `slice::split_first_mut`
- `slice::last_mut`
- `slice::split_last_mut`
|
|
Const-stabilizes:
- `UnsafeCell::get_mut`
|
|
Const-stabilizes:
- `NonNull::as_mut`
|
|
Const-stabilizes:
- `str::as_bytes_mut`
- `str::as_mut_ptr`
|
|
Const-stabilizes:
- `str::from_utf8_unchecked_mut`
|
|
Add `[Option<T>; N]::transpose`
This PR as a new unstable libs API, `[Option<T>; N]::transpose`, which permits going from `[Option<T>; N]` to `Option<[T; N]>`.
This new API doesn't have an ACP as it was directly asked by T-libs-api in https://github.com/rust-lang/rust/issues/97601#issuecomment-2372109119:
> [..] but it'd be trivial to provide a helper method `.transpose()` that turns array-of-Option into Option-of-array (**and we think that method should exist**; it already does for array-of-MaybeUninit).
r? libs
|
|
Small optimization for integers Display implementation
This is a first pass to try to speed up a bit integers `Display` implementation. The idea behind this is to reduce the stack usage for the buffer storing the output (shouldn't be visible in bench normally) and some small specialization which benefits a lot to smaller integers like `u8` and `i8`.
Here are the results of the benchmarks:
| bench name | current std | with this PR |
|-|-|-|
| bench_std_fmt::bench_i16_0 | 16.45 ns/iter (+/- 0.25) | 16.50 ns/iter (+/- 0.15) |
| bench_std_fmt::bench_i16_max | 17.83 ns/iter (+/- 0.66) | 17.58 ns/iter (+/- 0.10) |
| bench_std_fmt::bench_i16_min | 20.97 ns/iter (+/- 0.49) | 20.50 ns/iter (+/- 0.28) |
| bench_std_fmt::bench_i32_0 | 16.63 ns/iter (+/- 0.06) | 16.62 ns/iter (+/- 0.07) |
| bench_std_fmt::bench_i32_max | 19.79 ns/iter (+/- 0.43) | 19.55 ns/iter (+/- 0.14) |
| bench_std_fmt::bench_i32_min | 22.97 ns/iter (+/- 0.50) | 22.08 ns/iter (+/- 0.08) |
| bench_std_fmt::bench_i64_0 | 16.63 ns/iter (+/- 0.39) | 16.69 ns/iter (+/- 0.44) |
| bench_std_fmt::bench_i64_half | 19.60 ns/iter (+/- 0.05) | 19.10 ns/iter (+/- 0.05) |
| bench_std_fmt::bench_i64_max | 25.22 ns/iter (+/- 0.34) | 24.43 ns/iter (+/- 0.02) |
| bench_std_fmt::bench_i8_0 | 16.27 ns/iter (+/- 0.32) | 15.80 ns/iter (+/- 0.17) |
| bench_std_fmt::bench_i8_max | 16.71 ns/iter (+/- 0.09) | 16.25 ns/iter (+/- 0.01) |
| bench_std_fmt::bench_i8_min | 20.07 ns/iter (+/- 0.22) | 19.80 ns/iter (+/- 0.30) |
| bench_std_fmt::bench_u128_0 | 21.37 ns/iter (+/- 0.24) | 21.35 ns/iter (+/- 0.35) |
| bench_std_fmt::bench_u128_max | 48.13 ns/iter (+/- 0.20) | 48.78 ns/iter (+/- 0.29) |
| bench_std_fmt::bench_u16_0 | 16.48 ns/iter (+/- 0.46) | 16.03 ns/iter (+/- 0.39) |
| bench_std_fmt::bench_u16_max | 17.31 ns/iter (+/- 0.32) | 17.41 ns/iter (+/- 0.32) |
| bench_std_fmt::bench_u16_min | 16.40 ns/iter (+/- 0.45) | 16.02 ns/iter (+/- 0.39) |
| bench_std_fmt::bench_u32_0 | 16.17 ns/iter (+/- 0.04) | 16.29 ns/iter (+/- 0.16) |
| bench_std_fmt::bench_u32_max | 19.00 ns/iter (+/- 0.10) | 19.16 ns/iter (+/- 0.28) |
| bench_std_fmt::bench_u32_min | 16.16 ns/iter (+/- 0.09) | 16.28 ns/iter (+/- 0.11) |
| bench_std_fmt::bench_u64_0 | 16.22 ns/iter (+/- 0.22) | 16.14 ns/iter (+/- 0.18) |
| bench_std_fmt::bench_u64_half | 19.25 ns/iter (+/- 0.07) | 18.95 ns/iter (+/- 0.05) |
| bench_std_fmt::bench_u64_max | 24.31 ns/iter (+/- 0.08) | 24.18 ns/iter (+/- 0.08) |
| bench_std_fmt::bench_u8_0 | 15.76 ns/iter (+/- 0.08) | 15.66 ns/iter (+/- 0.08) |
| bench_std_fmt::bench_u8_max | 16.53 ns/iter (+/- 0.03) | 16.29 ns/iter (+/- 0.02) |
| bench_std_fmt::bench_u8_min | 15.77 ns/iter (+/- 0.06) | 15.67 ns/iter (+/- 0.02) |
The source code is:
<details>
<summary>source code</summary>
```rust
#![feature(test)]
#![allow(non_snake_case)]
#![allow(clippy::cast_lossless)]
extern crate test;
macro_rules! benches {
($($name:ident($value:expr))*) => {
mod bench_std_fmt {
use std::io::Write;
use test::{Bencher, black_box};
$(
#[bench]
fn $name(b: &mut Bencher) {
let mut buf = Vec::with_capacity(40);
b.iter(|| {
buf.clear();
write!(&mut buf, "{}", black_box($value)).unwrap();
black_box(&buf);
});
}
)*
}
}
}
benches! {
bench_u64_0(0u64)
bench_u64_half(u32::max_value() as u64)
bench_u64_max(u64::max_value())
bench_i64_0(0i64)
bench_i64_half(i32::max_value() as i64)
bench_i64_max(i64::max_value())
bench_u16_0(0u16)
bench_u16_min(u16::min_value())
bench_u16_max(u16::max_value())
bench_i16_0(0i16)
bench_i16_min(i16::min_value())
bench_i16_max(i16::max_value())
bench_u128_0(0u128)
bench_u128_max(u128::max_value())
bench_i8_0(0i8)
bench_i8_min(i8::min_value())
bench_i8_max(i8::max_value())
bench_u8_0(0u8)
bench_u8_min(u8::min_value())
bench_u8_max(u8::max_value())
bench_u32_0(0u32)
bench_u32_min(u32::min_value())
bench_u32_max(u32::max_value())
bench_i32_0(0i32)
bench_i32_min(i32::min_value())
bench_i32_max(i32::max_value())
}
```
</details>
And then I ran the equivalent code (source code below) in callgrind with [callgrind_differ](https://github.com/Ethiraric/callgrind_differ) to generate a nice output and here's the result:
```
core::fmt::num::imp::<impl core::fmt::Display for i16>::fmt | 1300000 | - 70000 - 5.385% 1230000
core::fmt::num::imp::<impl core::fmt::Display for i32>::fmt | 1910000 | - 100000 - 5.236% 1810000
core::fmt::num::imp::<impl core::fmt::Display for i64>::fmt | 2430000 | - 110000 - 4.527% 2320000
core::fmt::num::imp::<impl core::fmt::Display for i8>::fmt | 1080000 | - 170000 - 15.741% 910000
core::fmt::num::imp::<impl core::fmt::Display for u16>::fmt | 960000 | + 10000 + 1.042% 970000
core::fmt::num::imp::<impl core::fmt::Display for u32>::fmt | 1300000 | + 30000 + 2.308% 1330000
core::fmt::num::imp::<impl core::fmt::Display for u8>::fmt | 820000 | - 30000 - 3.659% 790000
```
<details>
<summary>Source code</summary>
```rust
#![feature(test)]
extern crate test;
use std::io::{stdout, Write};
use std::io::StdoutLock;
use test::black_box;
macro_rules! benches {
($handle:ident, $buf:ident, $($name:ident($value:expr))*) => {
$(
fn $name(handle: &mut StdoutLock, buf: &mut Vec<u8>) {
for _ in 0..10000 {
buf.clear();
write!(buf, "{}", black_box($value)).unwrap();
handle.write_all(buf);
}
}
$name(&mut $handle, &mut $buf);
)*
}
}
fn main() {
let mut handle = stdout().lock();
let mut buf = Vec::with_capacity(40);
benches! {
handle, buf,
bench_u64_0(0u64)
bench_u64_half(u32::max_value() as u64)
bench_u64_max(u64::max_value())
bench_i64_0(0i64)
bench_i64_half(i32::max_value() as i64)
bench_i64_max(i64::max_value())
bench_u16_0(0u16)
bench_u16_min(u16::min_value())
bench_u16_max(u16::max_value())
bench_i16_0(0i16)
bench_i16_min(i16::min_value())
bench_i16_max(i16::max_value())
bench_u128_0(0u128)
bench_u128_max(u128::max_value())
bench_i8_0(0i8)
bench_i8_min(i8::min_value())
bench_i8_max(i8::max_value())
bench_u8_0(0u8)
bench_u8_min(u8::min_value())
bench_u8_max(u8::max_value())
bench_i32_0(0i32)
bench_i32_min(i32::min_value())
bench_i32_max(i32::max_value())
bench_u32_0(0u32)
bench_u32_min(u32::min_value())
bench_u32_max(u32::max_value())
}
}
```
</details>
The next step would be to specialize the `ToString` implementation so it doesn't go through the `Display` trait. I'm not sure if it will improve anything but I think it's worth a try.
r? `@Amanieu`
|
|
|
|
Update Unicode escapes in `/library/core/src/char/methods.rs`
`char::MAX` is inconsistent on how Unicode escapes should be formatted. This PR resolves that.
|
|
ptr::add/sub: do not claim equivalence with `offset(c as isize)`
In https://github.com/rust-lang/rust/pull/110837, the `offset` intrinsic got changed to also allow a `usize` offset parameter. The intention is that this will do an unsigned multiplication with the size, and we have UB if that overflows -- and we also have UB if the result is larger than `usize::MAX`, i.e., if a subsequent cast to `isize` would wrap. ~~The LLVM backend sets some attributes accordingly.~~
This updates the docs for `add`/`sub` to match that intent, in preparation for adjusting codegen to exploit this UB. We use this opportunity to clarify what the exact requirements are: we compute the offset using mathematical multiplication (so it's no problem to have an `isize * usize` multiplication, we just multiply integers), and the result must fit in an `isize`.
Cc `@rust-lang/opsem` `@nikic`
https://github.com/rust-lang/rust/pull/130239 updates Miri to detect this UB.
`sub` still has some cases of UB not reflected in the underlying intrinsic semantics (and Miri does not catch): when we subtract `usize::MAX`, then after casting to `isize` that's just `-1` so we end up adding one unit without noticing any UB, but actually the offset we gave does not fit in an `isize`. Miri will currently still not complain for such cases:
```rust
fn main() {
let x = &[0i32; 2];
let x = x.as_ptr();
// This should be UB, we are subtracting way too much.
unsafe { x.sub(usize::MAX).read() };
}
```
However, the LLVM IR we generate here also is UB-free. This is "just" library UB but not language UB.
Cc `@saethlin;` might be worth adding precondition checks against overflow on `offset`/`add`/`sub`?
Fixes https://github.com/rust-lang/rust/issues/130211
|
|
Fixes: https://github.com/rust-lang/rust/issues/127942
|
|
|
|
|
|
|
|
make ptr metadata functions callable from stable const fn
So far this was done with a bunch of `rustc_allow_const_fn_unstable`. But those should be the exception, not the norm. If we are confident we can expose the ptr metadata APIs *indirectly* in stable const fn, we should just mark them as `rustc_const_stable`. And we better be confident we can do that since it's already been done a while ago. ;)
In particular this marks two intrinsics as const-stable: `aggregate_raw_ptr`, `ptr_metadata`. This should be uncontroversial, they are trivial to implement in the interpreter.
Cc `@rust-lang/wg-const-eval` `@rust-lang/lang`
|
|
stabilize const_cell_into_inner
This const-stabilizes
- `UnsafeCell::into_inner`
- `Cell::into_inner`
- `RefCell::into_inner`
- `OnceCell::into_inner`
`@rust-lang/wg-const-eval` this uses `rustc_allow_const_fn_unstable(const_precise_live_drops)`, so we'd be comitting to always finding *some* way to accept this code. IMO that's fine -- what these functions do is to move out the only field of a struct, and that struct has no destructor itself. The field's destructor does not get run as it gets returned to the caller.
`@rust-lang/libs-api` this was FCP'd already [years ago](https://github.com/rust-lang/rust/issues/78729#issuecomment-811409860), except that `OnceCell::into_inner` was added to the same feature gate since then (Cc `@tgross35).` Does that mean we have to re-run the FCP? If yes, I'd honestly prefer to move `OnceCell` into its own feature gate to not risk missing the next release. (That's why it's not great to add new functions to an already FCP'd feature gate.) OTOH if this needs an FCP either way since the previous FCP was so long ago, then we might as well do it all at once.
|
|
Improve Ord docs
- Makes wording more clear and re-structures some sections that can be overwhelming for someone not already in the know.
- Adds examples of how *not* to implement Ord, inspired by various anti-patterns found in real world code.
Many of the wording changes are inspired directly by my personal experience of being confused by the `Ord` docs and seeing other people get it wrong as well, especially lately having looked at a number of `Ord` implementations as part of #128899.
Created with help by `@orlp.`
r? `@workingjubilee`
|
|
r=tgross35
restate GlobalAlloc method safety preconditions in terms of what the caller has to do for greater clarity
|
|
Rename `standalone` doctest attribute into `standalone_crate`
Following [zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/Renaming.20code.20block.20.22standalone.22.20attribute.3F) and poll results.
r? `@notriddle`
|
|
coherency
|
|
|
|
Update `catch_unwind` doc comments for `c_unwind`
Updates `catch_unwind` doc comments to indicate that catching a foreign exception _will no longer_ be UB. Instead, there are two possible behaviors, though it is not specified which one an implementation will choose.
Nominated for t-lang to confirm that they are okay with making such a promise based on t-opsem FCP, or whether they would like to be included in the FCP.
Related: https://github.com/rust-lang/rust/issues/74990, https://github.com/rust-lang/rust/issues/115285, https://github.com/rust-lang/reference/pull/1226
|
|
|
|
- UnsafeCell: mention the term "data race", and reference the data race definition
- atomic: failing RMWs are just reads, reorder and reword docs
|
|
|
|
|
|
|
|
|
|
|
|
Stabilize `option_get_or_insert_default`
Closes: https://github.com/rust-lang/rust/issues/82901.
`@rustbot` label: +T-libs-api
r? libs-api
|
|
|
|
|
|
|
|
|
|
- Makes wording more clear and re-structures some
sections that can be overwhelming for some not
already in the know.
- Adds examples of how *not* to implement Ord,
inspired by various anti-patterns found in real
world code.
|
|
update `compiler-builtins` to 0.1.126
this requires the addition of a bootstrap variant of the new `naked_asm!` macro
r? `@tgross35`
extracted from https://github.com/rust-lang/rust/pull/128651
|
|
[`cfg_match`] Generalize inputs
cc #115585
Changes the input type from `item` to `tt`, which makes the macro have the same functionality of `cfg_if`.
Also adds a test to ensure that `stmt_expr_attributes` is not triggered.
|
|
add missing FIXME(const-hack)
r? ```@scottmcm```
|
|
Utf8Chunks: add link to Utf8Chunk
It is currently surprisingly non-trivial to go from the `utf8_chunks` method to the docs of the `valid`/`invalid` methods used in the example. This should help.
|
|
Document subtleties of `ManuallyDrop`
After seeing #130140 and #130141, I figured that `ManuallyDrop` needs documentation explaining its subtleties, hence this PR.
See also https://github.com/rust-lang/unsafe-code-guidelines/issues/245
|
|
|
|
|
|
|
|
And fix the stability attribute on the `pub use` in `core::ops`.
|
|
Since the stabilization in #127679 has reached stage0, 1.82-beta, we can
start using `&raw` freely, and even the soft-deprecated `ptr::addr_of!`
and `ptr::addr_of_mut!` can stop allowing the unstable feature.
I intentionally did not change any documentation or tests, but the rest
of those macro uses are all now using `&raw const` or `&raw mut` in the
standard library.
|
|
fix some cfg logic around optimize_for_size and 16-bit targets
Fixes https://github.com/rust-lang/rust/issues/130818.
Fixes https://github.com/rust-lang/rust/issues/129910.
There are still some warnings when building on a 16bit target:
```
warning: struct `AlignedStorage` is never constructed
--> /home/r/src/rust/rustc.2/library/core/src/slice/sort/stable/mod.rs:135:8
|
135 | struct AlignedStorage<T, const N: usize> {
| ^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: associated items `new` and `as_uninit_slice_mut` are never used
--> /home/r/src/rust/rustc.2/library/core/src/slice/sort/stable/mod.rs:141:8
|
140 | impl<T, const N: usize> AlignedStorage<T, N> {
| -------------------------------------------- associated items in this implementation
141 | fn new() -> Self {
| ^^^
...
145 | fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
| ^^^^^^^^^^^^^^^^^^^
warning: function `quicksort` is never used
--> /home/r/src/rust/rustc.2/library/core/src/slice/sort/unstable/quicksort.rs:19:15
|
19 | pub(crate) fn quicksort<'a, T, F>(
| ^^^^^^^^^
warning: `core` (lib) generated 3 warnings
```
However, the cfg stuff here is sufficiently messy that I didn't want to touch more of it. I think all `feature = "optimize_for_size"` should become `any(feature = "optimize_for_size", target_pointer_width = "16")` but I am not entirely certain. Warnings are fine, Miri will just ignore them.
Cc `@Voultapher`
|
|
|
|
|