248458 Commits

Author SHA1 Message Date
Ben Kimock
2a1f97f77f Explain why we don't use intrinsics::is_nonoverlapping 2024-03-09 13:36:36 -05:00
Ben Kimock
af49c4df0a NonZero::from_mut_unchecked is library UB 2024-03-09 12:27:11 -05:00
Ben Kimock
27cf4bb985
Only enable library UB checks in const-eval/Miri when debug_assertions are enabled
Co-authored-by: Ralf Jung <post@ralfj.de>
2024-03-09 11:34:15 -05:00
Ben Kimock
50d0bea153 Improve docs 2024-03-09 10:49:26 -05:00
Ben Kimock
5a93a59fd5 Distinguish between library and lang UB in assert_unsafe_precondition 2024-03-08 18:53:58 -05:00
bors
46b180ec24 Auto merge of #122206 - matthiaskrgr:rollup-4txx9wx, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #121201 (align_offset, align_to: no longer allow implementations to spuriously fail to align)
 - #122076 (Tweak the way we protect in-place function arguments in interpreters)
 - #122100 (Better comment for implicit captures in RPITIT)
 - #122157 (Add the new description field to Target::to_json, and add descriptions for some MSVC targets)
 - #122164 (Fix misaligned loads when loading UEFI arg pointers)
 - #122171 (Add some new solver tests)
 - #122172 (Don't ICE if we collect no RPITITs unless there are no unification errors)
 - #122197 (inspect formatter: add braces)
 - #122198 (Remove handling for previously dropped LLVM version)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-03-08 20:34:52 +00:00
Matthias Krüger
b61edb9544
Rollup merge of #122198 - beetrees:no-llvm-14, r=cuviper
Remove handling for previously dropped LLVM version

LLVM 14 support was dropped in #114148, so this LLVM version check is no longer required.
2024-03-08 21:02:04 +01:00
Matthias Krüger
bf939fcb99
Rollup merge of #122197 - lcnr:proof-tree-braces, r=BoxyUwU
inspect formatter: add braces

This makes it easier to hide subtrees when looking through proof trees. Looking at the proof tree for `usize: Clone`:

nightly:
```
ROOT GOAL: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }
    GOAL: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bind(DefId(0:5 ~ main[8e4b]::main)), predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] }
    REVISION 0
        INSTANTIATED: QueryInput { goal: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bind(DefId(0:5 ~ main[8e4b]::main)), predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }
        ROOT RESULT: Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] })
            CANDIDATE Impl(DefId(2:30665 ~ core[a9f5]::clone::impls::{impl#5})): Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] })
                TRY_EVALUATE_ADDED_GOALS: Ok(Yes)
                ITERATION 0
            CANDIDATE constituent tys: Err(NoSolution)
            NORMALIZING SELF TY FOR ASSEMBLY:
            NORMALIZING SELF TY FOR ASSEMBLY:
    RESULT: Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] })
```

with this PR:
```
ROOT GOAL: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } } {
    GOAL: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bind(DefId(0:5 ~ main[4f74]::main)), predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] }
    REVISION 0: {
        INSTANTIATED: QueryInput { goal: Goal { predicate: Binder { value: TraitPredicate(<usize as std::clone::Clone>, polarity:Positive), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bind(DefId(0:5 ~ main[4f74]::main)), predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }
        ROOT RESULT: Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) {
            CANDIDATE Impl(DefId(2:30468 ~ core[d1d7]::clone::impls::{impl#5})): Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) {
                TRY_EVALUATE_ADDED_GOALS: Ok(Yes)
                ITERATION 0 {}
            }
            CANDIDATE constituent tys: Err(NoSolution) {}
            NORMALIZING SELF TY FOR ASSEMBLY: {}
            NORMALIZING SELF TY FOR ASSEMBLY: {}
        }
    }
    RESULT: Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] })
}
```

r? `@BoxyUwU`
2024-03-08 21:02:03 +01:00
Matthias Krüger
02b89d1676
Rollup merge of #122172 - compiler-errors:rpitit-collect-ice, r=fmease
Don't ICE if we collect no RPITITs unless there are no unification errors

Move an assertion in `collect_return_position_impl_trait_in_trait_tys` to after the `ObligationCtxt::eq` calls, so that we only assert and ICE if we have unification errors.

Fixes #121468
2024-03-08 21:02:03 +01:00
Matthias Krüger
9829ff67ba
Rollup merge of #122171 - compiler-errors:next-solver-tests, r=lcnr
Add some new solver tests

Fixes #119607
Fixes #119608

r? lcnr
2024-03-08 21:02:02 +01:00
Matthias Krüger
2b6ae95d3f
Rollup merge of #122164 - beetrees:uefi-argv-align, r=workingjubilee
Fix misaligned loads when loading UEFI arg pointers

Currently, the two UEFI argument pointers are stored in an `alloca` of alignment 1, a pointer to which is then passed as `argv`. However, [the library code](9c3ad802d9/library/std/src/sys/pal/uefi/mod.rs (L60-L61)) treats `argv` as a pointer to an array of pointers and dereferences it as such, meaning that it presumes the `alloca` is aligned to at least the alignment of a pointer. This PR fixes this mismatch by aligning the `alloca` to the alignment of a pointer.

This PR also changed the `gep` to use the new `inbounds_ptradd` method.
2024-03-08 21:02:01 +01:00
Matthias Krüger
b9a3952479
Rollup merge of #122157 - dpaoliello:targetdesc, r=Nilstrieb
Add the new description field to Target::to_json, and add descriptions for some MSVC targets

The original PR to add a `description` field to `Target` (<https://github.com/rust-lang/rust/pull/121905>) didn't add the field to `Target::to_json`, which meant that the `check_consistency` testwould fail if you tried to set a description as it wouldn't survive round-tripping via JSON: https://github.com/rust-lang/rust/actions/runs/8180997936/job/22370052535#step:27:4967

This change adds the field to `Target::to_json`, and sets some descriptions to verify that it works correctly.
2024-03-08 21:02:01 +01:00
Matthias Krüger
e76bd6214f
Rollup merge of #122100 - compiler-errors:better-capture, r=oli-obk
Better comment for implicit captures in RPITIT

Improve the error message for implicit captures. Also always set E0657.

r? oli-obk
2024-03-08 21:02:00 +01:00
Matthias Krüger
2c3ca0931d
Rollup merge of #122076 - WaffleLapkin:mplace-args, r=RalfJung
Tweak the way we protect in-place function arguments in interpreters

Use `MPlaceTy` instead of `PlaceTy` in `FnArg` and ignore (copy) locals in an earlier step ("Locals that don't have their address taken are as protected as they can ever be").

This seems to be crucial for tail call support (as they can't refer to caller's locals which are killed when replacing the stack frame).

r? `@RalfJung`
cc `@oli-obk`
see https://github.com/rust-lang/rust/pull/121273#issuecomment-1980210690
2024-03-08 21:02:00 +01:00
Matthias Krüger
948d32d94f
Rollup merge of #121201 - RalfJung:align_offset_contract, r=cuviper
align_offset, align_to: no longer allow implementations to spuriously fail to align

For a long time, we have allowed `align_offset` to fail to compute a properly aligned offset, and `align_to` to return a smaller-than-maximal "middle slice". This was done to cover the implementation of `align_offset` in const-eval and Miri. See https://github.com/rust-lang/rust/issues/62420 for more background. For about the same amount of time, this has caused confusion and surprise, where people didn't realize they have to write their code to be defensive against `align_offset` failures.

Another way to put this is: the specification is effectively non-deterministic, and non-determinism is hard to test for -- in particular if the implementation everyone uses to test always produces the same reliable result, and nobody expects it to be non-deterministic to begin with.

With https://github.com/rust-lang/rust/pull/117840, Miri has stopped making use of this liberty in the spec; it now always behaves like rustc. That only leaves const-eval as potential motivation for this behavior. I do not think this is sufficient motivation. Currently, none of the relevant functions are stably const: `align_offset` is unstably const, `align_to` is not const at all. I propose that if we ever want to make these const-stable, we just accept the fact that they can behave differently at compile-time vs at run-time. This is not the end of the world, and it seems to be much less surprising to programmers than unexpected non-determinism. (Related: https://github.com/rust-lang/rfcs/pull/3352.)

`@thomcc` has repeatedly made it clear that they strongly dislike the non-determinism in align_offset, so I expect they will support this. `@oli-obk,` what do you think? Also, whom else should we involve? The primary team responsible is clearly libs-api, so I will nominate this for them. However, allowing const-evaluated code to behave different from run-time code is t-lang territory. The thing is, this is not stabilizing anything t-lang-worthy immediately, but it still does make a decision we will be bound to: if we accept this change, then
- either `align_offset`/`align_to` can never be called in const fn,
- or we allow compile-time behavior to differ from run-time behavior.

So I will nominate for t-lang as well, with the question being: are you okay with accepting either of these outcomes (without committing to which one, just accepting that it has to be one of them)? This closes the door to "have `align_offset` and `align_to` at compile-time and also always have compile-time behavior match run-time behavior".

Closes https://github.com/rust-lang/rust/issues/62420
2024-03-08 21:01:59 +01:00
Michael Goulet
ffd30e0a69 Improve error message for opaque captures 2024-03-08 19:08:13 +00:00
Daniel Paoliello
d6b597b786 Add the new description field to Target::to_json, and add descriptions for some MSVC targets 2024-03-08 09:57:20 -08:00
bors
a655e648a9 Auto merge of #122190 - matthiaskrgr:rollup-9ol4y30, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #121025 (add known-bug tests for derive failure to detect packed repr)
 - #121194 (Refactor pre-getopts command line argument handling)
 - #121563 (Use `ControlFlow` in visitors.)
 - #122173 (Don't ICE in CTFE if raw/fn-ptr types differ)
 - #122175 (Bless tidy issues order)
 - #122179 (rustc: Fix typo)
 - #122181 (Fix crash in internal late lint checking)
 - #122183 (interpret: update comment about read_discriminant on uninhabited variants)

Failed merges:

 - #122076 (Tweak the way we protect in-place function arguments in interpreters)
 - #122132 (Diagnostic renaming 3)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-03-08 17:31:00 +00:00
Ralf Jung
507583a40c align_offset, align_to: no longer allow implementations to spuriously fail to align 2024-03-08 18:28:38 +01:00
lcnr
309d85b06f inspect formatter: add braces 2024-03-08 17:03:04 +01:00
Michael Goulet
8dd4e2b5ca Add some new solver tests 2024-03-08 15:54:04 +00:00
Michael Goulet
07bd05e036 Don't ICE if we collect no RPITITs unless there are no unification errors 2024-03-08 15:52:29 +00:00
bors
74acabe9b0 Auto merge of #121500 - oli-obk:track_errors12, r=petrochenkov
Merge `collect_mod_item_types` query into `check_well_formed`

follow-up to https://github.com/rust-lang/rust/pull/121154

this removes more potential parallel-compiler bottlenecks and moves diagnostics for the same items next to each other, instead of grouping diagnostics by analysis kind
2024-03-08 15:06:36 +00:00
Maybe Waffle
a98432213b Tweak the way we protect in-place function arguments in interpreters
Use `MPlaceTy` instead of `PlaceTy` in `FnArg` and ignore (copy) locals in an
earlier step ("Locals that don't have their address taken are as protected as
they can ever be").

This seems to be crucial for tail call support (as they can't refer to caller's
locals which are killed when replacing the stack frame).
2024-03-08 13:08:35 +00:00
Matthias Krüger
8abeac230a
Rollup merge of #122183 - RalfJung:read-discriminant-uninhabited-variant, r=tmiasko
interpret: update comment about read_discriminant on uninhabited variants
2024-03-08 13:22:29 +01:00
Matthias Krüger
a08a5d4292
Rollup merge of #122181 - chenyukang:yukang-fix-late-lint-crash, r=oli-obk
Fix crash in internal late lint checking

Fixes #122177
2024-03-08 13:22:28 +01:00
Matthias Krüger
9fd60c5887
Rollup merge of #122179 - heiher:fix-typo, r=lcnr
rustc: Fix typo
2024-03-08 13:22:28 +01:00
Matthias Krüger
af3d06cece
Rollup merge of #122175 - chenyukang:yukang-fix-tidy-issues, r=workingjubilee
Bless tidy issues order

The order is not right now because of https://github.com/rust-lang/rust/pull/121248#issuecomment-1975324159

from https://github.com/rust-lang/rust/pull/122161#discussion_r1517107993

r? `@workingjubilee`
2024-03-08 13:22:27 +01:00
Matthias Krüger
3d71bada5a
Rollup merge of #122173 - compiler-errors:ptr-equality-in-ctfe, r=lcnr
Don't ICE in CTFE if raw/fn-ptr types differ

Fixes #121688

r? lcnr
2024-03-08 13:22:27 +01:00
Matthias Krüger
3e634f8c5c
Rollup merge of #121563 - Jarcho:use_cf, r=petrochenkov
Use `ControlFlow` in visitors.

Follow up to #121256

This does have a few small behaviour changes in some diagnostic output where the visitor will now find the first match rather than the last match. The change in `find_anon_types.rs` has the only affected test. I don't see this being an issue as the last occurrence isn't any better of a choice than the first.
2024-03-08 13:22:26 +01:00
Matthias Krüger
a8e3543b19
Rollup merge of #121194 - beetrees:rustc-raw-args, r=petrochenkov
Refactor pre-getopts command line argument handling

Rebased version of #111658. I've also fixed the Windows CI failure (although I don't have access to Windows to test it myself).
2024-03-08 13:22:25 +01:00
Matthias Krüger
075f1c34d4
Rollup merge of #121025 - oli-obk:taint_after_errors, r=petrochenkov
add known-bug tests for derive failure to detect packed repr

We only taint if it was a normal item. Modules and imports are untouched. Tainting them needs to be done differently, and it's unclear if that would be useful or desirable. If we just taint them into `Res::Err`, we end up losing some duplicate name messages *in the presence of other resolution errors*.

r? `@petrochenkov`
2024-03-08 13:22:25 +01:00
bors
42825768b1 Auto merge of #122078 - gurry:121443-ice-layout-is-sized-alt, r=oli-obk
Check that return type is WF in typeck

Ensures that non-WF types do not pass typeck and then later ICE in MIR/const eval

Fixes #121443
2024-03-08 12:16:42 +00:00
yukang
c81521ae54 Fix crash in late internal checking 2024-03-08 19:00:53 +08:00
Ralf Jung
2e5f86c6a7 interpret: update comment about read_discriminant on uninhabited variants 2024-03-08 10:52:33 +01:00
bors
1b2c53a15d Auto merge of #122182 - matthiaskrgr:rollup-gzimi4c, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #118623 (Improve std::fs::read_to_string example)
 - #119365 (Add asm goto support to `asm!`)
 - #120608 (Docs for std::ptr::slice_from_raw_parts)
 - #121832 (Add new Tier-3 target: `loongarch64-unknown-linux-musl`)
 - #121938 (Fix quadratic behavior of repeated vectored writes)
 - #122099 (Add  `#[inline]` to `BTreeMap::new` constructor)
 - #122103 (Make TAITs and ATPITs capture late-bound lifetimes in scope)
 - #122143 (PassWrapper: update for llvm/llvm-project@a331937197)

Failed merges:

 - #122076 (Tweak the way we protect in-place function arguments in interpreters)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-03-08 09:34:05 +00:00
Matthias Krüger
0d235ef9a4
Rollup merge of #122143 - durin42:llvm-19-compression-options, r=workingjubilee
PassWrapper: update for llvm/llvm-project@a331937197

``@rustbot`` label: +llvm-main
2024-03-08 08:19:20 +01:00
Matthias Krüger
d4d18d240b
Rollup merge of #122103 - compiler-errors:taits-capture-everything, r=oli-obk
Make TAITs and ATPITs capture late-bound lifetimes in scope

This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.

r? `@oli-obk` cc `@aliemjay`

Fixes #122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
2024-03-08 08:19:20 +01:00
Matthias Krüger
d16c55d6f6
Rollup merge of #122099 - Urgau:btreemap-inline-new, r=Amanieu
Add  `#[inline]` to `BTreeMap::new` constructor

This PR add the `#[inline]` attribute to `BTreeMap::new` constructor as to make it eligible for inlining.

<details>

For some context: I was profiling `rustc --check-cfg` with callgrind and due to the way we currently setup all the targets and we end-up calling `BTreeMap::new` multiple times for (nearly) all the targets. Adding the `#[inline]` attribute reduced the number of instructions needed.

</details>
2024-03-08 08:19:19 +01:00
Matthias Krüger
f586a79384
Rollup merge of #121938 - blyxxyz:quadratic-vectored-write, r=Amanieu
Fix quadratic behavior of repeated vectored writes

Some implementations of `Write::write_vectored` in the standard library (`BufWriter`, `LineWriter`, `Stdout`, `Stderr`) check all buffers to calculate the total length. This is O(n) over the number of buffers.

It's common that only a limited number of buffers is written at a time (e.g. 1024 for `writev(2)`). `write_vectored_all` will then call `write_vectored` repeatedly, leading to a runtime of O(n²) over the number of buffers.

This fix is to only calculate as much as needed if it's needed.

Here's a test program:
```rust
#![feature(write_all_vectored)]

use std::fs::File;
use std::io::{BufWriter, IoSlice, Write};
use std::time::Instant;

fn main() {
    let buf = vec![b'\0'; 100_000_000];
    let mut slices: Vec<IoSlice<'_>> = buf.chunks(100).map(IoSlice::new).collect();
    let mut writer = BufWriter::new(File::create("/dev/null").unwrap());

    let start = Instant::now();
    write_smart(&slices, &mut writer);
    println!("write_smart(): {:?}", start.elapsed());

    let start = Instant::now();
    writer.write_all_vectored(&mut slices).unwrap();
    println!("write_all_vectored(): {:?}", start.elapsed());
}

fn write_smart(mut slices: &[IoSlice<'_>], writer: &mut impl Write) {
    while !slices.is_empty() {
        // Only try to write as many slices as can be written
        let res = writer
            .write_vectored(slices.get(..1024).unwrap_or(slices))
            .unwrap();
        slices = &slices[(res / 100)..];
    }
}
```
Before this change:
```
write_smart(): 6.666952ms
write_all_vectored(): 498.437092ms
```
After this change:
```
write_smart(): 6.377158ms
write_all_vectored(): 6.923412ms
```

`LineWriter` (and by extension `Stdout`) isn't fully repaired by this because it looks for newlines. I could open an issue for that after this is merged, I think it's fixable but not trivially.
2024-03-08 08:19:19 +01:00
Matthias Krüger
7e6a6d0779
Rollup merge of #121832 - heiher:loongarch64-musl, r=wesleywiser
Add new Tier-3 target: `loongarch64-unknown-linux-musl`

MCP: https://github.com/rust-lang/compiler-team/issues/518
2024-03-08 08:19:18 +01:00
Matthias Krüger
b1aca86011
Rollup merge of #120608 - kornelski:slice-ptr-doc, r=cuviper
Docs for std::ptr::slice_from_raw_parts
2024-03-08 08:19:18 +01:00
Matthias Krüger
d774fbea7c
Rollup merge of #119365 - nbdd0121:asm-goto, r=Amanieu
Add asm goto support to `asm!`

Tracking issue: #119364

This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto).

Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary.

r? ``@Amanieu``
cc ``@ojeda``
2024-03-08 08:19:17 +01:00
Matthias Krüger
876847bed8
Rollup merge of #118623 - haydonryan:master, r=workingjubilee
Improve std::fs::read_to_string example

Resolves  [#118621](https://github.com/rust-lang/rust/issues/118621)

For the original code to succeed it requires address.txt to contain a socketaddress, however it is much easier to follow if this is just any strong - eg address could be a street address or just text.

Also changed the variable name from "foo" to something more meaningful as cargo clippy warns you against using foo as a placeholder.

```
$ cat main.rs
use std::fs;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let addr: String = fs::read_to_string("address.txt")?.parse()?;
    println!("{}", addr);
    Ok(())
}

$ cat address.txt
123 rusty lane
san francisco 94999

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `/home/haydon/workspace/rust-test-pr/tester/target/debug/tester`
123 rusty lane
san francisco 94999

```
2024-03-08 08:19:16 +01:00
bors
14fbc3c005 Auto merge of #120268 - DianQK:otherwise_is_last_variant_switchs, r=oli-obk
Replace the default branch with an unreachable branch If it is the last variant

Fixes #119520. Fixes #110097.

LLVM currently has limited ability to eliminate dead branches in switches, even with the patch of https://github.com/llvm/llvm-project/issues/73446.

The main reasons are as follows:

- Additional costs are required to calculate the range of values, and there exist many scenarios that cannot be analyzed accurately.
- Matching values by bitwise calculation cannot handle odd branches, nor can it handle values like `-1, 0, 1`. See [SimplifyCFG.cpp#L5424](https://github.com/llvm/llvm-project/blob/llvmorg-17.0.6/llvm/lib/Transforms/Utils/SimplifyCFG.cpp#L5424) and https://llvm.godbolt.org/z/qYMqhvMa8
- The current range information is continuous, even if the metadata for the range is submitted. See [ConstantRange.cpp#L1869-L1870](https://github.com/llvm/llvm-project/blob/llvmorg-17.0.6/llvm/lib/IR/ConstantRange.cpp#L1869-L1870).
- The metadata of the range may be lost in passes such as SROA. See https://rust.godbolt.org/z/e7f87vKMK.

Although we can make improvements, I think it would be more appropriate to put this issue to rustc first. After all, we can easily know the possible values.

Note that we've currently found a slow compilation problem in the presence of unreachable branches. See
https://github.com/llvm/llvm-project/issues/78578.

r? compiler
2024-03-08 07:18:17 +00:00
WANG Rui
c2f13db2b5 rustc: Fix typo 2024-03-08 14:25:11 +08:00
yukang
ece20f0d59 Bless tidy issues order 2024-03-08 13:05:51 +08:00
bors
9fb91aa2e7 Auto merge of #122059 - nyurik:with-as-const-str, r=cuviper
Optimize write with as_const_str for shorter code

Following up on #121001

Apparently this code generates significant code block for each call to `write()` with non-simple formatting string - approx 100 lines of assembly code, possibly due to `dyn` (?).  See generated assembly code [here](https://github.com/nyurik/rust-optimize-format-str/compare/before-changes..with-my-change#diff-6b404e954c692d8cdc8c452d819a216aa5dcf40522b5944639e9ad947279a477):

<details><summary>Details</summary>
<p>

This is the inlining of `write!(buffer, "Iteration {value} was written")`

```asm
core::fmt::Write::write_fmt:
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 194
		fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
	push r15
	push r14
	push r13
	push r12
	push rbx
	mov rdx, rsi
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 427
		match (self.pieces, self.args) {
	mov rcx, qword ptr [rsi + 8]
	mov rax, qword ptr [rsi + 24]
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 428
		([], []) => Some(""),
	cmp rcx, 1
	je .LBB0_8
	test rcx, rcx
	jne .LBB0_9
	test rax, rax
	jne .LBB0_9
		// /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911
		self.buf.reserve(self.len, additional);
	lea r12, [rdi + 16]
	lea rsi, [rip + .L__unnamed_2]
	xor ebx, ebx
.LBB0_6:
	mov r14, qword ptr [r12]
	jmp .LBB0_7
.LBB0_8:
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 429
		([s], []) => Some(s),
	test rax, rax
	je .LBB0_4
.LBB0_9:
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 1108
		if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) }
	lea rsi, [rip + .L__unnamed_1]
	pop rbx
	pop r12
	pop r13
	pop r14
	pop r15
	jmp qword ptr [rip + core::fmt::write_internal@GOTPCREL]
.LBB0_4:
	mov rax, qword ptr [rdx]
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 429
		([s], []) => Some(s),
	mov rsi, qword ptr [rax]
	mov rbx, qword ptr [rax + 8]
		// /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 248
		if T::IS_ZST { usize::MAX } else { self.cap.0 }
	mov rax, qword ptr [rdi]
		// /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911
		self.buf.reserve(self.len, additional);
	mov r14, qword ptr [rdi + 16]
		// /home/nyurik/dev/rust/rust/library/core/src/num/mod.rs : 1281
		uint_impl! {
	sub rax, r14
		// /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 392
		additional > self.capacity().wrapping_sub(len)
	cmp rax, rbx
		// /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 309
		if self.needs_to_grow(len, additional) {
	jb .LBB0_5
.LBB0_7:
	mov rax, qword ptr [rdi + 8]
		// /home/nyurik/dev/rust/rust/library/core/src/ptr/mut_ptr.rs : 1046
		unsafe { intrinsics::offset(self, count) }
	add rax, r14
	mov r15, rdi
		// /home/nyurik/dev/rust/rust/library/core/src/intrinsics.rs : 2922
		copy_nonoverlapping(src, dst, count)
	mov rdi, rax
	mov rdx, rbx
	call qword ptr [rip + memcpy@GOTPCREL]
		// /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 2040
		self.len += count;
	add r14, rbx
	mov qword ptr [r15 + 16], r14
		// /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 216
		}
	xor eax, eax
	pop rbx
	pop r12
	pop r13
	pop r14
	pop r15
	ret
.LBB0_5:
		// /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911
		self.buf.reserve(self.len, additional);
	lea r12, [rdi + 16]
	mov r15, rdi
	mov r13, rsi
		// /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 310
		do_reserve_and_handle(self, len, additional);
	mov rsi, r14
	mov rdx, rbx
	call alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle
	mov rsi, r13
	mov rdi, r15
	jmp .LBB0_6
```

</p>
</details>

```rust
#[inline]
pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
    if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) }
}
```

So, this brings back the older experiment - where I used `if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }` helper function, and called it in multiple places that used `write`.  This is not as optimal because now every user of `write` must do this logic, but at least it results in significantly smaller assembly code for the formatting case, and results in identical code as now for the "simple" (no formatting) case. See [assembly comparison](https://github.com/nyurik/rust-optimize-format-str/compare/with-my-change..with-as-const-str#diff-6b404e954c692d8cdc8c452d819a216aa5dcf40522b5944639e9ad947279a477) of what is now with what this change brings (focus only on `fmt/intel-lib.txt` and `str/intel-lib.txt` files).

```rust
               if let Some(s) = args.as_const_str() {
                    self.write_str(s)
                } else {
                    write(self, args)
                }
```
2024-03-08 04:15:17 +00:00
beetrees
0b6006e45e
Remove handling for previously dropped LLVM version 2024-03-08 04:12:04 +00:00
Michael Goulet
025ad403a9 Don't ICE in CTFE if raw/fn-ptr types differ 2024-03-08 02:57:06 +00:00