Fix `ElaborateBoxDerefs` on debug varinfo
Slightly simplifies the `ElaborateBoxDerefs` pass to fix cases where it was applying the wrong projections to debug var infos containing places that deref boxes.
From what I can tell[^1], we don't actually have any tests (or code anywhere, really) that exercise `debug x => *(...: Box<T>)`, and it's very difficult to trigger this in surface Rust, so I wrote a custom MIR test.
What happens is that the pass was turning `*(SOME_PLACE: Box<T>)` into `*(*((((SOME_PLACE).0: Unique<T>).0: NonNull<T>).0: *const T))` in debug var infos. In particular, notice the *double deref*, which was wrong.
This is the root cause of #128554, so this PR fixes#128554 as well. The reason that async closures was affected is because of the way that we compute the [`ByMove` body](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs), which resulted in `*(...: Box<T>)` in debug var info. But this really has nothing to do with async closures.
[^1]: Validated by literally replacing the `if elem == PlaceElem::Deref && base_ty.is_box() { ... }` innards with a `panic!()`, which compiled all of stage2 without panicking.
Improve `Ord` violation help
Recent experience in #128083 showed that the panic message when an Ord violation is detected by the new sort implementations can be confusing. So this PR aims to improve it, together with minor bug fixes in the doc comments for sort*, sort_unstable* and select_nth_unstable*.
Is it possible to get these changes into the 1.81 release? It doesn't change behavior and would greatly help when users encounter this panic for the first time, which they may after upgrading to 1.81.
Tagging `@orlp`
Stabilize `min_exhaustive_patterns`
## Stabilisation report
I propose we stabilize the [`min_exhaustive_patterns`](https://github.com/rust-lang/rust/issues/119612) language feature.
With this feature, patterns of empty types are considered unreachable when matched by-value. This allows:
```rust
enum Void {}
fn foo() -> Result<u32, Void>;
fn main() {
let Ok(x) = foo();
// also
match foo() {
Ok(x) => ...,
}
}
```
This is a subset of the long-unstable [`exhaustive_patterns`](https://github.com/rust-lang/rust/issues/51085) feature. That feature is blocked because omitting empty patterns is tricky when *not* matched by-value. This PR stabilizes the by-value case, which is not tricky.
The not-by-value cases (behind references, pointers, and unions) stay as they are today, e.g.
```rust
enum Void {}
fn foo() -> Result<u32, &Void>;
fn main() {
let Ok(x) = foo(); // ERROR: missing `Err(_)`
}
```
The consequence on existing code is some extra "unreachable pattern" warnings. This is fully backwards-compatible.
### Comparison with today's rust
This proposal only affects match checking of empty types (i.e. types with no valid values). Non-empty types behave the same with or without this feature. Note that everything below is phrased in terms of `match` but applies equallly to `if let` and other pattern-matching expressions.
To be precise, a visibly empty type is:
- an enum with no variants;
- the never type `!`;
- a struct with a *visible* field of a visibly empty type (and no #[non_exhaustive] annotation);
- a tuple where one of the types is visibly empty;
- en enum with all variants visibly empty (and no `#[non_exhaustive]` annotation);
- a `[T; N]` with `N != 0` and `T` visibly empty;
- all other types are nonempty.
(An extra change was proposed below: that we ignore #[non_exhaustive] for structs since adding fields cannot turn an empty struct into a non-empty one)
For normal types, exhaustiveness checking requires that we list all variants (or use a wildcard). For empty types it's more subtle: in some cases we require a `_` pattern even though there are no valid values that can match it. This is where the difference lies regarding this feature.
#### Today's rust
Under today's rust, a `_` is required for all empty types, except specifically: if the matched expression is of type `!` (the never type) or `EmptyEnum` (where `EmptyEnum` is an enum with no variants), then the `_` is not required.
```rust
let foo: Result<u32, !> = ...;
match foo {
Ok(x) => ...,
Err(_) => ..., // required
}
let foo: Result<u32, &!> = ...;
match foo {
Ok(x) => ...,
Err(_) => ..., // required
}
let foo: &! = ...;
match foo {
_ => ..., // required
}
fn blah(foo: (u32, !)) {
match foo {
_ => ..., // required
}
}
unsafe {
let ptr: *const ! = ...;
match *ptr {} // allowed
let ptr: *const (u32, !) = ...;
match *ptr {
(x, _) => { ... } // required
}
let ptr: *const Result<u32, !> = ...;
match *ptr {
Ok(x) => { ... }
Err(_) => { ... } // required
}
}
```
#### After this PR
After this PR, a pattern of an empty type can be omitted if (and only if):
- the match scrutinee expression has type `!` or `EmptyEnum` (like before);
- *or* the empty type is matched by value (that's the new behavior).
In all other cases, a `_` is required to match on an empty type.
```rust
let foo: Result<u32, !> = ...;
match foo {
Ok(x) => ..., // `Err` not required
}
let foo: Result<u32, &!> = ...;
match foo {
Ok(x) => ...,
Err(_) => ..., // required because `!` is under a dereference
}
let foo: &! = ...;
match foo {
_ => ..., // required because `!` is under a dereference
}
fn blah(foo: (u32, !)) {
match foo {} // allowed
}
unsafe {
let ptr: *const ! = ...;
match *ptr {} // allowed
let ptr: *const (u32, !) = ...;
match *ptr {
(x, _) => { ... } // required because the matched place is under a (pointer) dereference
}
let ptr: *const Result<u32, !> = ...;
match *ptr {
Ok(x) => { ... }
Err(_) => { ... } // required because the matched place is under a (pointer) dereference
}
}
```
### Documentation
The reference does not say anything specific about exhaustiveness checking, hence there is nothing to update there. The nomicon does, I opened https://github.com/rust-lang/nomicon/pull/445 to reflect the changes.
### Tests
The relevant tests are in `tests/ui/pattern/usefulness/empty-types.rs`.
### Unresolved Questions
None that I know of.
try-job: dist-aarch64-apple
A configurable recursion limit was introduced by looking at the
recursion_limit crate attribute. Instead of relying on a global constant
we will reuse this value for expansion limit as well.
internal: Move and split flycheck crate into rust-analyzer main crate
The crate no longer is about flychecking, it mainly hosts common command process handling shared by flycheck, test explorer and now project discovery. This re-organizes that into the main crate.
Improve crate manifest of 'syntax-bridge', adding missing `[package.repository]` and `[package.description]` fields
This is a follow-up of https://github.com/rust-lang/rust-analyzer/pull/17745, specifically [this comment](https://github.com/rust-lang/rust-analyzer/pull/17745#issuecomment-2271102382) by `@lnicola.`
It refines the manifest of the newly added 'syntax-bridge' crate, adding a `[package.repository]` as `workspace = true` and changes the existing `[package.description]` from "TBD" to a more useful description.
Include vendored crates in StaticIndex
`StaticIndex::compute` filters out modules from libraries. This makes an exceptions for vendored libraries, ie libraries actually defined inside the workspace being indexed.
This aims to solve https://bugzilla.mozilla.org/show_bug.cgi?id=1846041 In general StaticIndex is meant for code browsers, which likely want to index all visible source files.
fix: tyck for non-ADT types when searching refs for `Self` kw
See e0276dc5dd (r1389848845)
For ADTs, to handle `{error}` in generic args, we should to convert them to ADT for comparisons; for others, we can directly compare the types.
StaticIndex::compute filters out modules from libraries. This makes an
exceptions for vendored libraries, ie libraries actually defined inside
the workspace being indexed.
This aims to solve https://bugzilla.mozilla.org/show_bug.cgi?id=1846041
In general StaticIndex is meant for code browsers, which likely want to
index all visible source files.
Change output normalization logic to be linear against size of output
Modify the rendered output normalization routine to scan each character *once* and construct a `String` to be printed out to the terminal *once*, instead of using `String::replace` in a loop multiple times. The output doesn't change, but the time spent to prepare a diagnostic is now faster (or rather, closer to what it was before #127528).
Tweak type inference for `const` operands in inline asm
Previously these would be treated like integer literals and default to `i32` if a type could not be determined. To allow for forward-compatibility with `str` constants in the future, this PR changes type inference to use an unbound type variable instead.
The actual type checking is deferred until after typeck where we still ensure that the final type for the `const` operand is an integer type.
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->