Commit graph

7628 commits

Author SHA1 Message Date
Matthias Krüger
b25d266bef
Rollup merge of #131850 - lexeyOK:master, r=compiler-errors
Missing parenthesis

the line was missing closing parenthesis
2024-10-18 06:59:07 +02:00
bors
d9c4b8d475 Auto merge of #131572 - cuviper:ub-index_range, r=thomcc
Avoid superfluous UB checks in `IndexRange`

`IndexRange::len` is justified as an overall invariant, and
`take_prefix` and `take_suffix` are justified by local branch
conditions. A few more UB-checked calls remain in cases that are only
supported locally by `debug_assert!`, which won't do anything in
distributed builds, so those UB checks may still be useful.

We generally expect core's `#![rustc_preserve_ub_checks]` to optimize
away in user's release builds, but the mere presence of that extra code
can sometimes inhibit optimization, as seen in #131563.
2024-10-17 22:18:24 +00:00
lexx
4ab307f9e8
Missing parenthesis
the line was missing closing parenthesis
2024-10-18 01:04:01 +05:00
Matthias Krüger
e46d52ccda
Rollup merge of #131835 - ferrocene:amanjeev/add-missing-attribute-unwind, r=Noratrieb
Do not run test where it cannot run

This was seen on Ferrocene, where we have a custom test target that does not have unwind support
2024-10-17 20:47:32 +02:00
bors
86bd45979a Auto merge of #130223 - LaihoE:faster_str_replace, r=thomcc
optimize str.replace

Adds a fast path for str.replace for the ascii to ascii case. This allows for autovectorizing the code. Also should this instead be done with specialization? This way we could remove one branch. I think it is the kind of branch that is easy to predict though.

Benchmark for the fast path (replace all "a" with "b" in the rust wikipedia article, using criterion) :
| N        | Speedup | Time New (ns) | Time Old (ns) |
|----------|---------|---------------|---------------|
| 2        | 2.03    | 13.567        | 27.576        |
| 8        | 1.73    | 17.478        | 30.259        |
| 11       | 2.46    | 18.296        | 45.055        |
| 16       | 2.71    | 17.181        | 46.526        |
| 37       | 4.43    | 18.526        | 81.997        |
| 64       | 8.54    | 18.670        | 159.470       |
| 200      | 9.82    | 29.634        | 291.010       |
| 2000     | 24.34   | 81.114        | 1974.300      |
| 20000    | 30.61   | 598.520       | 18318.000     |
| 1000000  | 29.31   | 33458.000     | 980540.000    |
2024-10-17 16:20:02 +00:00
Amanjeev Sethi
f999ab86e0 Do not run test where it cannot run
This was seen on Ferrocene, where we have a custom test target that does not have unwind support
2024-10-17 09:33:39 -04:00
bors
798fb83f7d Auto merge of #131797 - matthiaskrgr:rollup-lzpze2k, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #130989 (Don't check unsize goal in MIR validation when opaques remain)
 - #131657 (Rustfmt `for<'a> async` correctly)
 - #131691 (Delay ambiguous intra-doc link resolution after `Cache` has been populated)
 - #131730 (Refactor some `core::fmt` macros)
 - #131751 (Rename `can_coerce` to `may_coerce`, and then structurally resolve correctly in the probe)
 - #131753 (Unify `secondary_span` and `swap_secondary_and_primary` args in `note_type_err`)
 - #131776 (Emscripten: Xfail backtrace ui tests)
 - #131777 (Fix trivially_copy_pass_by_ref in stable_mir)
 - #131778 (Fix needless_lifetimes in stable_mir)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-16 20:50:53 +00:00
Matthias Krüger
82952da360
Rollup merge of #131730 - zlfn:master, r=tgross35
Refactor some `core::fmt` macros

While looking at the macros in `core::fmt`, find that the macros are not well organized. So I created a patch to fix it.

[`core/src/fmt/num.rs`](https://github.com/rust-lang/rust/blob/master/library/core/src/fmt/num.rs)
*  `impl_int!` and `impl_uint!` macro are **completly** same. It would be better to combine for readability
* `impl_int!` has a problem that the indenting is not uniform. It has unified into 4 spaces
* `debug` macro in `num` renamed to `impl_Debug`, And it was moved to a position close to the `impl_Display`.

[`core/src/fmt/float.rs`](https://github.com/rust-lang/rust/blob/master/library/core/src/fmt/float.rs)
[`core/src/fmt/nofloat.rs`](https://github.com/rust-lang/rust/blob/master/library/core/src/fmt/nofloat.rs)
* `floating` macro now receive multiple idents at once. It makes the code cleaner.
* Modified the panic message more clearly in fallback function of `cfg(no_fp_fmt_parse)`
2024-10-16 20:15:54 +02:00
bors
7342830c05 Auto merge of #131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #130822 (Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.)
 - #131381 (Implement edition 2024 match ergonomics restrictions)
 - #131594 (rustdoc: Rename "object safe" to "dyn compatible")
 - #131686 (Add fast-path when computing the default visibility)
 - #131699 (Try to improve error messages involving aliases in the solver)
 - #131757 (Ignore lint-non-snake-case-crate#proc_macro_ on targets without unwind)
 - #131783 (Fix explicit_iter_loop in rustc_serialize)
 - #131788 (Fix mismatched quotation mark)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-16 17:58:25 +00:00
Matthias Krüger
1817de609b
Rollup merge of #130822 - bjoernager:non-null-from-ref, r=dtolnay
Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.

Relevant tracking issue: #130823

The `core::ptr::NonNull` type should have the convenience constructors `from_ref` and `from_mut` for parity with `core::ptr::from_ref` and `core::ptr::from_mut`.

Although the type in question already implements `From<&T>` and `From<&mut T>`, these new functions also carry the ability to be used in constant expressions (due to not being behind a trait).
2024-10-16 19:18:30 +02:00
bors
bed75e7c21 Auto merge of #131767 - cuviper:bump-stage0, r=Mark-Simulacrum
Bump bootstrap compiler to 1.83.0-beta.1

https://forge.rust-lang.org/release/process.html#master-bootstrap-update-tuesday
2024-10-16 14:40:08 +00:00
Urgau
f7af3aa7dc
Rollup merge of #131712 - tgross35:const-lazy_cell_into_inner, r=joboet
Mark the unstable LazyCell::into_inner const

Other cell `into_inner` functions are const and there shouldn't be any problem here. Make the unstable `LazyCell::into_inner` const under the same gate as its stability (`lazy_cell_into_inner`).

Tracking issue: https://github.com/rust-lang/rust/issues/125623
2024-10-16 12:03:41 +02:00
Josh Stone
acb09bf741 update bootstrap configs 2024-10-15 20:30:23 -07:00
Josh Stone
f204e2c23b replace placeholder version
(cherry picked from commit 567fd9610c)
2024-10-15 20:13:55 -07:00
Michael Goulet
1c799ff05e
Rollup merge of #131521 - jdonszelmann:rc, r=joboet
rename RcBox to RcInner for consistency

Arc uses ArcInner too (created in collaboration with `@aDotInTheVoid` and `@WaffleLapkin` )
2024-10-15 12:33:36 -04:00
Michael Goulet
2f3f001423
Rollup merge of #130568 - eduardosm:const-float-methods, r=RalfJung,tgross35
Make some float methods unstable `const fn`

Some float methods are now `const fn` under the `const_float_methods` feature gate.

I also made some unstable methods `const fn`, keeping their constness under their respective feature gate.

In order to support `min`, `max`, `abs` and `copysign`, the implementation of some intrinsics had to be moved from Miri to rustc_const_eval (cc `@RalfJung).`

Tracking issue: https://github.com/rust-lang/rust/issues/130843

```rust
impl <float> {
    // #[feature(const_float_methods)]
    pub const fn recip(self) -> Self;
    pub const fn to_degrees(self) -> Self;
    pub const fn to_radians(self) -> Self;
    pub const fn max(self, other: Self) -> Self;
    pub const fn min(self, other: Self) -> Self;
    pub const fn clamp(self, min: Self, max: Self) -> Self;
    pub const fn abs(self) -> Self;
    pub const fn signum(self) -> Self;
    pub const fn copysign(self, sign: Self) -> Self;

    // #[feature(float_minimum_maximum)]
    pub const fn maximum(self, other: Self) -> Self;
    pub const fn minimum(self, other: Self) -> Self;

    // Only f16/f128 (f32/f64 already const)
    pub const fn is_sign_positive(self) -> bool;
    pub const fn is_sign_negative(self) -> bool;
    pub const fn next_up(self) -> Self;
    pub const fn next_down(self) -> Self;
}
```

r? libs-api

try-job: dist-s390x-linux
2024-10-15 12:33:35 -04:00
zlfn
99af761632 Refactor floating macro and nofloat panic message 2024-10-15 22:27:06 +09:00
bors
f79fae3069 Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #122670 (Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode)
 - #131095 (Use environment variables instead of command line arguments for merged doctests)
 - #131339 (Expand set_ptr_value / with_metadata_of docs)
 - #131652 (Move polarity into `PolyTraitRef` rather than storing it on the side)
 - #131675 (Update lint message for ABI not supported)
 - #131681 (Fix up-to-date checking for run-make tests)
 - #131702 (Suppress import errors for traits that couldve applied for method lookup error)
 - #131703 (Resolved python deprecation warning in publish_toolstate.py)
 - #131710 (Remove `'apostrophes'` from `rustc_parse_format`)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-15 11:50:31 +00:00
zlfn
0637517da6 Rename debug! macro to impl_Debug! 2024-10-15 18:32:21 +09:00
zlfn
918dc38733 Combine impl_int and impl_uint
Two macros are exactly the same.
2024-10-15 18:23:39 +09:00
Eduardo Sánchez Muñoz
c09ed3e767 Make some float methods unstable const fn
Some float methods are now `const fn` under the `const_float_methods` feature gate.

In order to support `min`, `max`, `abs` and `copysign`, the implementation of some intrinsics had to be moved from Miri to rustc_const_eval.
2024-10-15 10:46:33 +02:00
bors
88f311479d Auto merge of #131724 - matthiaskrgr:rollup-ntgkkk8, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #130608 (Implemented `FromStr` for `CString` and `TryFrom<CString>` for `String`)
 - #130635 (Add `&pin (mut|const) T` type position sugar)
 - #130747 (improve error messages for `C-cmse-nonsecure-entry` functions)
 - #131137 (Add 1.82 release notes)
 - #131328 (Remove unnecessary sorts in `rustc_hir_analysis`)
 - #131496 (Stabilise `const_make_ascii`.)
 - #131706 (Fix two const-hacks)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-15 05:02:38 +00:00
Matthias Krüger
83252bd780
Rollup merge of #131706 - GKFX:fix-const-hacks, r=tgross35
Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option #67441.
2024-10-15 05:12:37 +02:00
Matthias Krüger
09103f2617
Rollup merge of #131339 - HeroicKatora:set_ptr_value-documentation, r=Mark-Simulacrum
Expand set_ptr_value / with_metadata_of docs

In preparation of a potential FCP, intends to clean up and expand the documentation of this operation.

Rewrite these blobs to explicitly mention the case of a sized operand. The previous made that seem wrong instead of emphasizing it is nothing but a simple cast. Instead, the explanation now emphasizes that the address portion of the argument, together with its provenance, is discarded which previously had to be inferred by the reader. Then an example demonstrates a simple line of incorrect usage based on this idea of provenance.

Tracking issue: https://github.com/rust-lang/rust/issues/75091
2024-10-15 05:11:37 +02:00
Matthias Krüger
6d9999662c
Rollup merge of #122670 - beetrees:non-unicode-option-env-error, r=compiler-errors
Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode

Fixes #122669 by making `option_env!` emit an error when the value of the environment variable is not valid Unicode.
2024-10-15 05:11:36 +02:00
bors
785c83015c Auto merge of #129458 - EnzymeAD:enzyme-frontend, r=jieyouxu
Autodiff Upstreaming - enzyme frontend

This is an upstream PR for the `autodiff` rustc_builtin_macro that is part of the autodiff feature.

For the full implementation, see: https://github.com/rust-lang/rust/pull/129175

**Content:**
It contains a new `#[autodiff(<args>)]` rustc_builtin_macro, as well as a `#[rustc_autodiff]` builtin attribute.
The autodiff macro is applied on function `f` and will expand to a second function `df` (name given by user).
It will add a dummy body to `df` to make sure it type-checks. The body will later be replaced by enzyme on llvm-ir level,
we therefore don't really care about the content. Most of the changes (700 from 1.2k) are in `compiler/rustc_builtin_macros/src/autodiff.rs`, which expand the macro. Nothing except expansion is implemented for now.
I have a fallback implementation for relevant functions in case that rustc should be build without autodiff support. The default for now will be off, although we want to flip it later (once everything landed) to on for nightly. For the sake of CI, I have flipped the defaults, I'll revert this before merging.

**Dummy function Body:**
The first line is an `inline_asm` nop to make inlining less likely (I have additional checks to prevent this in the middle end of rustc. If `f` gets inlined too early, we can't pass it to enzyme and thus can't differentiate it.
If `df` gets inlined too early, the call site will just compute this dummy code instead of the derivatives, a correctness issue. The following black_box lines make sure that none of the input arguments is getting optimized away before we replace the body.

**Motivation:**
The user facing autodiff macro can verify the user input. Then I write it as args to the rustc_attribute, so from here on I can know that these values should be sensible. A rustc_attribute also turned out to be quite nice to attach this information to the corresponding function and carry it till the backend.
This is also just an experiment, I expect to adjust the user facing autodiff macro based on user feedback, to improve usability.

As a simple example of what this will do, we can see this expansion:
From:
```
#[autodiff(df, Reverse, Duplicated, Const, Active)]
pub fn f1(x: &[f64], y: f64) -> f64 {
    unimplemented!()
}
```
to
```
#[rustc_autodiff]
#[inline(never)]
pub fn f1(x: &[f64], y: f64) -> f64 {
    ::core::panicking::panic("not implemented")
}
#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
#[inline(never)]
pub fn df(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
    unsafe { asm!("NOP"); };
    ::core::hint::black_box(f1(x, y));
    ::core::hint::black_box((dx, dret));
    ::core::hint::black_box(f1(x, y))
}
```
I will add a few more tests once I figured out why rustc rebuilds every time I touch a test.

Tracking:

- https://github.com/rust-lang/rust/issues/124509

try-job: dist-x86_64-msvc
2024-10-15 01:30:01 +00:00
Gabriel Bjørnager Jensen
3c31729887
Stabilise 'const_make_ascii' 2024-10-14 17:56:36 -07:00
Trevor Gross
373142aaa1 Mark LazyCell::into_inner unstably const
Other cell `into_inner` functions are const and there shouldn't be any
problem here. Make the unstable `LazyCell::into_inner` const under the
same gate as its stability (`lazy_cell_into_inner`).

Tracking issue: https://github.com/rust-lang/rust/issues/125623
2024-10-14 17:16:01 -04:00
George Bateman
4e438f7d6b
Fix two const-hacks 2024-10-14 20:50:40 +01:00
Matthias Krüger
32062b4b8e
Rollup merge of #131384 - saethlin:precondition-tests, r=ibraheemdev
Update precondition tests (especially for zero-size access to null)

I don't much like the current way I've updated the precondition check helpers, but I couldn't come up with anything better. Ideas welcome.

I've organized `tests/ui/precondition-checks` mostly with one file per function that has `assert_unsafe_precondition` in it, with revisions that check each precondition. The important new test is `tests/ui/precondition-checks/zero-size-null.rs`.
2024-10-14 17:06:36 +02:00
Matthias Krüger
7ed6d1cd38
Rollup merge of #129424 - coolreader18:stabilize-pin_as_deref_mut, r=dtolnay
Stabilize `Pin::as_deref_mut()`

Tracking issue: closes #86918

Stabilizing the following API:

```rust
impl<Ptr: DerefMut> Pin<Ptr> {
    pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target>;
}
```

I know that an FCP has not been started yet, but this isn't a very complex stabilization, and I'm hoping this can motivate an FCP to *get* started - this has been pending for a while and it's a very useful function when writing Future impls.

r? ``@jonhoo``
2024-10-14 17:06:35 +02:00
Matthias Krüger
5d63a3db9c
Rollup merge of #131616 - RalfJung:const_ip, r=tgross35
merge const_ipv4 / const_ipv6 feature gate into 'ip' feature gate

https://github.com/rust-lang/rust/issues/76205 has been closed a while ago, but there are still some functions that reference it. Those functions are all unstable *and* const-unstable. There's no good reason to use a separate feature gate for their const-stability, so this PR moves their const-stability under the same gate as their regular stability, and therefore removes the remaining references to https://github.com/rust-lang/rust/issues/76205.
2024-10-14 06:04:29 +02:00
Matthias Krüger
cc5d86ac60
Rollup merge of #131274 - workingjubilee:stabilize-the-one-that-got-away, r=scottmcm
library: Const-stabilize `MaybeUninit::assume_init_mut`

FCP completed in https://github.com/rust-lang/rust/issues/86722#issuecomment-2393954459

Also moves const-ness of an unstable fn under the `maybe_uninit_slice` gate, Cc https://github.com/rust-lang/rust/issues/63569
2024-10-14 06:04:27 +02:00
Matthias Krüger
e01eae72da
Rollup merge of #130629 - Dirbaio:net-from-octets, r=tgross35
core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments.

Adds:

- `Ipv4Address::from_octets([u8;4])`
- `Ipv6Address::from_octets([u8;16])`
- `Ipv6Address::from_segments([u16;8])`

equivalent to the existing `From` impls.

Advantages:

- Consistent with `to_bits, from_bits`.
- More discoverable than the `From` impls.
- Helps with type inference: it's common to want to convert byte slices to IP addrs. If you try this

```rust
fn foo(x: &[u8]) -> Ipv4Addr {
   Ipv4Addr::from(foo.try_into().unwrap())
}
```

it [doesn't work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0e2873312de275a58fa6e33d1b213bec). You have to write `Ipv4Addr::from(<[u8;4]>::try_from(x).unwrap())` instead, which is not great. With `from_octets` it is able to infer the right types.

Found this while porting [smoltcp](https://github.com/smoltcp-rs/smoltcp/) from its own IP address types to the `core::net` types.

~~Tracking issues #27709 #76205~~
Tracking issue: https://github.com/rust-lang/rust/issues/131360
2024-10-14 06:04:27 +02:00
Dario Nieuwenhuis
0b7e39908e core/net: use hex for ipv6 doctests for consistency. 2024-10-13 20:27:24 +02:00
Dario Nieuwenhuis
725d1f7905 core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments 2024-10-13 20:26:23 +02:00
bors
36780360b6 Auto merge of #125679 - clarfonthey:escape_ascii, r=joboet
Optimize `escape_ascii` using a lookup table

Based upon my suggestion here: https://github.com/rust-lang/rust/pull/125340#issuecomment-2130441817

Effectively, we can take advantage of the fact that ASCII only needs 7 bits to make the eighth bit store whether the value should be escaped or not. This adds a 256-byte lookup table, but 256 bytes *should* be small enough that very few people will mind, according to my probably not incontrovertible opinion.

The generated assembly isn't clearly better (although has fewer branches), so, I decided to benchmark on three inputs: first on a random 200KiB, then on `/bin/cat`, then on `Cargo.toml` for this repo. In all cases, the generated code ran faster on my machine. (an old i7-8700)

But, if you want to try my benchmarking code for yourself:

<details><summary>Criterion code below. Replace <code>/home/ltdk/rustsrc</code> with the appropriate directory.</summary>

```rust
#![feature(ascii_char)]
#![feature(ascii_char_variants)]
#![feature(const_option)]
#![feature(let_chains)]
use core::ascii;
use core::ops::Range;
use criterion::{criterion_group, criterion_main, Criterion};
use rand::{thread_rng, Rng};

const HEX_DIGITS: [ascii::Char; 16] = *b"0123456789abcdef".as_ascii().unwrap();

#[inline]
const fn backslash<const N: usize>(a: ascii::Char) -> ([ascii::Char; N], Range<u8>) {
    const { assert!(N >= 2) };

    let mut output = [ascii::Char::Null; N];

    output[0] = ascii::Char::ReverseSolidus;
    output[1] = a;

    (output, 0..2)
}

#[inline]
const fn hex_escape<const N: usize>(byte: u8) -> ([ascii::Char; N], Range<u8>) {
    const { assert!(N >= 4) };

    let mut output = [ascii::Char::Null; N];

    let hi = HEX_DIGITS[(byte >> 4) as usize];
    let lo = HEX_DIGITS[(byte & 0xf) as usize];

    output[0] = ascii::Char::ReverseSolidus;
    output[1] = ascii::Char::SmallX;
    output[2] = hi;
    output[3] = lo;

    (output, 0..4)
}

#[inline]
const fn verbatim<const N: usize>(a: ascii::Char) -> ([ascii::Char; N], Range<u8>) {
    const { assert!(N >= 1) };

    let mut output = [ascii::Char::Null; N];

    output[0] = a;

    (output, 0..1)
}

/// Escapes an ASCII character.
///
/// Returns a buffer and the length of the escaped representation.
const fn escape_ascii_old<const N: usize>(byte: u8) -> ([ascii::Char; N], Range<u8>) {
    const { assert!(N >= 4) };

    match byte {
        b'\t' => backslash(ascii::Char::SmallT),
        b'\r' => backslash(ascii::Char::SmallR),
        b'\n' => backslash(ascii::Char::SmallN),
        b'\\' => backslash(ascii::Char::ReverseSolidus),
        b'\'' => backslash(ascii::Char::Apostrophe),
        b'\"' => backslash(ascii::Char::QuotationMark),
        0x00..=0x1F => hex_escape(byte),
        _ => match ascii::Char::from_u8(byte) {
            Some(a) => verbatim(a),
            None => hex_escape(byte),
        },
    }
}

/// Escapes an ASCII character.
///
/// Returns a buffer and the length of the escaped representation.
const fn escape_ascii_new<const N: usize>(byte: u8) -> ([ascii::Char; N], Range<u8>) {
    /// Lookup table helps us determine how to display character.
    ///
    /// Since ASCII characters will always be 7 bits, we can exploit this to store the 8th bit to
    /// indicate whether the result is escaped or unescaped.
    ///
    /// We additionally use 0x80 (escaped NUL character) to indicate hex-escaped bytes, since
    /// escaped NUL will not occur.
    const LOOKUP: [u8; 256] = {
        let mut arr = [0; 256];
        let mut idx = 0;
        loop {
            arr[idx as usize] = match idx {
                // use 8th bit to indicate escaped
                b'\t' => 0x80 | b't',
                b'\r' => 0x80 | b'r',
                b'\n' => 0x80 | b'n',
                b'\\' => 0x80 | b'\\',
                b'\'' => 0x80 | b'\'',
                b'"' => 0x80 | b'"',

                // use NUL to indicate hex-escaped
                0x00..=0x1F | 0x7F..=0xFF => 0x80 | b'\0',

                _ => idx,
            };
            if idx == 255 {
                break;
            }
            idx += 1;
        }
        arr
    };

    let lookup = LOOKUP[byte as usize];

    // 8th bit indicates escape
    let lookup_escaped = lookup & 0x80 != 0;

    // SAFETY: We explicitly mask out the eighth bit to get a 7-bit ASCII character.
    let lookup_ascii = unsafe { ascii::Char::from_u8_unchecked(lookup & 0x7F) };

    if lookup_escaped {
        // NUL indicates hex-escaped
        if matches!(lookup_ascii, ascii::Char::Null) {
            hex_escape(byte)
        } else {
            backslash(lookup_ascii)
        }
    } else {
        verbatim(lookup_ascii)
    }
}

fn escape_bytes(bytes: &[u8], f: impl Fn(u8) -> ([ascii::Char; 4], Range<u8>)) -> Vec<ascii::Char> {
    let mut vec = Vec::new();
    for b in bytes {
        let (buf, range) = f(*b);
        vec.extend_from_slice(&buf[range.start as usize..range.end as usize]);
    }
    vec
}

pub fn criterion_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("escape_ascii");

    group.sample_size(1000);

    let rand_200k = &mut [0; 200 * 1024];
    thread_rng().fill(&mut rand_200k[..]);
    let cat = include_bytes!("/bin/cat");
    let cargo_toml = include_bytes!("/home/ltdk/rustsrc/Cargo.toml");

    group.bench_function("old_rand", |b| {
        b.iter(|| escape_bytes(rand_200k, escape_ascii_old));
    });
    group.bench_function("new_rand", |b| {
        b.iter(|| escape_bytes(rand_200k, escape_ascii_new));
    });

    group.bench_function("old_bin", |b| {
        b.iter(|| escape_bytes(cat, escape_ascii_old));
    });
    group.bench_function("new_bin", |b| {
        b.iter(|| escape_bytes(cat, escape_ascii_new));
    });

    group.bench_function("old_cargo_toml", |b| {
        b.iter(|| escape_bytes(cargo_toml, escape_ascii_old));
    });
    group.bench_function("new_cargo_toml", |b| {
        b.iter(|| escape_bytes(cargo_toml, escape_ascii_new));
    });

    group.finish();
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
```

</details>

My benchmark results:

```
escape_ascii/old_rand   time:   [1.6965 ms 1.7006 ms 1.7053 ms]
Found 22 outliers among 1000 measurements (2.20%)
  4 (0.40%) high mild
  18 (1.80%) high severe
escape_ascii/new_rand   time:   [1.6749 ms 1.6953 ms 1.7158 ms]
Found 38 outliers among 1000 measurements (3.80%)
  38 (3.80%) high mild
escape_ascii/old_bin    time:   [224.59 µs 225.40 µs 226.33 µs]
Found 39 outliers among 1000 measurements (3.90%)
  17 (1.70%) high mild
  22 (2.20%) high severe
escape_ascii/new_bin    time:   [164.86 µs 165.63 µs 166.58 µs]
Found 107 outliers among 1000 measurements (10.70%)
  43 (4.30%) high mild
  64 (6.40%) high severe
escape_ascii/old_cargo_toml
                        time:   [23.397 µs 23.699 µs 24.014 µs]
Found 204 outliers among 1000 measurements (20.40%)
  21 (2.10%) high mild
  183 (18.30%) high severe
escape_ascii/new_cargo_toml
                        time:   [16.404 µs 16.438 µs 16.483 µs]
Found 88 outliers among 1000 measurements (8.80%)
  56 (5.60%) high mild
  32 (3.20%) high severe
```

Random: 1.7006ms => 1.6953ms (<1% speedup)
Binary: 225.40µs => 165.63µs (26% speedup)
Text: 23.699µs => 16.438µs (30% speedup)
2024-10-13 14:05:50 +00:00
Ralf Jung
90e4f10f6c switch unicode-data back to 'static' 2024-10-13 11:53:06 +02:00
Ralf Jung
1ebfd97051 merge const_ipv4 / const_ipv6 feature gate into 'ip' feature gate 2024-10-13 09:55:34 +02:00
beetrees
feecfaa18d
Fix bug where option_env! would return None when env var is present but not valid Unicode 2024-10-13 02:10:19 +01:00
Andreas Molzer
c128b4c433 Fix typo thing->thin referring to pointer 2024-10-13 02:35:09 +02:00
Trevor Gross
19f6c17df4 Stabilize const_option
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

    impl<T> Option<&T> {
        pub const fn copied(self) -> Option<T>
        where T: Copy;
    }

    impl<T> Option<&mut T> {
        pub const fn copied(self) -> Option<T>
        where T: Copy;
    }

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <https://github.com/rust-lang/rust/issues/67441>
2024-10-12 17:07:13 -04:00
Trevor Gross
8a86f1dd8c
Rollup merge of #130954 - workingjubilee:stabilize-const-mut-fn, r=RalfJung
Stabilize const `ptr::write*` and `mem::replace`

Since `const_mut_refs` and `const_refs_to_cell` have been stabilized, we may now also stabilize the ability to write to places during const evaluation inside our library API. So, we now propose the `const fn` version of `ptr::write` and its variants. This allows us to also stabilize `mem::replace` and `ptr::replace`.
- const `mem::replace`: https://github.com/rust-lang/rust/issues/83164#issuecomment-2338660862
- const `ptr::write{,_bytes,_unaligned}`: https://github.com/rust-lang/rust/issues/86302#issuecomment-2330275266

Their implementation requires an additional internal stabilization of `const_intrinsic_forget`, which is required for `*::write*` and thus `*::replace`. Thus we const-stabilize the internal intrinsics `forget`, `write_bytes`, and `write_via_move`.
2024-10-12 11:08:42 -05:00
Jubilee Young
187c8b0ce9 library: Stabilize const_replace
Depends on stabilizing `const_ptr_write`.

Const-stabilizes:
- `core::mem::replace`
- `core::ptr::replace`
2024-10-12 00:02:38 -07:00
Jubilee Young
ddc367ded7 library: Stabilize const_ptr_write
Const-stabilizes:
- `write`
- `write_bytes`
- `write_unaligned`

In the following paths:
- `core::ptr`
- `core::ptr::NonNull`
- pointer `<*mut T>`

Const-stabilizes the internal `core::intrinsics`:
- `write_bytes`
- `write_via_move`
2024-10-12 00:02:36 -07:00
Jubilee Young
9a523001e3 library: Stabilize const_intrinsic_forget
This is an implicit requirement of stabilizing `const_ptr_write`.

Const-stabilizes the internal `core::intrinsics`:
- `forget`
2024-10-12 00:02:09 -07:00
Trevor Gross
3e16b77465
Rollup merge of #131289 - RalfJung:duration_consts_float, r=tgross35
stabilize duration_consts_float

Waiting for FCP in https://github.com/rust-lang/rust/issues/72440 to pass.

`as_millis_f32` and `as_millis_f64` are not stable at all yet, so I moved their const-stability together with their regular stability (tracked at https://github.com/rust-lang/rust/issues/122451).

Fixes https://github.com/rust-lang/rust/issues/72440
2024-10-11 23:57:45 -04:00
Trevor Gross
3f9aa50b70
Rollup merge of #124874 - jedbrown:float-mul-add-fast, r=saethlin
intrinsics fmuladdf{32,64}: expose llvm.fmuladd.* semantics

Add intrinsics `fmuladd{f32,f64}`. This computes `(a * b) + c`, to be fused if the code generator determines that (i) the target instruction set has support for a fused operation, and (ii) that the fused operation is more efficient than the equivalent, separate pair of `mul` and `add` instructions.

https://llvm.org/docs/LangRef.html#llvm-fmuladd-intrinsic

The codegen_cranelift uses the `fma` function from libc, which is a correct implementation, but without the desired performance semantic. I think this requires an update to cranelift to expose a suitable instruction in its IR.

I have not tested with codegen_gcc, but it should behave the same way (using `fma` from libc).

---
This topic has been discussed a few times on Zulip and was suggested, for example, by `@workingjubilee` in [Effect of fma disabled](https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Effect.20of.20fma.20disabled/near/274179331).
2024-10-11 23:57:44 -04:00
Josh Stone
5365b3f7be Avoid superfluous UB checks in IndexRange
`IndexRange::len` is justified as an overall invariant, and
`take_prefix` and `take_suffix` are justified by local branch
conditions. A few more UB-checked calls remain in cases that are only
supported locally by `debug_assert!`, which won't do anything in
distributed builds, so those UB checks may still be useful.

We generally expect core's `#![rustc_preserve_ub_checks]` to optimize
away in user's release builds, but the mere presence of that extra code
can sometimes inhibit optimization, as seen in #131563.
2024-10-11 16:22:43 -07:00
Trevor Gross
8ea41b903f
Rollup merge of #131463 - bjoernager:const-char-encode-utf8, r=RalfJung
Stabilise `const_char_encode_utf8`.

Closes: #130512

This PR stabilises the `const_char_encode_utf8` feature gate (i.e. support for `char::encode_utf8` in const scenarios).

Note that the linked tracking issue is currently awaiting FCP.
2024-10-11 16:53:49 -05:00