Remove a bunch of diagnostic stashing that doesn't do anything
#121669 removed a bunch of conditional diagnostic stashing/canceling, but left around the `steal` calls which just emitted the error eagerly instead of canceling the diagnostic. I think that these no-op `steal` calls don't do much and are confusing to encounter, so let's remove them.
The net effect is:
1. We emit more duplicated errors, since stashing has the side effect of duplicating diagnostics. This is not a big deal, since outside of `-Zdeduplicate-diagnostics=no`, the errors are already being deduplicated by the compiler.
2. It changes the order of diagnostics, since we're no longer stashing and then later stealing the errors. I don't think this matters much for the changes that the UI test suite manifests, and it makes these errors less order dependent.
Make MIR cleanup for functions with impossible predicates into a real MIR pass
It's a bit jarring to see the body of a function with an impossible-to-satisfy where clause suddenly go to a single `unreachable` terminator when looking at the MIR dump output in order, and I discovered it's because we manually replace the body outside of a MIR pass.
Let's make it into a fully flegded MIR pass so it's more clear what it's doing and when it's being applied.
Suggest typo fix when trait path expression is typo'ed
When users write something like `Default::defualt()` (notice the typo), failure to resolve the erroneous `defualt` item will cause resolution + lowering to interpret this as a type-dependent path whose self type is `Default` which is a trait object without `dyn`, rather than a trait function like `<_ as Default>::default()`.
Try to provide a bit of guidance in this situation when we can detect the typo.
Fixes https://github.com/rust-lang/rust/issues/135349
Add inherent versions of MaybeUninit methods for slices
This is my attempt to un-stall #63569 and #79995, by creating methods that mirror the existing `MaybeUninit` API:
```rust
impl<T> MaybeUninit<T> {
pub fn write(&mut self, value: T) -> &mut T;
pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
pub unsafe fn assume_init_drop(&mut self);
pub unsafe fn assume_init_ref(&self) -> &T;
pub unsafe fn assume_init_mut(&mut self) -> &mut T;
}
```
Adding these APIs:
```rust
impl<T> [MaybeUninit<T>] {
// replacing copy_from_slice; renamed to avoid conflict
pub fn write_copy_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Copy;
// replacing clone_from_slice; renamed to avoid conflict
pub fn write_clone_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Clone;
// identical to non-slice versions; no conflict
pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
pub unsafe fn assume_init_drop(&mut self);
pub unsafe fn assume_init_ref(&self) -> &[T];
pub unsafe fn assume_init_mut(&mut self) -> &mut [T];
}
```
Since the `assume_init` methods are identical to those on non-slices, they feel pretty natural. The main issue with the write methods is naming, as discussed in #79995 among other places. My rationale:
* The term "write" should be in them somewhere, to mirror the other API, and this pretty much automatically makes them not collide with any other inherent slice methods.
* I chose `write_clone_of_slice` and `write_copy_of_slice` since `clone` and `copy` are being used as objects here, whereas they're being used as actions in `clone_from_slice` and `copy_from_slice`.
The final "weird" thing I've done in this PR is remove a link to `Vec<T>` from `assume_init_drop` (both copies, since they're effectively copied docs), since there's no good way to link to `Vec` for something that can occur both on the page for `std/primitive.slice.html` and `std/vec/struct.Vec.html`, since the code here lives in libcore and can't use intra-doc-linking to mention `Vec`. (see: #121436)
The reason why this method shows up both on `Vec<T>` and `[T]` is because the `[T]` docs are automatically inlined on `Vec<T>`'s page, since it implements `Deref`. It's unfortunate that rustdoc doesn't have a way of dealing with this at the moment, but it is what it is, and it's a reasonable compromise for now.
Cleanup `suggest_binding_for_closure_capture_self` diag in borrowck
Mostly grammar fix/improvement, but also a small cleanup to use iterators instead of for loops for collecting into a vector.
this addresses review comments while:
- keeping the symmetry between the NLL and Polonius out of scope
precomputers
- keeping the unstable `calculate_borrows_out_of_scope_at_location`
function to avoid churn for consumers
we're in in the endgame now
set up the location-sensitive analysis end to end:
- stop recording inflowing loans and loan liveness in liveness
- replace location-insensitive liveness data with live loans computed by
reachability
- remove equivalence between polonius scopes and NLL scopes, and only
run one scope computation
in NLLs some locals are marked live at all points if one of their
regions escapes the function but that doesn't work in a flow-sensitive
setting like polonius
Eagerly collect mono items for non-generic closures
This allows users to use `-Zprint-mono-items=eager` to eagerly monomorphize closures and coroutine bodies, in case they want to inspect the LLVM or ASM for those items.
`-Zprint-mono-items`, which used to be called `-Zprint-trans-items`, was originally added in https://github.com/rust-lang/rust/pull/30900:
> Eager mode is meant to be used in conjunction with incremental compilation
> where a stable set of translation items is more important than a minimal
> one. Thus, eager mode will instantiate drop-glue for every drop-able type
> in the crate, even of no drop call for that type exists (yet). It will
> also instantiate default implementations of trait methods, something that
> otherwise is only done on demand.
Although it remains an unstable option, its purpose has somewhat expanded since then, and as far as I can tell it's generally useful for cases when you want to monomorphize as many items as possible, even if they're unreachable. Specifically, it's useful for debugging since you can look at the codegen'd body of a function, since we don't emit items that are not reachable in monomorphization.
And even more specifically, it would be very to monomorphize the coroutine body of an async fn, since those you can't easily call those without a runtime. This PR enables this usecase since we now monomorphize `DefKind::Closure`.
Rename `BitSet` to `DenseBitSet`
r? `@Mark-Simulacrum` as you requested this in https://github.com/rust-lang/rust/pull/134438#discussion_r1890659739 after such a confusion.
This PR renames `BitSet` to `DenseBitSet` to make it less obvious as the go-to solution for bitmap needs, as well as make its representation (and positives/negatives) clearer. It also expands the comments there to hopefully make it clearer when it's not a good fit, with some alternative bitsets types.
(This migrates the subtrees cg_gcc and clippy to use the new name in separate commits, for easier review by their respective owners, but they can obvs be squashed)
Avoid ICE: Account for `for<'a>` types when checking for non-structural type in constant as pattern
When we encounter a constant in a pattern, we check if it is non-structural. If so, we check if the type implements `PartialEq`, but for types with escaping bound vars the check would be incorrect as is, so we break early. This is ok because these types would be filtered anyways.
Slight tweak to output to remove unnecessary context as a drive-by.
Fix#134764.
add `-Zmin-function-alignment`
tracking issue: https://github.com/rust-lang/rust/issues/82232
This PR adds the `-Zmin-function-alignment=<align>` flag, that specifies a minimum alignment for all* functions.
### Motivation
This feature is requested by RfL [here](https://github.com/rust-lang/rust/issues/128830):
> i.e. the equivalents of `-fmin-function-alignment` ([GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmin-function-alignment_003dn), Clang does not support it) / `-falign-functions` ([GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-falign-functions), [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang1-falign-functions)).
>
> For the Linux kernel, the behavior wanted is that of GCC's `-fmin-function-alignment` and Clang's `-falign-functions`, i.e. align all functions, including cold functions.
>
> There is [`feature(fn_align)`](https://github.com/rust-lang/rust/issues/82232), but we need to do it globally.
### Behavior
The `fn_align` feature does not have an RFC. It was decided at the time that it would not be necessary, but maybe we feel differently about that now? In any case, here are the semantics of this flag:
- `-Zmin-function-alignment=<align>` specifies the minimum alignment of all* functions
- the `#[repr(align(<align>))]` attribute can be used to override the function alignment on a per-function basis: when `-Zmin-function-alignment` is specified, the attribute's value is only used when it is higher than the value passed to `-Zmin-function-alignment`.
- the target may decide to use a higher value (e.g. on x86_64 the minimum that LLVM generates is 16)
- The highest supported alignment in rust is `2^29`: I checked a bunch of targets, and they all emit the `.p2align 29` directive for targets that align functions at all (some GPU stuff does not have function alignment).
*: Only with `build-std` would the minimum alignment also be applied to `std` functions.
---
cc `@ojeda`
r? `@workingjubilee` you were active on the tracking issue
Add an InstSimplify for repetitive array expressions
I noticed in https://github.com/rust-lang/rust/pull/135068#issuecomment-2569955426 that GVN's implementation of this same transform was quite profitable on the deep-vector benchmark. But of course GVN doesn't run in unoptimized builds, so this is my attempt to write a version of this transform that benefits the deep-vector case and is fast enough to run in InstSimplify.
The benchmark suite indicates that this is effective.
Use llvm.memset.p0i8.* to initialize all same-bytes arrays
Similar to #43488
debug builds can now handle `0x0101_u16` and other multi-byte scalars that have all the same bytes (instead of special casing just `0`)
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:5
|
LL | object = &object2;
| ^^^^^^
|
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:1:9
|
LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^^^
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object2(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument, trying to avoid an E0308.
```
error[E0308]: mismatched types
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:6:14
|
LL | fn change_object(mut object: &Object) {
| ------- expected due to this parameter type
LL | let object2 = Object;
LL | object = object2;
| ^^^^^^^ expected `&Object`, found `Object`
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument. We avoid suggesting `object = &object2;`, as that is less likely to be what was intended.
When we encounter a constant in a pattern, we check if it is non-structural. If so, we check if the type implements `PartialEq`, but for types with escaping bound vars the check would be incorrect as is, so we break early. This is ok because these types would be filtered anyways.
Fix#134764.