Fix coroutine validation for mixed panic strategy
Validation introduced in #113124 allows `UnwindAction::Continue` and `TerminatorKind::Resume` to occur only in functions with ABI that can unwind. The function ABI depends on the panic strategy, which can vary across crates.
Usually MIR is built and validated in the same crate. The coroutine drop glue thus far was an exception. As a result validation could fail when mixing different panic strategies.
Avoid the problem by executing `AbortUnwindingCalls` along with the validation.
Fixes#116953.
Eagerly return `ExprKind::Err` on `yield`/`await` in wrong coroutine context
This PR does 2 things:
1. Refuses to lower `.await` or `yield` when we are outside of the right coroutine context for the operator. Instead, we lower to `hir::ExprKind::Err`, to silence subsequent redundant errors.
2. Reworks a bit of the span tracking in `LoweringContext` to fix a bad span when we have something like `let x = [0; async_fn().await]` where the `await` is inside of an anon const. The span for the "item" still kinda sucks, since it overlaps with the `await` span, but at least it's accurate.
Remove HIR opkinds
`hir::BinOp`, `hir::BinOpKind`, and `hir::UnOp` are identical to `ast::BinOp`, `ast::BinOpKind`, and `ast::UnOp`, respectively. This seems silly, so this PR removes the HIR ones. (A re-export lets the AST ones be referred to using a `hir::` qualifier, which avoids renaming churn.)
r? `@cjgillot`
Unify `TraitRefs` and `PolyTraitRefs` in `ValuePairs`
I did this recently with `FnSigs` and `PolyFnSigs` but didn't think to do it with `TraitRefs` and `PolyTraitRefs`.
remove the memcpy-on-equal-ptrs assumption
One of the libc we support, musl, [defines `memcpy` with `restrict` pointers](https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c#n5). This in fact matches the definition in the C standard. Calling that `memcpy` with overlapping pointers is clearly UB, who knows what the compiler did when optimizing this `memcpy` -- it certainly assumed source and destination to be disjoint.
Lucky enough, it does not seem like we actually need this assumption that `memcpy(p, p, n)` is always allowed. clang and GCC need it since they use `memcpy` to compile C assignments, but [we use memmove for similar code](https://godbolt.org/z/bcW85WYcM). There are no known cases where LLVM introduces calls to memcpy on equal pointers itself. (And if there were, that would be a soundness bug in rustc due to the musl issue mentioned above.)
This does mean we must make sure to never call the LLVM `memcpy` builtin on equal ranges even though the LangRef says that is allowed. Currently that is the case so we just need to make sure it remains the case. :) Cc `@rust-lang/opsem` `@rust-lang/wg-llvm`
Implement thread parking for xous
This follows the pattern set by [the Windows parker](ddef56d5df/library/std/src/sys/windows/thread_parking.rs) when it uses keyed events. An atomic variable is used to track the state and optimize the fast path, while notifications are send via the ticktime server to block and unblock the thread.
ping `@xobs`
`@rustbot` label +T-libs +A-atomic
r? libs
Cut code size for feature hashing
This locally cuts ~32 kB of .text instructions.
This isn't really a clear win in terms of readability. IMO the code size benefits are worth it (even if they're not necessarily present in the x86_64 hyperoptimized build, I expect them to translate similarly to other platforms). Ultimately there's lots of "small ish" low hanging fruit like this that I'm seeing that seems worth tackling to me, and could translate into larger wins in aggregate.
Remove Stacked Borrows GC heuristics
Removing these has no impact on our benchmarks. I think I initially added these because they have a significant impact on runtime at shorter GC intervals. But both these heuristics result in undesirable memory growth in real programs, especially `modified_since_last_gc`. I didn't realize at the time that required state becomes garbage as a result of changes to _other_ allocations.
I think this nets even primarily because we get better heap reuse. With this change I see almost all the mmap calls coming from our diagnostics infrastructure go away. Not that there were many to start with, but it's an indicator that our memory locality has improved.
Before:
```
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/backtraces/Cargo.toml"
Time (mean ± σ): 4.046 s ± 0.087 s [User: 3.952 s, System: 0.085 s]
Range (min … max): 3.952 s … 4.139 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/invalidate/Cargo.toml"
Time (mean ± σ): 6.271 s ± 0.073 s [User: 6.206 s, System: 0.054 s]
Range (min … max): 6.195 s … 6.365 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/mse/Cargo.toml"
Time (mean ± σ): 570.3 ms ± 6.7 ms [User: 505.5 ms, System: 61.8 ms]
Range (min … max): 559.6 ms … 576.0 ms 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/serde1/Cargo.toml"
Time (mean ± σ): 2.013 s ± 0.012 s [User: 1.938 s, System: 0.069 s]
Range (min … max): 1.994 s … 2.024 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/serde2/Cargo.toml"
Time (mean ± σ): 4.155 s ± 0.082 s [User: 4.078 s, System: 0.067 s]
Range (min … max): 4.011 s … 4.211 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/slice-get-unchecked/Cargo.toml"
Time (mean ± σ): 541.5 ms ± 3.9 ms [User: 477.3 ms, System: 60.0 ms]
Range (min … max): 536.1 ms … 545.1 ms 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/unicode/Cargo.toml"
Time (mean ± σ): 1.496 s ± 0.002 s [User: 1.442 s, System: 0.050 s]
Range (min … max): 1.494 s … 1.500 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/zip-equal/Cargo.toml"
Time (mean ± σ): 2.190 s ± 0.043 s [User: 2.109 s, System: 0.075 s]
Range (min … max): 2.114 s … 2.215 s 5 runs
```
After:
```
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/backtraces/Cargo.toml"
Time (mean ± σ): 3.954 s ± 0.057 s [User: 3.871 s, System: 0.075 s]
Range (min … max): 3.912 s … 4.052 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/invalidate/Cargo.toml"
Time (mean ± σ): 6.200 s ± 0.108 s [User: 6.129 s, System: 0.060 s]
Range (min … max): 6.072 s … 6.295 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/mse/Cargo.toml"
Time (mean ± σ): 575.3 ms ± 9.3 ms [User: 511.5 ms, System: 60.2 ms]
Range (min … max): 558.9 ms … 580.8 ms 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/serde1/Cargo.toml"
Time (mean ± σ): 1.966 s ± 0.007 s [User: 1.903 s, System: 0.058 s]
Range (min … max): 1.959 s … 1.974 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/serde2/Cargo.toml"
Time (mean ± σ): 4.138 s ± 0.040 s [User: 4.057 s, System: 0.072 s]
Range (min … max): 4.110 s … 4.207 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/slice-get-unchecked/Cargo.toml"
Time (mean ± σ): 541.8 ms ± 5.6 ms [User: 470.7 ms, System: 66.9 ms]
Range (min … max): 535.6 ms … 549.1 ms 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/unicode/Cargo.toml"
Time (mean ± σ): 1.490 s ± 0.021 s [User: 1.424 s, System: 0.060 s]
Range (min … max): 1.454 s … 1.505 s 5 runs
Benchmark 1: cargo miri run --manifest-path "/home/ben/miri/bench-cargo-miri/zip-equal/Cargo.toml"
Time (mean ± σ): 2.215 s ± 0.048 s [User: 2.113 s, System: 0.072 s]
Range (min … max): 2.183 s … 2.299 s 5 runs
```
Rollup of 6 pull requests
Successful merges:
- #118193 (Add missing period in `std::process::Command` docs)
- #118222 (unify read_to_end and io::copy impls for reading into a Vec)
- #118323 (give dev-friendly error message for incorrect config profiles)
- #118378 (Perform LTO optimisations with wasm-ld + -Clinker-plugin-lto)
- #118399 (Clean dead codes in miri)
- #118410 (update test for new LLVM 18 codegen)
r? `@ghost`
`@rustbot` modify labels: rollup
[`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block
close#11357
----
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block
Validation introduced in #113124 allows UnwindAction::Continue and
TerminatorKind::Resume to occur only in functions with ABI that can
unwind. The function ABI depends on the panic strategy, which can vary
across crates.
Usually MIR is built and validated in the same crate. The coroutine drop
glue thus far was an exception. As a result validation could fail when
mixing different panic strategies.
Avoid the problem by executing AbortUnwindingCalls along with the
validation.
When encountering a bare assignment in a let-chain, suggest turning the
assignment into a `let` expression or an equality check.
```
error: expected expression, found `let` statement
--> $DIR/bad-if-let-suggestion.rs:5:8
|
LL | if let x = 1 && i = 2 {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
|
LL | if let x = 1 && let i = 2 {}
| +++
help: you might have meant to compare for equality
|
LL | if let x = 1 && i == 2 {}
| +
```
Perform LTO optimisations with wasm-ld + -Clinker-plugin-lto
Fixes (partially) #60059. Technically, `--target wasm32-unknown-unknown -Clinker-plugin-lto` would complete without errors before, but it was not producing optimized code. At least, it may have been but it was probably not the opt-level people intended.
Similarly to #118377, this could benefit from a warning about using an explicit libLTO path with LLD, which will ignore it and use its internal LLVM. Especially given we always use lld on wasm targets. I left the code open to that possibility rather than making it perfectly neat.
give dev-friendly error message for incorrect config profiles
before this change, an incorrect profile would result in the following error:
```sh
...
...
File "/home/nimda/devspace/onur-ozkan/rust/src/bootstrap/bootstrap.py", line 1088, in bootstrap
with open(include_path) as included_toml:
^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/home/nimda/devspace/onur-ozkan/rust/src/bootstrap/defaults/config.aaaa.toml'
```
with this change, the error message is now:
```sh
...
...
File "/home/nimda/devspace/onur-ozkan/rust/src/bootstrap/bootstrap.py", line 1088, in bootstrap
raise Exception("Unrecognized profile '{}'. Check src/bootstrap/defaults"
Exception: Unrecognized profile 'aaaa'. Check src/bootstrap/defaults for available options.
```
unify read_to_end and io::copy impls for reading into a Vec
This ports over the initial probe (to avoid allocation) and the dynamic read sizing from the io::copy specialization to the `default_read_to_end` implementation which already had its own optimizations for different cases.
I think it should be a best-of-both now.
suggested by `@a1phyr` in https://github.com/rust-lang/rust/pull/117576#issuecomment-1803408492
Expand in-place iteration specialization to Flatten, FlatMap and ArrayChunks
This enables the following cases to collect in-place:
```rust
let v = vec![[0u8; 4]; 1024]
let v: Vec<_> = v.into_iter().flatten().collect();
let v: Vec<Option<NonZeroUsize>> = vec![NonZeroUsize::new(0); 1024];
let v: Vec<_> = v.into_iter().flatten().collect();
let v = vec![u8; 4096];
let v: Vec<_> = v.into_iter().array_chunks::<4>().collect();
```
Especially the nicheful-option-flattening should be useful in real code.