Skip to content

Commit 05b989e

Browse files
committed
Skip lifetimes in binders when visiting
1 parent 4f334f2 commit 05b989e

File tree

3 files changed

+76
-78
lines changed

3 files changed

+76
-78
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,12 +1353,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13531353
}),
13541354
);
13551355

1356-
let (lifetimes_in_bounds, binders_to_ignore) =
1357-
lifetime_collector::lifetimes_in_bounds(bounds);
1356+
let lifetimes_in_bounds =
1357+
lifetime_collector::lifetimes_in_bounds(&lctx.resolver, bounds);
13581358
debug!(?lifetimes_in_bounds);
1359-
debug!(?binders_to_ignore);
13601359

1361-
lctx.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
1360+
lctx.create_and_capture_lifetime_defs(&lifetimes_in_bounds);
13621361

13631362
let ret = lctx.lower_param_bounds(bounds, itctx);
13641363

@@ -1447,11 +1446,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14471446
hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
14481447
}
14491448

1450-
fn create_and_capture_lifetime_defs(
1451-
&mut self,
1452-
lifetimes_in_bounds: &[&Lifetime],
1453-
binders_to_ignore: &FxHashMap<NodeId, Vec<NodeId>>,
1454-
) {
1449+
fn create_and_capture_lifetime_defs(&mut self, lifetimes_in_bounds: &[&Lifetime]) {
14551450
for lifetime in lifetimes_in_bounds {
14561451
let ident = lifetime.ident;
14571452
let span = ident.span;
@@ -1461,53 +1456,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14611456

14621457
if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
14631458
match res {
1464-
LifetimeRes::Param { param, binder } => {
1465-
if !binders_to_ignore
1466-
.get(&lifetime.id)
1467-
.unwrap_or(&Vec::new())
1468-
.contains(&binder)
1469-
{
1470-
match captured_lifetimes.captures.entry(param) {
1471-
Entry::Occupied(_) => {}
1472-
Entry::Vacant(v) => {
1473-
let node_id = self.next_node_id();
1474-
let name = ParamName::Plain(ident);
1475-
1476-
self.create_def(
1477-
captured_lifetimes.parent_def_id,
1478-
node_id,
1479-
DefPathData::LifetimeNs(name.ident().name),
1480-
);
1481-
1482-
v.insert((span, node_id, name, res));
1483-
}
1459+
LifetimeRes::Param { param, binder: _ } => {
1460+
match captured_lifetimes.captures.entry(param) {
1461+
Entry::Occupied(_) => {}
1462+
Entry::Vacant(v) => {
1463+
let node_id = self.next_node_id();
1464+
let name = ParamName::Plain(ident);
1465+
1466+
self.create_def(
1467+
captured_lifetimes.parent_def_id,
1468+
node_id,
1469+
DefPathData::LifetimeNs(name.ident().name),
1470+
);
1471+
1472+
v.insert((span, node_id, name, res));
14841473
}
14851474
}
14861475
}
14871476

1488-
LifetimeRes::Fresh { param, binder } => {
1477+
LifetimeRes::Fresh { param, binder: _ } => {
14891478
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1490-
if !binders_to_ignore
1491-
.get(&lifetime.id)
1492-
.unwrap_or(&Vec::new())
1493-
.contains(&binder)
1494-
{
1495-
let param = self.local_def_id(param);
1496-
match captured_lifetimes.captures.entry(param) {
1497-
Entry::Occupied(_) => {}
1498-
Entry::Vacant(v) => {
1499-
let node_id = self.next_node_id();
1500-
1501-
let name = ParamName::Fresh;
1502-
1503-
self.create_def(
1504-
captured_lifetimes.parent_def_id,
1505-
node_id,
1506-
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
1507-
);
1508-
1509-
v.insert((span, node_id, name, res));
1510-
}
1479+
let param = self.local_def_id(param);
1480+
match captured_lifetimes.captures.entry(param) {
1481+
Entry::Occupied(_) => {}
1482+
Entry::Vacant(v) => {
1483+
let node_id = self.next_node_id();
1484+
1485+
let name = ParamName::Fresh;
1486+
1487+
self.create_def(
1488+
captured_lifetimes.parent_def_id,
1489+
node_id,
1490+
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
1491+
);
1492+
1493+
v.insert((span, node_id, name, res));
15111494
}
15121495
}
15131496
}
@@ -1758,12 +1741,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17581741
}),
17591742
);
17601743

1761-
let (lifetimes_in_bounds, binders_to_ignore) =
1762-
lifetime_collector::lifetimes_in_ret_ty(output);
1744+
let lifetimes_in_bounds =
1745+
lifetime_collector::lifetimes_in_ret_ty(&this.resolver, output);
17631746
debug!(?lifetimes_in_bounds);
1764-
debug!(?binders_to_ignore);
17651747

1766-
this.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
1748+
this.create_and_capture_lifetime_defs(&lifetimes_in_bounds);
17671749

17681750
// We have to be careful to get elision right here. The
17691751
// idea is that we create a lifetime parameter for each
Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1+
use super::ResolverAstLoweringExt;
12
use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
23
use rustc_ast::{
34
FnRetTy, GenericBounds, Lifetime, NodeId, PolyTraitRef, TraitBoundModifier, Ty, TyKind,
45
};
5-
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_hir::def::LifetimeRes;
7+
use rustc_middle::ty::ResolverAstLowering;
68

7-
struct LifetimeCollectVisitor<'ast> {
9+
struct LifetimeCollectVisitor<'this, 'ast: 'this> {
10+
resolver: &'this ResolverAstLowering,
811
current_binders: Vec<NodeId>,
9-
binders_to_ignore: FxHashMap<NodeId, Vec<NodeId>>,
1012
collected_lifetimes: Vec<&'ast Lifetime>,
1113
}
1214

13-
impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
15+
impl<'this, 'ast: 'this> LifetimeCollectVisitor<'this, 'ast> {
16+
fn new(resolver: &'this ResolverAstLowering) -> Self {
17+
Self { resolver, current_binders: Vec::new(), collected_lifetimes: Vec::new() }
18+
}
19+
}
20+
21+
impl<'this, 'ast: 'this> Visitor<'ast> for LifetimeCollectVisitor<'this, 'ast> {
1422
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) {
15-
if !self.collected_lifetimes.contains(&lifetime) {
16-
self.collected_lifetimes.push(lifetime);
23+
let res = self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error);
24+
25+
if res.binder().map_or(true, |b| !self.current_binders.contains(&b)) {
26+
if !self.collected_lifetimes.contains(&lifetime) {
27+
self.collected_lifetimes.push(lifetime);
28+
}
1729
}
18-
self.binders_to_ignore.insert(lifetime.id, self.current_binders.clone());
1930
}
2031

2132
fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
@@ -37,26 +48,22 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
3748
}
3849
}
3950

40-
pub fn lifetimes_in_ret_ty(ret_ty: &FnRetTy) -> (Vec<&Lifetime>, FxHashMap<NodeId, Vec<NodeId>>) {
41-
let mut visitor = LifetimeCollectVisitor {
42-
current_binders: Vec::new(),
43-
binders_to_ignore: FxHashMap::default(),
44-
collected_lifetimes: Vec::new(),
45-
};
51+
pub fn lifetimes_in_ret_ty<'this, 'ast: 'this>(
52+
resolver: &'this ResolverAstLowering,
53+
ret_ty: &'ast FnRetTy,
54+
) -> Vec<&'ast Lifetime> {
55+
let mut visitor = LifetimeCollectVisitor::new(resolver);
4656
visitor.visit_fn_ret_ty(ret_ty);
47-
(visitor.collected_lifetimes, visitor.binders_to_ignore)
57+
visitor.collected_lifetimes
4858
}
4959

50-
pub fn lifetimes_in_bounds(
51-
bounds: &GenericBounds,
52-
) -> (Vec<&Lifetime>, FxHashMap<NodeId, Vec<NodeId>>) {
53-
let mut visitor = LifetimeCollectVisitor {
54-
current_binders: Vec::new(),
55-
binders_to_ignore: FxHashMap::default(),
56-
collected_lifetimes: Vec::new(),
57-
};
60+
pub fn lifetimes_in_bounds<'this, 'ast: 'this>(
61+
resolver: &'this ResolverAstLowering,
62+
bounds: &'ast GenericBounds,
63+
) -> Vec<&'ast Lifetime> {
64+
let mut visitor = LifetimeCollectVisitor::new(resolver);
5865
for bound in bounds {
5966
visitor.visit_param_bound(bound, BoundKind::Bound);
6067
}
61-
(visitor.collected_lifetimes, visitor.binders_to_ignore)
68+
visitor.collected_lifetimes
6269
}

compiler/rustc_hir/src/def.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,3 +747,12 @@ pub enum LifetimeRes {
747747
/// HACK: This is used to recover the NodeId of an elided lifetime.
748748
ElidedAnchor { start: NodeId, end: NodeId },
749749
}
750+
751+
impl LifetimeRes {
752+
pub fn binder(&self) -> Option<NodeId> {
753+
match self {
754+
LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. } => Some(*binder),
755+
_ => None,
756+
}
757+
}
758+
}

0 commit comments

Comments
 (0)