From 1802d45b1238409d2c29cf7e8f25a96b94874fe2 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 2 Aug 2022 11:03:29 -0300 Subject: [PATCH] Record RPITs elided lifetimes in path segments --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../src/lifetime_collector.rs | 51 ++++++++++++------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c21afa26f4f..6cf938a242e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1446,7 +1446,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item)) } - fn create_and_capture_lifetime_defs(&mut self, lifetimes_in_bounds: &[&Lifetime]) { + fn create_and_capture_lifetime_defs(&mut self, lifetimes_in_bounds: &[Lifetime]) { for lifetime in lifetimes_in_bounds { let ident = lifetime.ident; let span = ident.span; diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 586436240f1..51fa7075d34 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -1,25 +1,26 @@ use super::ResolverAstLoweringExt; use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor}; use rustc_ast::{ - FnRetTy, GenericBounds, Lifetime, NodeId, PolyTraitRef, TraitBoundModifier, Ty, TyKind, + FnRetTy, GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, TraitBoundModifier, Ty, + TyKind, }; use rustc_hir::def::LifetimeRes; use rustc_middle::ty::ResolverAstLowering; +use rustc_span::symbol::{kw, Ident}; +use rustc_span::Span; -struct LifetimeCollectVisitor<'this, 'ast: 'this> { - resolver: &'this ResolverAstLowering, +struct LifetimeCollectVisitor<'ast> { + resolver: &'ast ResolverAstLowering, current_binders: Vec, - collected_lifetimes: Vec<&'ast Lifetime>, + collected_lifetimes: Vec, } -impl<'this, 'ast: 'this> LifetimeCollectVisitor<'this, 'ast> { - fn new(resolver: &'this ResolverAstLowering) -> Self { +impl<'ast> LifetimeCollectVisitor<'ast> { + fn new(resolver: &'ast ResolverAstLowering) -> Self { Self { resolver, current_binders: Vec::new(), collected_lifetimes: Vec::new() } } -} -impl<'this, 'ast: 'this> Visitor<'ast> for LifetimeCollectVisitor<'this, 'ast> { - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) { + fn record_lifetime_use(&mut self, lifetime: Lifetime) { let res = self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error); if res.binder().map_or(true, |b| !self.current_binders.contains(&b)) { @@ -28,6 +29,25 @@ impl<'this, 'ast: 'this> Visitor<'ast> for LifetimeCollectVisitor<'this, 'ast> { } } } +} + +impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) { + self.record_lifetime_use(*lifetime); + } + + fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) { + if let Some(LifetimeRes::ElidedAnchor { start, end }) = + self.resolver.get_lifetime_res(path_segment.id) + { + for i in start..end { + let lifetime = + Lifetime { id: i, ident: Ident::new(kw::UnderscoreLifetime, path_span) }; + self.record_lifetime_use(lifetime); + } + } + visit::walk_path_segment(self, path_span, path_segment); + } fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) { self.current_binders.push(t.trait_ref.ref_id); @@ -51,19 +71,16 @@ impl<'this, 'ast: 'this> Visitor<'ast> for LifetimeCollectVisitor<'this, 'ast> { } } -pub fn lifetimes_in_ret_ty<'this, 'ast: 'this>( - resolver: &'this ResolverAstLowering, - ret_ty: &'ast FnRetTy, -) -> Vec<&'ast Lifetime> { +pub fn lifetimes_in_ret_ty(resolver: &ResolverAstLowering, ret_ty: &FnRetTy) -> Vec { let mut visitor = LifetimeCollectVisitor::new(resolver); visitor.visit_fn_ret_ty(ret_ty); visitor.collected_lifetimes } -pub fn lifetimes_in_bounds<'this, 'ast: 'this>( - resolver: &'this ResolverAstLowering, - bounds: &'ast GenericBounds, -) -> Vec<&'ast Lifetime> { +pub fn lifetimes_in_bounds( + resolver: &ResolverAstLowering, + bounds: &GenericBounds, +) -> Vec { let mut visitor = LifetimeCollectVisitor::new(resolver); for bound in bounds { visitor.visit_param_bound(bound, BoundKind::Bound);