From 685984a780041b8e5dc51a83439db81b3f5e3151 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 May 2026 08:53:22 +0200 Subject: [PATCH 1/8] Merge two functions always called after each other --- compiler/rustc_resolve/src/late.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index fb8de90d28aca..dfea0f45ec7dd 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -27,7 +27,7 @@ use rustc_errors::{ use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate}; +use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility}; use rustc_middle::{bug, span_bug}; @@ -4780,8 +4780,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // it needs to be added to the trait map. if ns == ValueNS { let item_name = path.last().unwrap().ident; - let traits = self.traits_in_scope(item_name, ns); - self.r.trait_map.insert(node_id, traits); + self.record_traits_in_scope(node_id, item_name); } if PrimTy::from_name(path[0].ident.name).is_some() { @@ -5382,13 +5381,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // we need to add any trait methods we find that match the // field name so that we can do some nice error reporting // later on in typeck. - let traits = self.traits_in_scope(ident, ValueNS); - self.r.trait_map.insert(expr.id, traits); + self.record_traits_in_scope(expr.id, ident); } ExprKind::MethodCall(ref call) => { debug!("(recording candidate traits for expr) recording traits for {}", expr.id); - let traits = self.traits_in_scope(call.seg.ident, ValueNS); - self.r.trait_map.insert(expr.id, traits); + self.record_traits_in_scope(expr.id, call.seg.ident); } _ => { // Nothing to do. @@ -5396,13 +5393,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } - fn traits_in_scope(&mut self, ident: Ident, ns: Namespace) -> &'tcx [TraitCandidate<'tcx>] { - self.r.traits_in_scope( + fn record_traits_in_scope(&mut self, node_id: NodeId, ident: Ident) { + let traits = self.r.traits_in_scope( self.current_trait_ref.as_ref().map(|(module, _)| *module), &self.parent_scope, ident.span, - Some((ident.name, ns)), - ) + Some((ident.name, ValueNS)), + ); + self.r.trait_map.insert(node_id, traits); } fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option { From ed8e3ba2782c602e6c3c9e1e47bd7dd6df2ab7fa Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 May 2026 09:39:54 +0200 Subject: [PATCH 2/8] Remove an unnecessary generic --- compiler/rustc_resolve/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f5f4c9e6e2580..22c4f4576d44b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -822,7 +822,7 @@ impl<'ra> Module<'ra> { } /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx>(self, resolver: &impl AsRef>) { + fn ensure_traits<'tcx>(self, resolver: &Resolver<'ra, 'tcx>) { let mut traits = self.traits.borrow_mut(resolver.as_ref()); if traits.is_none() { let mut collected_traits = Vec::new(); From 31a054c51b7965345a320b505805f1ad6951dd61 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 12:31:24 +0200 Subject: [PATCH 3/8] Add a dedicated method for error lifetime recording --- compiler/rustc_resolve/src/late.rs | 84 ++++++++++-------------------- 1 file changed, 28 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dfea0f45ec7dd..9e26acfe249e3 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -781,8 +781,7 @@ pub(crate) struct DiagMetadata<'ast> { /// Accumulate the errors due to missed lifetime elision, /// and report them all at once for each function. - current_elision_failures: - Vec<(MissingLifetime, LifetimeElisionCandidate, Either>)>, + current_elision_failures: Vec<(MissingLifetime, Either>)>, } struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { @@ -1831,20 +1830,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeRibKind::Item => break, LifetimeRibKind::ConstParamTy => { let guar = self.emit_non_static_lt_in_const_param_ty_error(lifetime); - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error(guar), - LifetimeElisionCandidate::Ignore, - ); + self.record_lifetime_err(lifetime.id, guar); return; } LifetimeRibKind::ConcreteAnonConst(cause) => { let guar = self.emit_forbidden_non_static_lifetime_error(cause, lifetime); - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error(guar), - LifetimeElisionCandidate::Ignore, - ); + self.record_lifetime_err(lifetime.id, guar); return; } LifetimeRibKind::AnonymousCreateParameter { .. } @@ -1862,11 +1853,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer)); let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res); - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error(guar), - LifetimeElisionCandidate::Named, - ); + self.record_lifetime_err(lifetime.id, guar); } #[instrument(level = "debug", skip(self))] @@ -2015,11 +2002,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { span: lifetime.ident.span, }) }; - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error(guar), - elision_candidate, - ); + self.record_lifetime_err(lifetime.id, guar); return; } LifetimeRibKind::Elided(res) => { @@ -2027,11 +2010,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; } LifetimeRibKind::ElisionFailure => { - self.diag_metadata.current_elision_failures.push(( - missing_lifetime, - elision_candidate, - Either::Left(lifetime.id), - )); + self.diag_metadata + .current_elision_failures + .push((missing_lifetime, Either::Left(lifetime.id))); return; } LifetimeRibKind::Item => break, @@ -2045,7 +2026,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } let guar = self.report_missing_lifetime_specifiers([&missing_lifetime], None); - self.record_lifetime_res(lifetime.id, LifetimeRes::Error(guar), elision_candidate); + self.record_lifetime_err(lifetime.id, guar); } fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) { @@ -2311,11 +2292,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { should_lint = false; for id in node_ids { - self.record_lifetime_res( - id, - LifetimeRes::Error(guar), - LifetimeElisionCandidate::Named, - ); + self.record_lifetime_err(id, guar); } break; } @@ -2345,11 +2322,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { break; } LifetimeRibKind::ElisionFailure => { - self.diag_metadata.current_elision_failures.push(( - missing_lifetime, - LifetimeElisionCandidate::Ignore, - Either::Right(node_ids), - )); + self.diag_metadata + .current_elision_failures + .push((missing_lifetime, Either::Right(node_ids))); break; } // `LifetimeRes::Error`, which would usually be used in the case of @@ -2360,11 +2335,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let guar = self.report_missing_lifetime_specifiers([&missing_lifetime], None); for id in node_ids { - self.record_lifetime_res( - id, - LifetimeRes::Error(guar), - LifetimeElisionCandidate::Ignore, - ); + self.record_lifetime_err(id, guar); } break; } @@ -2412,9 +2383,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { res: LifetimeRes, candidate: LifetimeElisionCandidate, ) { - if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) { - panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)") - } + self.record_lifetime_param(id, res); match res { LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => { @@ -2426,6 +2395,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } + #[instrument(level = "debug", skip(self))] + fn record_lifetime_err(&mut self, id: NodeId, guar: ErrorGuaranteed) { + self.record_lifetime_param(id, LifetimeRes::Error(guar)); + } + #[instrument(level = "debug", skip(self))] fn record_lifetime_param(&mut self, id: NodeId, res: LifetimeRes) { if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) { @@ -2470,15 +2444,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { elision_failures.iter().map(|(missing_lifetime, ..)| missing_lifetime), Some(failure_info), ); - let mut record_res = |lifetime, candidate| { - this.record_lifetime_res(lifetime, LifetimeRes::Error(guar), candidate) - }; - for (_, candidate, nodes) in elision_failures { + let mut record_res = |lifetime| this.record_lifetime_err(lifetime, guar); + for (_, nodes) in elision_failures { match nodes { - Either::Left(node_id) => record_res(node_id, candidate), + Either::Left(node_id) => record_res(node_id), Either::Right(node_ids) => { for lifetime in node_ids { - record_res(lifetime, candidate) + record_res(lifetime) } } } @@ -3146,7 +3118,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { param.ident, ); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); + self.record_lifetime_err(param.id, guar); continue; } @@ -3158,7 +3130,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let rib = match param.kind { GenericParamKind::Lifetime => { // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); + self.record_lifetime_err(param.id, guar); continue; } GenericParamKind::Type { .. } => &mut function_type_rib, @@ -3193,7 +3165,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span }) .emit_unless_delay(is_raw_underscore_lifetime); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); + self.record_lifetime_err(param.id, guar); continue; } @@ -3203,7 +3175,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { lifetime: param.ident, }); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); + self.record_lifetime_err(param.id, guar); continue; } From d8cddda134d970e81ad95ee4be548cf6cdd6f3fc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 26 May 2026 13:14:02 +0200 Subject: [PATCH 4/8] Rename and document some methods --- compiler/rustc_resolve/src/late.rs | 36 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9e26acfe249e3..1b3da5b9dcbb1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1748,7 +1748,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let ident = lifetime.ident; if ident.name == kw::StaticLifetime { - self.record_lifetime_res( + self.record_lifetime_use( lifetime.id, LifetimeRes::Static, LifetimeElisionCandidate::Named, @@ -1764,7 +1764,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { while let Some(rib) = lifetime_rib_iter.next() { let normalized_ident = ident.normalize_to_macros_2_0(); if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) { - self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named); + self.record_lifetime_use(lifetime.id, res, LifetimeElisionCandidate::Named); if let LifetimeRes::Param { param, binder } = res { match self.lifetime_uses.entry(param) { @@ -1880,7 +1880,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match rib.kind { LifetimeRibKind::AnonymousCreateParameter { binder, .. } => { let res = self.create_fresh_lifetime(lifetime.ident, binder, kind); - self.record_lifetime_res(lifetime.id, res, elision_candidate); + self.record_lifetime_use(lifetime.id, res, elision_candidate); return; } LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => { @@ -1898,7 +1898,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } if lifetimes_in_scope.is_empty() { - self.record_lifetime_res( + self.record_lifetime_use( lifetime.id, LifetimeRes::Static, elision_candidate, @@ -2006,7 +2006,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; } LifetimeRibKind::Elided(res) => { - self.record_lifetime_res(lifetime.id, res, elision_candidate); + self.record_lifetime_use(lifetime.id, res, elision_candidate); return; } LifetimeRibKind::ElisionFailure => { @@ -2123,7 +2123,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let id = self.r.next_node_id(); let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) }; - self.record_lifetime_res( + self.record_lifetime_use( anchor_id, LifetimeRes::ElidedAnchor { start: id, end: id + 1 }, LifetimeElisionCandidate::Ignore, @@ -2144,7 +2144,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Leave the responsibility to create the `LocalDefId` to lowering. let param = self.r.next_node_id(); let res = LifetimeRes::Fresh { param, binder, kind }; - self.record_lifetime_param(param, res); + self.record_lifetime_def(param, res); // Record the created lifetime parameter so lowering can pick it up and add it to HIR. self.r @@ -2207,7 +2207,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } let node_ids = self.r.next_node_ids(expected_lifetimes); - self.record_lifetime_res( + self.record_lifetime_use( segment_id, LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end }, LifetimeElisionCandidate::Ignore, @@ -2233,7 +2233,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Do not create a parameter for patterns and expressions: type checking can infer // the appropriate lifetime for us. for id in node_ids { - self.record_lifetime_res( + self.record_lifetime_use( id, LifetimeRes::Infer, LifetimeElisionCandidate::Named, @@ -2302,7 +2302,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime); for id in node_ids { let res = self.create_fresh_lifetime(ident, binder, kind); - self.record_lifetime_res( + self.record_lifetime_use( id, res, replace(&mut candidate, LifetimeElisionCandidate::Named), @@ -2313,7 +2313,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeRibKind::Elided(res) => { let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime); for id in node_ids { - self.record_lifetime_res( + self.record_lifetime_use( id, res, replace(&mut candidate, LifetimeElisionCandidate::Ignore), @@ -2376,14 +2376,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } + /// Register a use of an already defined lifetime. #[instrument(level = "debug", skip(self))] - fn record_lifetime_res( + fn record_lifetime_use( &mut self, id: NodeId, res: LifetimeRes, candidate: LifetimeElisionCandidate, ) { - self.record_lifetime_param(id, res); + self.record_lifetime_def(id, res); match res { LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => { @@ -2395,13 +2396,16 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } + /// Can be used for both definitions and uses of lifetimes, as an error + /// has already been reported. #[instrument(level = "debug", skip(self))] fn record_lifetime_err(&mut self, id: NodeId, guar: ErrorGuaranteed) { - self.record_lifetime_param(id, LifetimeRes::Error(guar)); + self.record_lifetime_def(id, LifetimeRes::Error(guar)); } + /// Define a new lifetime (e.g. in generics) #[instrument(level = "debug", skip(self))] - fn record_lifetime_param(&mut self, id: NodeId, res: LifetimeRes) { + fn record_lifetime_def(&mut self, id: NodeId, res: LifetimeRes) { if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) { panic!( "lifetime parameter {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)" @@ -3189,7 +3193,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } GenericParamKind::Lifetime => { let res = LifetimeRes::Param { param: def_id, binder }; - self.record_lifetime_param(param.id, res); + self.record_lifetime_def(param.id, res); function_lifetime_rib.bindings.insert(ident, (param.id, res)); continue; } From bf5045cae0ce9af1632f610f376264ada78b45f0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 12:38:57 +0200 Subject: [PATCH 5/8] Drop an unused distinction (in diagnostics code) between anonymous and named lifetimes --- compiler/rustc_resolve/src/late.rs | 12 +++++------- compiler/rustc_resolve/src/late/diagnostics.rs | 4 +--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1b3da5b9dcbb1..2a06244fd117a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1751,7 +1751,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.record_lifetime_use( lifetime.id, LifetimeRes::Static, - LifetimeElisionCandidate::Named, + LifetimeElisionCandidate::Ignore, ); return; } @@ -1764,7 +1764,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { while let Some(rib) = lifetime_rib_iter.next() { let normalized_ident = ident.normalize_to_macros_2_0(); if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) { - self.record_lifetime_use(lifetime.id, res, LifetimeElisionCandidate::Named); + self.record_lifetime_use(lifetime.id, res, LifetimeElisionCandidate::Ignore); if let LifetimeRes::Param { param, binder } = res { match self.lifetime_uses.entry(param) { @@ -2236,7 +2236,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.record_lifetime_use( id, LifetimeRes::Infer, - LifetimeElisionCandidate::Named, + LifetimeElisionCandidate::Ignore, ); } continue; @@ -2305,7 +2305,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.record_lifetime_use( id, res, - replace(&mut candidate, LifetimeElisionCandidate::Named), + replace(&mut candidate, LifetimeElisionCandidate::Ignore), ); } break; @@ -2529,9 +2529,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }); all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| { match candidate { - LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => { - None - } + LifetimeElisionCandidate::Ignore => None, LifetimeElisionCandidate::Missing(missing) => Some(missing), } })); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 419a47b126980..423c13ff87d37 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -149,10 +149,8 @@ pub(super) struct ElisionFnParameter { /// This is used to suggest introducing an explicit lifetime. #[derive(Clone, Copy, Debug)] pub(super) enum LifetimeElisionCandidate { - /// This is not a real lifetime. + /// This is not a real lifetime, or it is a named lifetime, in which case we won't suggest anything. Ignore, - /// There is a named lifetime, we won't suggest anything. - Named, Missing(MissingLifetime), } From c0819ffeca08e91b720d3f9feadc7550c17d9276 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 15:19:31 +0200 Subject: [PATCH 6/8] Remove some dead code --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index e38415caaa222..89052a19f57b6 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1928,7 +1928,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Introduce extra lifetimes if late resolution tells us to. let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id); - params.extend(extra_lifetimes.into_iter().filter_map(|&(ident, node_id, res)| { + params.extend(extra_lifetimes.into_iter().map(|&(ident, node_id, res)| { self.lifetime_res_to_generic_param( ident, node_id, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a916ee1f143bd..8d973ad3f1889 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -950,11 +950,8 @@ impl<'hir> LoweringContext<'_, 'hir> { node_id: NodeId, res: LifetimeRes, source: hir::GenericParamSource, - ) -> Option> { + ) -> hir::GenericParam<'hir> { let (name, kind) = match res { - LifetimeRes::Param { .. } => { - (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit) - } LifetimeRes::Fresh { param, kind, .. } => { // Late resolution delegates to us the creation of the `LocalDefId`. let _def_id = self.create_def( @@ -967,7 +964,6 @@ impl<'hir> LoweringContext<'_, 'hir> { (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind)) } - LifetimeRes::Static { .. } | LifetimeRes::Error(..) => return None, res => panic!( "Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, ident.span @@ -975,7 +971,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let hir_id = self.lower_node_id(node_id); let def_id = self.local_def_id(node_id); - Some(hir::GenericParam { + hir::GenericParam { hir_id, def_id, name, @@ -984,7 +980,7 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: hir::GenericParamKind::Lifetime { kind }, colon_span: None, source, - }) + } } /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR @@ -1005,7 +1001,7 @@ impl<'hir> LoweringContext<'_, 'hir> { debug!(?extra_lifetimes); let extra_lifetimes: Vec<_> = extra_lifetimes .iter() - .filter_map(|&(ident, node_id, res)| { + .map(|&(ident, node_id, res)| { self.lifetime_res_to_generic_param( ident, node_id, From 87f9c4f5b592a1cba95d406b1431c46a98fec5e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 15:37:28 +0200 Subject: [PATCH 7/8] Remove an unused field --- compiler/rustc_hir/src/def.rs | 2 -- compiler/rustc_resolve/src/late.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index ad5d6b1509dfd..d275d5a28b88a 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -991,8 +991,6 @@ pub enum LifetimeRes { /// /// Creating the associated `LocalDefId` is the responsibility of lowering. param: NodeId, - /// Id of the introducing place. See `Param`. - binder: NodeId, /// Kind of elided lifetime kind: hir::MissingLifetimeKind, }, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2a06244fd117a..91464f768cea9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2143,7 +2143,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Leave the responsibility to create the `LocalDefId` to lowering. let param = self.r.next_node_id(); - let res = LifetimeRes::Fresh { param, binder, kind }; + let res = LifetimeRes::Fresh { param, kind }; self.record_lifetime_def(param, res); // Record the created lifetime parameter so lowering can pick it up and add it to HIR. From 19a5af7d86f19668e8b73f341c86adb2fa17fe2e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 15:39:25 +0200 Subject: [PATCH 8/8] extra_lifetime_params_map can only ever contain `LifetimeRes::Fresh`, so just encode the fields we need --- compiler/rustc_ast_lowering/src/item.rs | 4 +-- compiler/rustc_ast_lowering/src/lib.rs | 35 +++++++++---------------- compiler/rustc_middle/src/ty/mod.rs | 5 ++-- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 4 +-- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 89052a19f57b6..0a50d9fffe775 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1928,11 +1928,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // Introduce extra lifetimes if late resolution tells us to. let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id); - params.extend(extra_lifetimes.into_iter().map(|&(ident, node_id, res)| { + params.extend(extra_lifetimes.into_iter().map(|&(ident, node_id, kind)| { self.lifetime_res_to_generic_param( ident, node_id, - res, + kind, hir::GenericParamSource::Generics, ) })); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8d973ad3f1889..2366cb8db462d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,7 +55,7 @@ use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::DelayedLint; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, - LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, + LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, find_attr, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -310,7 +310,7 @@ impl<'tcx> ResolverAstLowering<'tcx> { /// /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. - fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, LifetimeRes)] { + fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, MissingLifetimeKind)] { self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..]) } @@ -948,36 +948,27 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, ident: Ident, node_id: NodeId, - res: LifetimeRes, + kind: MissingLifetimeKind, source: hir::GenericParamSource, ) -> hir::GenericParam<'hir> { - let (name, kind) = match res { - LifetimeRes::Fresh { param, kind, .. } => { - // Late resolution delegates to us the creation of the `LocalDefId`. - let _def_id = self.create_def( - param, - Some(kw::UnderscoreLifetime), - DefKind::LifetimeParam, - ident.span, - ); - debug!(?_def_id); + // Late resolution delegates to us the creation of the `LocalDefId`. + let _def_id = self.create_def( + node_id, + Some(kw::UnderscoreLifetime), + DefKind::LifetimeParam, + ident.span, + ); + debug!(?_def_id); - (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind)) - } - res => panic!( - "Unexpected lifetime resolution {:?} for {:?} at {:?}", - res, ident, ident.span - ), - }; let hir_id = self.lower_node_id(node_id); let def_id = self.local_def_id(node_id); hir::GenericParam { hir_id, def_id, - name, + name: hir::ParamName::Fresh, span: self.lower_span(ident.span), pure_wrt_drop: false, - kind: hir::GenericParamKind::Lifetime { kind }, + kind: hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided(kind) }, colon_span: None, source, } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 74f9e75fb48c0..2958b2d5cd590 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -37,12 +37,11 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHashe use rustc_data_structures::steal::Steal; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Diag, ErrorGuaranteed, LintBuffer}; -use rustc_hir as hir; use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; -use rustc_hir::{LangItem, attrs as attr, find_attr}; +use rustc_hir::{self as hir, LangItem, MissingLifetimeKind, attrs as attr, find_attr}; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; use rustc_macros::{ @@ -232,7 +231,7 @@ pub struct ResolverAstLowering<'tcx> { /// Resolutions for lifetimes. pub lifetimes_res_map: NodeMap, /// Lifetime parameters that lowering will have to introduce. - pub extra_lifetime_params_map: NodeMap>, + pub extra_lifetime_params_map: NodeMap>, pub next_node_id: ast::NodeId, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 91464f768cea9..5c709998cfe32 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2151,7 +2151,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .extra_lifetime_params_map .entry(binder) .or_insert_with(Vec::new) - .push((ident, param, res)); + .push((ident, param, kind)); res } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 22c4f4576d44b..2ce50b23ac5ed 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -58,7 +58,7 @@ use rustc_hir::def::{ }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguatorsMap}; -use rustc_hir::{PrimTy, TraitCandidate, find_attr}; +use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; @@ -1385,7 +1385,7 @@ pub struct Resolver<'ra, 'tcx> { /// Resolutions for lifetimes. lifetimes_res_map: NodeMap = Default::default(), /// Lifetime parameters that lowering will have to introduce. - extra_lifetime_params_map: NodeMap> = Default::default(), + extra_lifetime_params_map: NodeMap> = Default::default(), /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: UnordMap = Default::default(),