about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2022-08-01 16:03:49 -0300
committerSantiago Pastorino <spastorino@gmail.com>2022-08-04 11:26:54 -0300
commit05b989e16e7c6a7d4364f33f2612e540a50b1a27 (patch)
tree5bd0b800319ab45fef380545ef5508f08912d01e
parent4f334f2b970c3149365d4d98f02090d52767e44f (diff)
downloadrust-05b989e16e7c6a7d4364f33f2612e540a50b1a27.tar.gz
rust-05b989e16e7c6a7d4364f33f2612e540a50b1a27.zip
Skip lifetimes in binders when visiting
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs92
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs53
-rw-r--r--compiler/rustc_hir/src/def.rs9
3 files changed, 76 insertions, 78 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 2883299291e..c21afa26f4f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1353,12 +1353,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }),
                 );
 
-                let (lifetimes_in_bounds, binders_to_ignore) =
-                    lifetime_collector::lifetimes_in_bounds(bounds);
+                let lifetimes_in_bounds =
+                    lifetime_collector::lifetimes_in_bounds(&lctx.resolver, bounds);
                 debug!(?lifetimes_in_bounds);
-                debug!(?binders_to_ignore);
 
-                lctx.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
+                lctx.create_and_capture_lifetime_defs(&lifetimes_in_bounds);
 
                 let ret = lctx.lower_param_bounds(bounds, itctx);
 
@@ -1447,11 +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],
-        binders_to_ignore: &FxHashMap<NodeId, Vec<NodeId>>,
-    ) {
+    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;
@@ -1461,53 +1456,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
             if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
                 match res {
-                    LifetimeRes::Param { param, binder } => {
-                        if !binders_to_ignore
-                            .get(&lifetime.id)
-                            .unwrap_or(&Vec::new())
-                            .contains(&binder)
-                        {
-                            match captured_lifetimes.captures.entry(param) {
-                                Entry::Occupied(_) => {}
-                                Entry::Vacant(v) => {
-                                    let node_id = self.next_node_id();
-                                    let name = ParamName::Plain(ident);
-
-                                    self.create_def(
-                                        captured_lifetimes.parent_def_id,
-                                        node_id,
-                                        DefPathData::LifetimeNs(name.ident().name),
-                                    );
-
-                                    v.insert((span, node_id, name, res));
-                                }
+                    LifetimeRes::Param { param, binder: _ } => {
+                        match captured_lifetimes.captures.entry(param) {
+                            Entry::Occupied(_) => {}
+                            Entry::Vacant(v) => {
+                                let node_id = self.next_node_id();
+                                let name = ParamName::Plain(ident);
+
+                                self.create_def(
+                                    captured_lifetimes.parent_def_id,
+                                    node_id,
+                                    DefPathData::LifetimeNs(name.ident().name),
+                                );
+
+                                v.insert((span, node_id, name, res));
                             }
                         }
                     }
 
-                    LifetimeRes::Fresh { param, binder } => {
+                    LifetimeRes::Fresh { param, binder: _ } => {
                         debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
-                        if !binders_to_ignore
-                            .get(&lifetime.id)
-                            .unwrap_or(&Vec::new())
-                            .contains(&binder)
-                        {
-                            let param = self.local_def_id(param);
-                            match captured_lifetimes.captures.entry(param) {
-                                Entry::Occupied(_) => {}
-                                Entry::Vacant(v) => {
-                                    let node_id = self.next_node_id();
-
-                                    let name = ParamName::Fresh;
-
-                                    self.create_def(
-                                        captured_lifetimes.parent_def_id,
-                                        node_id,
-                                        DefPathData::LifetimeNs(kw::UnderscoreLifetime),
-                                    );
-
-                                    v.insert((span, node_id, name, res));
-                                }
+                        let param = self.local_def_id(param);
+                        match captured_lifetimes.captures.entry(param) {
+                            Entry::Occupied(_) => {}
+                            Entry::Vacant(v) => {
+                                let node_id = self.next_node_id();
+
+                                let name = ParamName::Fresh;
+
+                                self.create_def(
+                                    captured_lifetimes.parent_def_id,
+                                    node_id,
+                                    DefPathData::LifetimeNs(kw::UnderscoreLifetime),
+                                );
+
+                                v.insert((span, node_id, name, res));
                             }
                         }
                     }
@@ -1758,12 +1741,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }),
             );
 
-            let (lifetimes_in_bounds, binders_to_ignore) =
-                lifetime_collector::lifetimes_in_ret_ty(output);
+            let lifetimes_in_bounds =
+                lifetime_collector::lifetimes_in_ret_ty(&this.resolver, output);
             debug!(?lifetimes_in_bounds);
-            debug!(?binders_to_ignore);
 
-            this.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
+            this.create_and_capture_lifetime_defs(&lifetimes_in_bounds);
 
             // We have to be careful to get elision right here. The
             // idea is that we create a lifetime parameter for each
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index 1dab8799ae5..f67cbd69e47 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -1,21 +1,32 @@
+use super::ResolverAstLoweringExt;
 use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
 use rustc_ast::{
     FnRetTy, GenericBounds, Lifetime, NodeId, PolyTraitRef, TraitBoundModifier, Ty, TyKind,
 };
-use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def::LifetimeRes;
+use rustc_middle::ty::ResolverAstLowering;
 
-struct LifetimeCollectVisitor<'ast> {
+struct LifetimeCollectVisitor<'this, 'ast: 'this> {
+    resolver: &'this ResolverAstLowering,
     current_binders: Vec<NodeId>,
-    binders_to_ignore: FxHashMap<NodeId, Vec<NodeId>>,
     collected_lifetimes: Vec<&'ast Lifetime>,
 }
 
-impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
+impl<'this, 'ast: 'this> LifetimeCollectVisitor<'this, 'ast> {
+    fn new(resolver: &'this 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) {
-        if !self.collected_lifetimes.contains(&lifetime) {
-            self.collected_lifetimes.push(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)) {
+            if !self.collected_lifetimes.contains(&lifetime) {
+                self.collected_lifetimes.push(lifetime);
+            }
         }
-        self.binders_to_ignore.insert(lifetime.id, self.current_binders.clone());
     }
 
     fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
@@ -37,26 +48,22 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
     }
 }
 
-pub fn lifetimes_in_ret_ty(ret_ty: &FnRetTy) -> (Vec<&Lifetime>, FxHashMap<NodeId, Vec<NodeId>>) {
-    let mut visitor = LifetimeCollectVisitor {
-        current_binders: Vec::new(),
-        binders_to_ignore: FxHashMap::default(),
-        collected_lifetimes: Vec::new(),
-    };
+pub fn lifetimes_in_ret_ty<'this, 'ast: 'this>(
+    resolver: &'this ResolverAstLowering,
+    ret_ty: &'ast FnRetTy,
+) -> Vec<&'ast Lifetime> {
+    let mut visitor = LifetimeCollectVisitor::new(resolver);
     visitor.visit_fn_ret_ty(ret_ty);
-    (visitor.collected_lifetimes, visitor.binders_to_ignore)
+    visitor.collected_lifetimes
 }
 
-pub fn lifetimes_in_bounds(
-    bounds: &GenericBounds,
-) -> (Vec<&Lifetime>, FxHashMap<NodeId, Vec<NodeId>>) {
-    let mut visitor = LifetimeCollectVisitor {
-        current_binders: Vec::new(),
-        binders_to_ignore: FxHashMap::default(),
-        collected_lifetimes: Vec::new(),
-    };
+pub fn lifetimes_in_bounds<'this, 'ast: 'this>(
+    resolver: &'this ResolverAstLowering,
+    bounds: &'ast GenericBounds,
+) -> Vec<&'ast Lifetime> {
+    let mut visitor = LifetimeCollectVisitor::new(resolver);
     for bound in bounds {
         visitor.visit_param_bound(bound, BoundKind::Bound);
     }
-    (visitor.collected_lifetimes, visitor.binders_to_ignore)
+    visitor.collected_lifetimes
 }
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index be5b7eccbaf..2a89947f927 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -747,3 +747,12 @@ pub enum LifetimeRes {
     /// HACK: This is used to recover the NodeId of an elided lifetime.
     ElidedAnchor { start: NodeId, end: NodeId },
 }
+
+impl LifetimeRes {
+    pub fn binder(&self) -> Option<NodeId> {
+        match self {
+            LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. } => Some(*binder),
+            _ => None,
+        }
+    }
+}