Remove some unnecessary lifetimes.
We have a number of structs with more lifetimes than necessary. This commit removes them.
LLM disclosure: I asked Claude Code to check for unnecessary lifetimes in all types with three or more lifetimes, and it produced a list of candidates (half of which were invalid). I did the modifications for the valid cases myself, and found a couple more cases along the way.
r? @JohnTitor
Fix an ICE observed with an explicit tail-call in a default trait method
Right now, explicit tail-calls cannot be used in functions that hold the `#[track_caller]` attribute. This check is performed on a resolved concrete instance of a function, which would be absent for a tail-call performed from the body of a default trait method. This PR fixes the issue by checking for the relevant attribute in default trait methods separately, without expecting a specific resolved instance.
Closes https://github.com/rust-lang/rust/issues/144985.
The logic determining whether the relevant function is marked as `#[track_caller]`
only worked with functions that could be resolved to a concrete instance, which default
trait methods cannot. We need to check the codegen attribute on the default method itself.
Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
We have a number of structs with more lifetimes than necessary. This
commit removes them.
LLM disclosure: I asked Claude Code to check for unnecessary lifetimes
in all types with three or more lifetimes, and it produced a list of
candidates (half of which were invalid). I did the modifications for the
valid cases myself, and found a couple more cases along the way.
Refactor FnDecl and FnSig non-type fields into a new wrapper type
#### Why this Refactor?
This PR is part of an initial cleanup for the [arg splat experiment](https://github.com/rust-lang/rust/issues/153629), but it's a useful refactor by itself.
It refactors the non-type fields of `FnDecl`, `FnSig`, and `FnHeader` into a new packed wrapper types, based on this comment in the `splat` experiment PR:
https://github.com/rust-lang/rust/pull/153697#discussion_r3004637413
It also refactors some common `FnSig` creation settings into their own methods. I did this instead of creating a struct with defaults.
#### Relationship to `splat` Experiment
I don't think we can use functional struct updates (`..default()`) to create `FnDecl` and `FnSig`, because we need the bit-packing for the `splat` experiment.
Bit-packing will avoid breaking "type is small" assertions for commonly used types when `splat` is added.
This PR packs these types:
- ExternAbi: enum + `unwind` variants (38) -> 6 bits
- ImplicitSelfKind: enum variants (5) -> 3 bits
- lifetime_elision_allowed, safety, c_variadic: bool -> 1 bit
#### Minor Changes
Fixes some typos, and applies rustfmt to clippy files that got skipped somehow.
match exhaustiveness: Show the guard exhaustivity note only when it's the guards alone that cause non-exhaustiveness
Only show the "match arms with guards don't count towards exhaustivity" note when removing all guards would make the match exhaustive, but also in the cases when the match contains arms without guards. Previously, this note was shown only if all arms had guards, but even if the patterns themselves were insufficient to cover all valid values of a type.
Do this by rerunning the exhaustiveness analysis with guards stripped to determine whether the guards are actually the cause of non-exhaustiveness. This only happens on an actual exhaustiveness error, so should not be a performance concern.
This will make a program like:
```rust
fn main() {
let some_condition = true;
let some_option: Option<u8> = None;
let _res = match some_option {
Some(val) if some_condition => val,
None => 0,
};
}
```
produce the note ”match arms with guards don't count towards exhaustivity” that previously would not have been appearing.
Closesrust-lang/rust#104653 as I think this addresses the spirit of that issue. I don’t believe it’s necessary to be any more elaborate in the diagnostics here?
Don't store `pattern_ty` in `TestableCase`
This field's only remaining use was in an assertion, but we can perform the same assertion earlier when constructing `TestableCase::Range`.
---
For background, the `pattern_ty` field was introduced in https://github.com/rust-lang/rust/pull/136435 to replace a reference to the full THIR pattern node. Since then, most uses of `pattern_ty` were removed by https://github.com/rust-lang/rust/pull/150238.
Only show the "match arms with guards don't count towards exhaustivity"
note when removing all guards would make the match exhaustive. Previously,
this note was shown whenever all arms had guards, even if the patterns
themselves were insufficient to cover all valid values of a type.
Re-run the exhaustiveness analysis with guards stripped to determine
whether the guards are actually the cause of non-exhaustiveness. This only happens
on an actual exhaustiveness error, so should not be a performance concern.
refactor: remove `Adjust::ReborrowPin`
Followed by rust-lang/rust#149130, this PR removes `Adjust::ReborrowPin` and use an `Adjust::Deref(DerefAdjustKind::Pin)` followed by an `Adjust::Borrow(AutoBorrow::Pin)` instead.
Suggest using equality comparison instead of pattern matching on non-structural constant in pattern
When encountering a pattern containing a non-structural constant (not marked as `#[derive(PartialEq)]` to make it suitable for pattern matching, `C` in the examples below), we would previously not provide additional guidance. With this PR, the `help` in the following examples are added:
```
error: constant of non-structural type `partial_eq::S` in a pattern
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:16:18
|
LL | struct S;
| -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: S = S;
| ---------- constant defined here
...
LL | Some(C) => {}
| ^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
|
LL | impl PartialEq<S> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^
help: add a condition to the match arm checking for equality
|
LL - Some(C) => {}
LL + Some(binding) if binding == C => {}
|
```
```
error: constant of non-structural type `partial_eq::S` in a pattern
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:22:18
|
LL | struct S;
| -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: S = S;
| ---------- constant defined here
...
LL | let Some(C) = Some(S) else { return; };
| ^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
|
LL | impl PartialEq<S> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^
help: check for equality instead of pattern matching
|
LL - let Some(C) = Some(S) else { return; };
LL + if Some(C) == Some(S) { return; };
|
```
The suggestion accounts for a few conditions:
- if the type is not from the local crate and has no `PartialEq` impl, the user can't make it structural, so we don't provide the suggestion
- regardless of whether the type is local or remote, if it has a manual `PartialEq`, explain that with a derived `PartialEq` you could use equality
- if the type is local and has no impl, suggest adding a derived `PartialEq` and use equality check instead of pattern matching
- when suggesting equality, account for `if-let` to suggest chaining (edition dependent), `match` arm with a present `if` check, `match` arm without an existing `if` check
- when encountering `let-else`, we suggest turning it into an `if` expression instead (this doesn't check for additional bindings beyond the constant, which would suggest incorrect code in some more complex cases).
Fixrust-lang/rust#42753.
Simplify find_attr! for HirId usage
Add a `HasAttrs<'tcx, Tcx>` trait to `rustc_hir` that allows `find_attr!` to accept `DefId`, `LocalDefId`, `OwnerId`, and `HirId` directly, instead of requiring callers to manually fetch the attribute slice first.
Before:
`find_attr!(tcx.hir_attrs(hir_id), SomeAttr)`
After:
`find_attr!(tcx, hir_id, SomeAttr)`
The trait is defined in `rustc_hir` with a generic `Tcx` parameter to avoid a dependency cycle (`rustc_hir` cannot depend on `rustc_middle`). The four concrete impls for `TyCtxt` are in `rustc_middle`.
Fixes https://github.com/rust-lang/rust/issues/153103
Guard patterns: lowering to THIR
This pr implements lowering of guard patterns to THIR
r? @Nadrieril
cc @max-niederman
Tracking issue: rust-lang/rust#129967
```
error: constant of non-structural type `partial_eq::S` in a pattern
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:22:18
|
LL | struct S;
| -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: S = S;
| ---------- constant defined here
...
LL | let Some(C) = Some(S) else { return; };
| ^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
|
LL | impl PartialEq<S> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^
help: check for equality instead of pattern matching
|
LL - let Some(C) = Some(S) else { return; };
LL + if Some(C) == Some(S) { return; };
|
```
```
error: constant of non-structural type `partial_eq::S` in a pattern
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:16:18
|
LL | struct S;
| -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: S = S;
| ---------- constant defined here
...
LL | Some(C) => {}
| ^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5
|
LL | impl PartialEq<S> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^
help: add a condition to the match arm checking for equality
|
LL - Some(C) => {}
LL + Some(binding) if binding == C => {}
|
```
Add a HasAttrs<'tcx, Tcx> trait to rustc_hir that allows find_attr! to
accept DefId, LocalDefId, OwnerId, and HirId directly, instead of
requiring callers to manually fetch the attribute slice first.
The trait is defined in rustc_hir with a generic Tcx parameter to avoid
a dependency cycle (rustc_hir cannot depend on rustc_middle). The four
concrete impls for TyCtxt are in rustc_middle.
Move `Spanned`.
It's defined in `rustc_span::source_map` which doesn't make any sense because it has nothing to do with source maps. This commit moves it to the crate root, a more sensible spot for something this basic.
r? @JonathanBrouwer
It's defined in `rustc_span::source_map` which doesn't make any sense
because it has nothing to do with source maps. This commit moves it to
the crate root, a more sensible spot for something this basic.
Overhaul `ensure_ok`
The interaction of `ensure_ok` and the `return_result_from_ensure_ok` query modifier is weird and hacky. This PR cleans it up. Details in the individual commits.
r? @Zalathar
`ensure_ok` provides a special, more efficient way of calling a query
when its return value isn't needed. But there is a complication: if the
query is marked with the `return_result_from_ensure_ok` modifier, then
it will return `Result<(), ErrorGuaranteed`. This is clunky and feels
tacked on. It's annoying to have to add a modifier to a query to declare
information present in its return type, and it's confusing that queries
called via `ensure_ok` have different return types depending on the
modifier.
This commit:
- Eliminates the `return_result_from_ensure_ok` modifier. The proc macro
now looks at the return type and detects if it matches `Result<_,
ErrorGuarantee>`. If so, it adds the modifier
`returns_error_guaranteed`. (Aside: We need better terminology to
distinguish modifiers written by the user in a `query` declaration
(e.g. `cycle_delayed_bug`) from modifiers added by the proc macro
(e.g. `cycle_error_handling`.))
- Introduces `ensure_result`, which replaces the use of `ensure_ok` for
queries that return `Result<_, ErrorGuarantee>`. As a result,
`ensure_ok` can now only be used for the "ignore the return value"
case.
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
Box in `ValTreeKind::Branch(Box<[I::Const]>)` changed to `List`
This is related to trait system refactoring. It fixes the FIXME in `ValTreeKind`
```
// FIXME(mgca): Use a `List` here instead of a boxed slice
Branch(Box<[I::Const]>),
```
It introduces `Interner::Consts`, changes `Branch(Box<[I::Const]>)` to `Branch(I::Consts)`, and updates all relevant places.
r? lcnr
fix(thir): Include `NoneWithError` in Enum Struct Tail Assertion
### Summary:
Fixes the ICE triggered when a syntax error appears inside an enum variant struct literal.
PR rust-lang/rust#153227 added `StructTailExpr::NoneWithError` and updated the `match base` arm in the `AdtKind::Enum` branch of `thir/cx/expr.rs`, but overlooked the `assert!(matches!(...))` guard preceding it, which still only listed `None | DefaultFields(_)`.
Closesrust-lang/rust#153390
r? @dingxiangfei2009
cc @matthiaskrgr