Rollup merge of #155549 - nnethercote:rm-lifetimes, r=JohnTitor

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
This commit is contained in:
Jonathan Brouwer
2026-04-20 13:52:07 +02:00
committed by GitHub
8 changed files with 64 additions and 66 deletions
+2 -2
View File
@@ -107,7 +107,7 @@ fn on_successor_discovered(&mut self, current_node: LocalizedNode, successor: Lo
/// - a mermaid graph of the NLL regions and the constraints between them
/// - a mermaid graph of the NLL SCCs and the constraints between them
fn emit_polonius_dump<'tcx>(
dumper: &MirDumper<'_, '_, 'tcx>,
dumper: &MirDumper<'_, 'tcx>,
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &BorrowSet<'tcx>,
@@ -186,7 +186,7 @@ fn emit_polonius_dump<'tcx>(
/// Emits the polonius MIR, as escaped HTML.
fn emit_html_mir<'tcx>(
dumper: &MirDumper<'_, '_, 'tcx>,
dumper: &MirDumper<'_, 'tcx>,
body: &Body<'tcx>,
out: &mut dyn io::Write,
) -> io::Result<()> {
+27 -27
View File
@@ -1901,14 +1901,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
struct FnCallDiagCtxt<'a, 'b, 'tcx> {
arg_matching_ctxt: ArgMatchingCtxt<'a, 'b, 'tcx>,
struct FnCallDiagCtxt<'a, 'tcx> {
arg_matching_ctxt: ArgMatchingCtxt<'a, 'tcx>,
errors: Vec<Error<'tcx>>,
matched_inputs: IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
}
impl<'a, 'b, 'tcx> Deref for FnCallDiagCtxt<'a, 'b, 'tcx> {
type Target = ArgMatchingCtxt<'a, 'b, 'tcx>;
impl<'a, 'tcx> Deref for FnCallDiagCtxt<'a, 'tcx> {
type Target = ArgMatchingCtxt<'a, 'tcx>;
fn deref(&self) -> &Self::Target {
&self.arg_matching_ctxt
@@ -1921,9 +1921,9 @@ enum ArgumentsFormatting {
Multiline { fallback_indent: String, brace_indent: String },
}
impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> {
impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
fn new(
arg: &'a FnCtxt<'b, 'tcx>,
arg: &'a FnCtxt<'a, 'tcx>,
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
provided_args: IndexVec<ProvidedIdx, &'tcx Expr<'tcx>>,
@@ -2618,7 +2618,7 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
(suggestions, labels, suggestion_text)
}
fn label_generic_mismatches(&self, err: &mut Diag<'b>) {
fn label_generic_mismatches(&self, err: &mut Diag<'a>) {
self.fn_ctxt.label_generic_mismatches(
err,
self.fn_def_id,
@@ -2778,22 +2778,22 @@ fn suggestion_code(&self) -> (Span, String) {
}
}
struct ArgMatchingCtxt<'a, 'b, 'tcx> {
args_ctxt: ArgsCtxt<'a, 'b, 'tcx>,
struct ArgMatchingCtxt<'a, 'tcx> {
args_ctxt: ArgsCtxt<'a, 'tcx>,
provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)>,
}
impl<'a, 'b, 'tcx> Deref for ArgMatchingCtxt<'a, 'b, 'tcx> {
type Target = ArgsCtxt<'a, 'b, 'tcx>;
impl<'a, 'tcx> Deref for ArgMatchingCtxt<'a, 'tcx> {
type Target = ArgsCtxt<'a, 'tcx>;
fn deref(&self) -> &Self::Target {
&self.args_ctxt
}
}
impl<'a, 'b, 'tcx> ArgMatchingCtxt<'a, 'b, 'tcx> {
impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> {
fn new(
arg: &'a FnCtxt<'b, 'tcx>,
arg: &'a FnCtxt<'a, 'tcx>,
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
provided_args: IndexVec<ProvidedIdx, &'tcx Expr<'tcx>>,
@@ -2924,23 +2924,23 @@ fn remove_idx_is_perfect(&self, idx: usize) -> bool {
}
}
struct ArgsCtxt<'a, 'b, 'tcx> {
call_ctxt: CallCtxt<'a, 'b, 'tcx>,
struct ArgsCtxt<'a, 'tcx> {
call_ctxt: CallCtxt<'a, 'tcx>,
call_metadata: CallMetadata,
args_span: Span,
}
impl<'a, 'b, 'tcx> Deref for ArgsCtxt<'a, 'b, 'tcx> {
type Target = CallCtxt<'a, 'b, 'tcx>;
impl<'a, 'tcx> Deref for ArgsCtxt<'a, 'tcx> {
type Target = CallCtxt<'a, 'tcx>;
fn deref(&self) -> &Self::Target {
&self.call_ctxt
}
}
impl<'a, 'b, 'tcx> ArgsCtxt<'a, 'b, 'tcx> {
impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> {
fn new(
arg: &'a FnCtxt<'b, 'tcx>,
arg: &'a FnCtxt<'a, 'tcx>,
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
provided_args: IndexVec<ProvidedIdx, &'tcx Expr<'tcx>>,
@@ -2951,7 +2951,7 @@ fn new(
call_expr: &'tcx Expr<'tcx>,
tuple_arguments: TupleArgumentsFlag,
) -> Self {
let call_ctxt: CallCtxt<'_, '_, '_> = CallCtxt::new(
let call_ctxt: CallCtxt<'_, '_> = CallCtxt::new(
arg,
compatibility_diagonal,
formal_and_expected_inputs,
@@ -3058,8 +3058,8 @@ struct CallMetadata {
is_method: bool,
}
struct CallCtxt<'a, 'b, 'tcx> {
fn_ctxt: &'a FnCtxt<'b, 'tcx>,
struct CallCtxt<'a, 'tcx> {
fn_ctxt: &'a FnCtxt<'a, 'tcx>,
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
@@ -3073,17 +3073,17 @@ struct CallCtxt<'a, 'b, 'tcx> {
callee_ty: Option<Ty<'tcx>>,
}
impl<'a, 'b, 'tcx> Deref for CallCtxt<'a, 'b, 'tcx> {
type Target = &'a FnCtxt<'b, 'tcx>;
impl<'a, 'tcx> Deref for CallCtxt<'a, 'tcx> {
type Target = &'a FnCtxt<'a, 'tcx>;
fn deref(&self) -> &Self::Target {
&self.fn_ctxt
}
}
impl<'a, 'b, 'tcx> CallCtxt<'a, 'b, 'tcx> {
impl<'a, 'tcx> CallCtxt<'a, 'tcx> {
fn new(
fn_ctxt: &'a FnCtxt<'b, 'tcx>,
fn_ctxt: &'a FnCtxt<'a, 'tcx>,
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
@@ -3093,7 +3093,7 @@ fn new(
call_span: Span,
call_expr: &'tcx hir::Expr<'tcx>,
tuple_arguments: TupleArgumentsFlag,
) -> CallCtxt<'a, 'b, 'tcx> {
) -> CallCtxt<'a, 'tcx> {
let callee_expr = match &call_expr.peel_blocks().kind {
hir::ExprKind::Call(callee, _) => Some(*callee),
hir::ExprKind::MethodCall(_, receiver, ..) => {
@@ -16,15 +16,15 @@
use crate::FnCtxt;
use crate::method::probe::{self, Pick};
struct AmbiguousTraitMethodCall<'a, 'b, 'tcx> {
struct AmbiguousTraitMethodCall<'a, 'tcx> {
segment_name: Symbol,
self_expr_span: Span,
pick: &'a Pick<'tcx>,
tcx: TyCtxt<'tcx>,
edition: &'b str,
edition: &'static str,
}
impl<'a, 'b, 'c, 'tcx> Diagnostic<'a, ()> for AmbiguousTraitMethodCall<'b, 'c, 'tcx> {
impl<'a, 'b, 'tcx> Diagnostic<'a, ()> for AmbiguousTraitMethodCall<'b, 'tcx> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let Self { segment_name, self_expr_span, pick, tcx, edition } = self;
let mut lint = Diag::new(
@@ -80,20 +80,18 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
}
}
struct AmbiguousTraitMethod<'a, 'b, 'tcx, 'pcx, 'fnctx> {
segment: &'a hir::PathSegment<'pcx>,
struct AmbiguousTraitMethod<'a, 'tcx, 'fnctx> {
segment: &'a hir::PathSegment<'tcx>,
call_expr: &'tcx hir::Expr<'tcx>,
self_expr: &'tcx hir::Expr<'tcx>,
pick: &'a Pick<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
edition: &'b str,
edition: &'static str,
span: Span,
this: &'a FnCtxt<'fnctx, 'tcx>,
}
impl<'a, 'b, 'c, 'tcx, 'pcx, 'fnctx> Diagnostic<'a, ()>
for AmbiguousTraitMethod<'b, 'c, 'tcx, 'pcx, 'fnctx>
{
impl<'a, 'c, 'tcx, 'fnctx> Diagnostic<'a, ()> for AmbiguousTraitMethod<'c, 'tcx, 'fnctx> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let Self { segment, call_expr, self_expr, pick, args, edition, span, this } = self;
let mut lint = Diag::new(
@@ -158,7 +156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(super) fn lint_edition_dependent_dot_call(
&self,
self_ty: Ty<'tcx>,
segment: &hir::PathSegment<'_>,
segment: &hir::PathSegment<'tcx>,
span: Span,
call_expr: &'tcx hir::Expr<'tcx>,
self_expr: &'tcx hir::Expr<'tcx>,
+6 -6
View File
@@ -958,15 +958,15 @@ fn perform_2229_migration_analysis(
capture_clause: hir::CaptureBy,
span: Span,
) {
struct MigrationLint<'a, 'b, 'tcx> {
struct MigrationLint<'a, 'tcx> {
closure_def_id: LocalDefId,
this: &'a FnCtxt<'b, 'tcx>,
this: &'a FnCtxt<'a, 'tcx>,
body_id: hir::BodyId,
need_migrations: Vec<NeededMigration>,
migration_message: String,
}
impl<'a, 'b, 'c, 'tcx> Diagnostic<'a, ()> for MigrationLint<'b, 'c, 'tcx> {
impl<'a, 'b, 'tcx> Diagnostic<'a, ()> for MigrationLint<'b, 'tcx> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let Self { closure_def_id, this, body_id, need_migrations, migration_message } =
self;
@@ -2084,8 +2084,8 @@ fn drop_location_span(tcx: TyCtxt<'_>, hir_id: HirId) -> Span {
tcx.sess.source_map().end_point(owner_span)
}
struct InferBorrowKind<'fcx, 'a, 'tcx> {
fcx: &'fcx FnCtxt<'a, 'tcx>,
struct InferBorrowKind<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
// The def-id of the closure whose kind and upvar accesses are being inferred.
closure_def_id: LocalDefId,
@@ -2119,7 +2119,7 @@ struct InferBorrowKind<'fcx, 'a, 'tcx> {
fake_reads: Vec<(Place<'tcx>, FakeReadCause, HirId)>,
}
impl<'fcx, 'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'fcx, 'a, 'tcx> {
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn fake_read(
&mut self,
@@ -156,15 +156,15 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
}
}
struct WrongDefaultImpl<'a, 'hir, 'tcx> {
struct WrongDefaultImpl<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
type_def_id: DefId,
orig_fields: FxHashMap<Symbol, &'a hir::FieldDef<'hir>>,
fields: &'a [hir::ExprField<'hir>],
orig_fields: FxHashMap<Symbol, &'a hir::FieldDef<'tcx>>,
fields: &'a [hir::ExprField<'tcx>],
impl_span: Span,
}
impl<'a, 'b, 'hir, 'tcx> Diagnostic<'a, ()> for WrongDefaultImpl<'b, 'hir, 'tcx> {
impl<'a, 'b, 'tcx> Diagnostic<'a, ()> for WrongDefaultImpl<'b, 'tcx> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let Self { tcx, type_def_id, orig_fields, fields, impl_span } = self;
let mut diag =
+10 -10
View File
@@ -61,14 +61,14 @@ pub fn from_cli(tcx: TyCtxt<'_>) -> Self {
/// Manages MIR dumping, which is MIR writing done to a file with a specific name. In particular,
/// it makes it impossible to dump MIR to one of these files when it hasn't been requested from the
/// command line. Layered on top of `MirWriter`, which does the actual writing.
pub struct MirDumper<'dis, 'de, 'tcx> {
pub struct MirDumper<'a, 'tcx> {
show_pass_num: bool,
pass_name: &'static str,
disambiguator: &'dis dyn Display,
writer: MirWriter<'de, 'tcx>,
disambiguator: &'a dyn Display,
writer: MirWriter<'a, 'tcx>,
}
impl<'dis, 'de, 'tcx> MirDumper<'dis, 'de, 'tcx> {
impl<'a, 'tcx> MirDumper<'a, 'tcx> {
// If dumping should be performed (e.g. because it was requested on the
// CLI), returns a `MirDumper` with default values for the following fields:
// - `show_pass_num`: `false`
@@ -112,7 +112,7 @@ pub fn set_show_pass_num(mut self) -> Self {
}
#[must_use]
pub fn set_disambiguator(mut self, disambiguator: &'dis dyn Display) -> Self {
pub fn set_disambiguator(mut self, disambiguator: &'a dyn Display) -> Self {
self.disambiguator = disambiguator;
self
}
@@ -120,7 +120,7 @@ pub fn set_disambiguator(mut self, disambiguator: &'dis dyn Display) -> Self {
#[must_use]
pub fn set_extra_data(
mut self,
extra_data: &'de dyn Fn(PassWhere, &mut dyn io::Write) -> io::Result<()>,
extra_data: &'a dyn Fn(PassWhere, &mut dyn io::Write) -> io::Result<()>,
) -> Self {
self.writer.extra_data = extra_data;
self
@@ -369,13 +369,13 @@ pub fn write_mir_pretty<'tcx>(
}
/// Does the writing of MIR to output, e.g. a file.
pub struct MirWriter<'de, 'tcx> {
pub struct MirWriter<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
extra_data: &'de dyn Fn(PassWhere, &mut dyn io::Write) -> io::Result<()>,
extra_data: &'a dyn Fn(PassWhere, &mut dyn io::Write) -> io::Result<()>,
options: PrettyPrintMirOptions,
}
impl<'de, 'tcx> MirWriter<'de, 'tcx> {
impl<'a, 'tcx> MirWriter<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
MirWriter { tcx, extra_data: &|_, _| Ok(()), options: PrettyPrintMirOptions::from_cli(tcx) }
}
@@ -709,7 +709,7 @@ pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option<DefId>) -> Vec<DefId> {
///////////////////////////////////////////////////////////////////////////
// Basic blocks and their parts (statements, terminators, ...)
impl<'de, 'tcx> MirWriter<'de, 'tcx> {
impl<'a, 'tcx> MirWriter<'a, 'tcx> {
/// Write out a human-readable textual representation for the given basic block.
fn write_basic_block(
&self,
+3 -3
View File
@@ -649,14 +649,14 @@ pub(crate) enum UnusedUnsafeEnclosing {
},
}
pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
pub(crate) cx: &'m RustcPatCtxt<'p, 'tcx>,
pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'a, 'tcx> {
pub(crate) cx: &'a RustcPatCtxt<'a, 'tcx>,
pub(crate) scrut_span: Span,
pub(crate) braces_span: Option<Span>,
pub(crate) ty: Ty<'tcx>,
}
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let mut diag =
Diag::new(dcx, level, msg!("non-exhaustive patterns: type `{$ty}` is non-empty"));
@@ -37,14 +37,14 @@ struct StaticSccIdx {}
// Adjacency-list graph for statics using `StaticNodeIdx` as node type.
// We cannot use `DefId` as the node type directly because each node must be
// represented by an index in the range `0..num_nodes`.
struct StaticRefGraph<'a, 'b, 'tcx> {
struct StaticRefGraph<'a, 'tcx> {
// maps from `StaticNodeIdx` to `DefId` and vice versa
statics: &'a FxIndexSet<DefId>,
// contains for each `MonoItem` the `MonoItem`s it uses
used_map: &'b UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
used_map: &'a UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
}
impl<'a, 'b, 'tcx> DirectedGraph for StaticRefGraph<'a, 'b, 'tcx> {
impl<'a, 'tcx> DirectedGraph for StaticRefGraph<'a, 'tcx> {
type Node = StaticNodeIdx;
fn num_nodes(&self) -> usize {
@@ -52,7 +52,7 @@ fn num_nodes(&self) -> usize {
}
}
impl<'a, 'b, 'tcx> Successors for StaticRefGraph<'a, 'b, 'tcx> {
impl<'a, 'tcx> Successors for StaticRefGraph<'a, 'tcx> {
fn successors(&self, node_idx: StaticNodeIdx) -> impl Iterator<Item = StaticNodeIdx> {
let def_id = self.statics[node_idx.index()];
self.used_map[&MonoItem::Static(def_id)].iter().filter_map(|&mono_item| match mono_item {