Unimplement unsized_locals
Implements https://github.com/rust-lang/compiler-team/issues/630
Tracking issue here: https://github.com/rust-lang/rust/issues/111942
Note that this just removes the feature, not the implementation, and does not touch `unsized_fn_params`. This is because it is required to support `Box<dyn FnOnce()>: FnOnce()`.
There may be more that should be removed (possibly in follow up prs)
- the `forget_unsized` function and `forget` intrinsic.
- the `unsized_locals` test directory; I've just fixed up the tests for now
- various codegen support for unsized values and allocas
cc ``@JakobDegen`` ``@oli-obk`` ``@Noratrieb`` ``@programmerjake`` ``@bjorn3``
``@rustbot`` label F-unsized_locals
Fixesrust-lang/rust#79409
mir-opt: Do not create storage marks in EarlyOtherwiseBranch
Fixes#141212.
The first commit add `StorageDead` by creating new indirect BB that makes CFG more complicated, but I think it's better to just not create storage marks.
r? mir-opt
Fix for async drop inside async gen fn
Return value (for yield) is corrected for async drop inside async gen function.
In CFG, when internal async drop future is polled and returned `Poll<()>::Pending`, then async gen resume function returns `Poll<(OptRet)>::Pending`.
Fixesrust-lang/rust#140530
Async drop - type instead of async drop fn, fixes#140484Fixes: rust-lang/rust#140484Fixes: rust-lang/rust#140500
Fixes ICE, when type is provided in AsyncDrop trait instead of `async fn drop()`.
Fixes ICE, when async drop fn has wrong signature.
`slice.get(i)` should use a slice projection in MIR, like `slice[i]` does
`slice[i]` is built-in magic, so ends up being quite different from `slice.get(i)` in MIR, even though they're both doing nearly identical operations -- checking the length of the slice then getting a ref/ptr to the element if it's in-bounds.
This PR adds a `slice_get_unchecked` intrinsic for `impl SliceIndex for usize` to use to fix that, so it no longer needs to do a bunch of lines of pointer math and instead just gets the obvious single statement. (This is *not* used for the range versions, since `slice[i..]` and `slice[..k]` can't use the mir Slice projection as they're using fenceposts, not indices.)
I originally tried to do this with some kind of GVN pattern, but realized that I'm pretty sure it's not legal to optimize `BinOp::Offset` to `PlaceElem::Index` without an extremely complicated condition. Basically, the problem is that the `Index` projection on a dereferenced slice pointer *cares about the metadata*, since it's UB to `PlaceElem::Index` outside the range described by the metadata. But then you cast the fat pointer to a thin pointer then offset it, that *ignores* the slice length metadata, so it's possible to write things that are legal with `Offset` but would be UB if translated in the obvious way to `Index`. Checking (or even determining) the necessary conditions for that would be complicated and error-prone, whereas this intrinsic-based approach is quite straight-forward.
Zero backend changes, because it just lowers to MIR, so it's already supported naturally by CTFE/Miri/cg_llvm/cg_clif.
Make two transmute-related MIR lints into HIR lint
Make `PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS` (rust-lang/rust#130540) and `UNNECESSARY_TRANSMUTES` (rust-lang/rust#136083) into "normal" HIR-based lints.
Funny enough this came up in the review of the latter (https://github.com/rust-lang/rust/pull/136083#issuecomment-2614301413), but I guess it just was overlooked.
But anywyas, there's no reason for these to be MIR lints; in fact, it makes the suggestions for them a bit more complicated than necessary.
Note that there's probably a few more simplifications and improvements to be done here. Follow-ups can be done in a separate PR, especially if they're about the messaging and suggestions themselves, which I didn't write.
gvn: bail out unavoidable non-ssa locals in repeat
Fixes#141251.
We cannot transform `*elem` to `array[idx1]` in the following code, as `idx1` has already been modified.
```rust
mir! {
let array;
let elem;
{
array = [*val; 5];
elem = &array[idx1];
idx1 = idx2;
RET = *elem;
Return()
}
}
```
Perhaps I could transform it to `array[0]`, but I prefer the conservative approach.
r? mir-opt
interpret: add allocation parameters to `AllocBytes`
Necessary for a better implementation of [rust-lang/miri#4343](https://github.com/rust-lang/miri/pull/4343). Also included here is the code from that PR, adapted to this new interface for the sake of example and so that CI can run on them; the Miri changes can be reverted and merged separately, though.
r? `@RalfJung`
Emit dummy open drop for unsafe binder
Fixesrust-lang/rust#141394
We can't taint the body in wfcheck when we have a `T: Copy` bound failure, so we end up binding MIR here. Emit a dummy open drop so that drop elaboration doesn't fail.
r? oli-obk
Async drop poll shim for error dropee generates noop body
Fixes https://github.com/rust-lang/rust/issues/140930.
When dropee type for async drop poll shim is `ty::Error(_)`, the generated poll function will be noop body. To avoid ICE in `elaborate_drop`.
dont handle bool transmute
removes `transmute(u8) -> bool` suggestion due to ambiguity, leave it for clippy
elaboration on ambiguity in question:
`transmute::<u8, bool>(x)` will codegen to an `assume(u8 < 2)`;
`_ == 1` or `_ != 0` or `_ % 2 == 0` would remove that assumption
`match _ { x @ (0 | 1) => x == 1, _ => std::hint::unreachable_unchecked() }` is very verbose
`@rustbot` label L-unnecessary_transmutes
We cannot transform `*elem` to `array[idx1]` in the following code,
as `idx1` has already been modified.
```rust
mir! {
let array;
let elem;
{
array = [*val; 5];
elem = &array[idx1];
idx1 = idx2;
RET = *elem;
Return()
}
}
```
coverage: Detect unused local file IDs to avoid an LLVM assertion
Each function's coverage metadata contains a *local file table* that maps local file IDs (used by the function's mapping regions) to global file IDs (shared by all functions in the same CGU).
LLVM requires all local file IDs to have at least one mapping region, and has an assertion that will fail if it detects a local file ID with no regions. To make sure that assertion doesn't fire, we need to detect and skip functions whose metadata would trigger it.
(This can't actually happen yet, because currently all of a function's spans must belong to the same file and expansion. But this will be an important edge case when adding expansion region support.)
make `rustc_attr_parsing` less dominant in the rustc crate graph
It has/had a glob re-export of `rustc_attr_data_structures`, which is a crate much lower in the graph, and a lot of crates were using it *just* (or *mostly*) for that re-export, while they can rely on `rustc_attr_data_structures` directly.
Previous graph:

Graph with this PR:

The first commit keeps the re-export, and just changes the dependency if possible. The second commit is the "breaking change" which removes the re-export, and "explicitly" adds the `rustc_attr_data_structures` dependency where needed. It also switches over some src/tools/*.
The second commit is actually a lot more involved than I expected. Please let me know if it's a better idea to back it out and just keep the first commit.
gvn: avoid creating overlapping assignments
Quick fix#141038, as I couldn't find a way to avoid in-place modification. I'm considering handling all `ravlue` modifications within the `visit_statement` function.
r? mir-opt
Return value of coroutine_layout fn changed to Result with LayoutError
Continue of https://github.com/rust-lang/rust/pull/140902:
`coroutine_layout` fn is now returns `Result` with `LayoutError` to have consistent error with `layout_of_uncached`.
`async_drop_coroutine_layout` fn is now return `LayoutError::TooGeneric` in case of not-fully-specialized `async_drop_in_place<T>::{closure}` coroutine.