Skip to content

Commit 76340ce

Browse files
authored
Rollup merge of rust-lang#97415 - cjgillot:is-late-bound-solo, r=estebank
Compute `is_late_bound_map` query separately from lifetime resolution This query is actually very simple, and is only useful for functions and method. It can be computed directly by fetching the HIR, with no need to embed it within the lifetime resolution visitor. Based on rust-lang#96296
2 parents 72f7e31 + ba40fe9 commit 76340ce

File tree

17 files changed

+205
-266
lines changed

17 files changed

+205
-266
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+17-24
Original file line numberDiff line numberDiff line change
@@ -672,9 +672,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
672672
LifetimeRes::Param { .. } => {
673673
(hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
674674
}
675-
LifetimeRes::Fresh { param, .. } => {
676-
(hir::ParamName::Fresh(param), hir::LifetimeParamKind::Elided)
677-
}
675+
LifetimeRes::Fresh { .. } => (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided),
678676
LifetimeRes::Static | LifetimeRes::Error => return None,
679677
res => panic!(
680678
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
@@ -1576,10 +1574,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15761574
(hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id })
15771575
}
15781576
// Input lifetime like `'1`:
1579-
LifetimeRes::Fresh { param, .. } => (
1580-
hir::ParamName::Fresh(outer_def_id),
1581-
LifetimeRes::Fresh { param, binder: fn_node_id },
1582-
),
1577+
LifetimeRes::Fresh { param, .. } => {
1578+
(hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id })
1579+
}
15831580
LifetimeRes::Static | LifetimeRes::Error => continue,
15841581
res => {
15851582
panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span)
@@ -1749,18 +1746,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17491746
) -> hir::Lifetime {
17501747
debug!(?self.captured_lifetimes);
17511748
let name = match res {
1752-
LifetimeRes::Param { param, binder } => {
1749+
LifetimeRes::Param { mut param, binder } => {
17531750
debug_assert_ne!(ident.name, kw::UnderscoreLifetime);
17541751
let p_name = ParamName::Plain(ident);
17551752
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
17561753
&mut self.captured_lifetimes
17571754
&& !binders_to_ignore.contains(&binder)
17581755
{
17591756
match captures.entry(param) {
1760-
Entry::Occupied(_) => {}
1757+
Entry::Occupied(o) => param = self.resolver.local_def_id(o.get().1),
17611758
Entry::Vacant(v) => {
17621759
let p_id = self.resolver.next_node_id();
1763-
self.resolver.create_def(
1760+
let p_def_id = self.resolver.create_def(
17641761
*parent_def_id,
17651762
p_id,
17661763
DefPathData::LifetimeNs(p_name.ident().name),
@@ -1769,10 +1766,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17691766
);
17701767

17711768
v.insert((span, p_id, p_name, res));
1769+
param = p_def_id;
17721770
}
17731771
}
17741772
}
1775-
hir::LifetimeName::Param(p_name)
1773+
hir::LifetimeName::Param(param, p_name)
17761774
}
17771775
LifetimeRes::Fresh { mut param, binder } => {
17781776
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
@@ -1792,21 +1790,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17921790
span.with_parent(None),
17931791
);
17941792

1795-
let p_name = ParamName::Fresh(param);
1796-
v.insert((span, p_id, p_name, res));
1793+
v.insert((span, p_id, ParamName::Fresh, res));
17971794
param = p_def_id;
17981795
}
17991796
}
18001797
}
1801-
let p_name = ParamName::Fresh(param);
1802-
hir::LifetimeName::Param(p_name)
1798+
hir::LifetimeName::Param(param, ParamName::Fresh)
18031799
}
18041800
LifetimeRes::Anonymous { binder, elided } => {
1805-
let l_name = if elided {
1806-
hir::LifetimeName::Implicit
1807-
} else {
1808-
hir::LifetimeName::Underscore
1809-
};
18101801
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
18111802
&mut self.captured_lifetimes
18121803
&& !binders_to_ignore.contains(&binder)
@@ -1819,18 +1810,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18191810
ExpnId::root(),
18201811
span.with_parent(None),
18211812
);
1822-
let p_name = ParamName::Fresh(p_def_id);
1823-
captures.insert(p_def_id, (span, p_id, p_name, res));
1824-
hir::LifetimeName::Param(p_name)
1813+
captures.insert(p_def_id, (span, p_id, ParamName::Fresh, res));
1814+
hir::LifetimeName::Param(p_def_id, ParamName::Fresh)
1815+
} else if elided {
1816+
hir::LifetimeName::Implicit
18251817
} else {
1826-
l_name
1818+
hir::LifetimeName::Underscore
18271819
}
18281820
}
18291821
LifetimeRes::Static => hir::LifetimeName::Static,
18301822
LifetimeRes::Error => hir::LifetimeName::Error,
18311823
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
18321824
};
18331825
debug!(?self.captured_lifetimes);
1826+
debug!(?name);
18341827
hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
18351828
}
18361829

compiler/rustc_borrowck/src/diagnostics/region_name.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -567,14 +567,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
567567
let lifetime =
568568
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
569569
match lifetime.name {
570-
hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error)
570+
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
571571
| hir::LifetimeName::Error
572572
| hir::LifetimeName::Static => {
573573
let lifetime_span = lifetime.span;
574574
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
575575
}
576576

577-
hir::LifetimeName::Param(hir::ParamName::Fresh(_))
577+
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
578578
| hir::LifetimeName::ImplicitObjectLifetimeDefault
579579
| hir::LifetimeName::Implicit
580580
| hir::LifetimeName::Underscore => {

compiler/rustc_borrowck/src/universal_regions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
830830
fn_def_id: DefId,
831831
mut f: impl FnMut(ty::Region<'tcx>),
832832
) {
833-
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
833+
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
834834
for &region_def_id in late_bounds.iter() {
835835
let name = tcx.item_name(region_def_id.to_def_id());
836836
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
837-
scope: owner.to_def_id(),
837+
scope: fn_def_id,
838838
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
839839
}));
840840
f(liberated_region);

compiler/rustc_hir/src/hir.rs

+32-20
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
2626
use smallvec::SmallVec;
2727
use std::fmt;
2828

29-
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
29+
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
3030
pub struct Lifetime {
3131
pub hir_id: HirId,
3232
pub span: Span,
@@ -60,7 +60,7 @@ pub enum ParamName {
6060
/// ```
6161
/// where `'f` is something like `Fresh(0)`. The indices are
6262
/// unique per impl, but not necessarily continuous.
63-
Fresh(LocalDefId),
63+
Fresh,
6464

6565
/// Indicates an illegal name was given and an error has been
6666
/// reported (so we should squelch other derived errors). Occurs
@@ -72,9 +72,7 @@ impl ParamName {
7272
pub fn ident(&self) -> Ident {
7373
match *self {
7474
ParamName::Plain(ident) => ident,
75-
ParamName::Fresh(_) | ParamName::Error => {
76-
Ident::with_dummy_span(kw::UnderscoreLifetime)
77-
}
75+
ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
7876
}
7977
}
8078

@@ -90,7 +88,7 @@ impl ParamName {
9088
#[derive(HashStable_Generic)]
9189
pub enum LifetimeName {
9290
/// User-given names or fresh (synthetic) names.
93-
Param(ParamName),
91+
Param(LocalDefId, ParamName),
9492

9593
/// User wrote nothing (e.g., the lifetime in `&u32`).
9694
Implicit,
@@ -127,7 +125,7 @@ impl LifetimeName {
127125
| LifetimeName::Error => Ident::empty(),
128126
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
129127
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
130-
LifetimeName::Param(param_name) => param_name.ident(),
128+
LifetimeName::Param(_, param_name) => param_name.ident(),
131129
}
132130
}
133131

@@ -136,9 +134,9 @@ impl LifetimeName {
136134
LifetimeName::ImplicitObjectLifetimeDefault
137135
| LifetimeName::Implicit
138136
| LifetimeName::Underscore
139-
| LifetimeName::Param(ParamName::Fresh(_))
137+
| LifetimeName::Param(_, ParamName::Fresh)
140138
| LifetimeName::Error => true,
141-
LifetimeName::Static | LifetimeName::Param(_) => false,
139+
LifetimeName::Static | LifetimeName::Param(..) => false,
142140
}
143141
}
144142

@@ -148,12 +146,12 @@ impl LifetimeName {
148146
| LifetimeName::Implicit
149147
| LifetimeName::Underscore => true,
150148

151-
// It might seem surprising that `Fresh(_)` counts as
149+
// It might seem surprising that `Fresh` counts as
152150
// *not* elided -- but this is because, as far as the code
153-
// in the compiler is concerned -- `Fresh(_)` variants act
151+
// in the compiler is concerned -- `Fresh` variants act
154152
// equivalently to "some fresh name". They correspond to
155153
// early-bound regions on an impl, in other words.
156-
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
154+
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
157155
}
158156
}
159157

@@ -163,8 +161,8 @@ impl LifetimeName {
163161

164162
pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
165163
match *self {
166-
LifetimeName::Param(param_name) => {
167-
LifetimeName::Param(param_name.normalize_to_macros_2_0())
164+
LifetimeName::Param(def_id, param_name) => {
165+
LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0())
168166
}
169167
lifetime_name => lifetime_name,
170168
}
@@ -177,12 +175,6 @@ impl fmt::Display for Lifetime {
177175
}
178176
}
179177

180-
impl fmt::Debug for Lifetime {
181-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182-
write!(f, "lifetime({}: {})", self.hir_id, self.name.ident())
183-
}
184-
}
185-
186178
impl Lifetime {
187179
pub fn is_elided(&self) -> bool {
188180
self.name.is_elided()
@@ -628,6 +620,16 @@ impl<'hir> Generics<'hir> {
628620
})
629621
}
630622

623+
pub fn outlives_for_param(
624+
&self,
625+
param_def_id: LocalDefId,
626+
) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
627+
self.predicates.iter().filter_map(move |pred| match pred {
628+
WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
629+
_ => None,
630+
})
631+
}
632+
631633
pub fn bounds_span_for_suggestions(&self, param_def_id: LocalDefId) -> Option<Span> {
632634
self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
633635
|bound| {
@@ -769,6 +771,16 @@ pub struct WhereRegionPredicate<'hir> {
769771
pub bounds: GenericBounds<'hir>,
770772
}
771773

774+
impl<'hir> WhereRegionPredicate<'hir> {
775+
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
776+
pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
777+
match self.lifetime.name {
778+
LifetimeName::Param(id, _) => id == param_def_id,
779+
_ => false,
780+
}
781+
}
782+
}
783+
772784
/// An equality predicate (e.g., `T = int`); currently unsupported.
773785
#[derive(Debug, HashStable_Generic)]
774786
pub struct WhereEqPredicate<'hir> {

compiler/rustc_hir/src/intravisit.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -510,11 +510,11 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
510510
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
511511
visitor.visit_id(lifetime.hir_id);
512512
match lifetime.name {
513-
LifetimeName::Param(ParamName::Plain(ident)) => {
513+
LifetimeName::Param(_, ParamName::Plain(ident)) => {
514514
visitor.visit_ident(ident);
515515
}
516-
LifetimeName::Param(ParamName::Fresh(_))
517-
| LifetimeName::Param(ParamName::Error)
516+
LifetimeName::Param(_, ParamName::Fresh)
517+
| LifetimeName::Param(_, ParamName::Error)
518518
| LifetimeName::Static
519519
| LifetimeName::Error
520520
| LifetimeName::Implicit
@@ -879,7 +879,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
879879
visitor.visit_id(param.hir_id);
880880
match param.name {
881881
ParamName::Plain(ident) => visitor.visit_ident(ident),
882-
ParamName::Error | ParamName::Fresh(_) => {}
882+
ParamName::Error | ParamName::Fresh => {}
883883
}
884884
match param.kind {
885885
GenericParamKind::Lifetime { .. } => {}

compiler/rustc_middle/src/hir/map/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,11 @@ impl<'hir> Map<'hir> {
364364
match node.node {
365365
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
366366
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
367-
OwnerNode::Item(Item {
367+
OwnerNode::ForeignItem(ForeignItem {
368+
kind: ForeignItemKind::Fn(_, _, generics),
369+
..
370+
})
371+
| OwnerNode::Item(Item {
368372
kind:
369373
ItemKind::Fn(_, generics, _)
370374
| ItemKind::TyAlias(_, generics)

compiler/rustc_middle/src/middle/resolve_lifetime.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
66
use rustc_hir::def_id::{DefId, LocalDefId};
77
use rustc_hir::ItemLocalId;
88
use rustc_macros::HashStable;
9-
use rustc_span::symbol::Symbol;
109

1110
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
1211
pub enum Region {
@@ -22,12 +21,12 @@ pub enum Region {
2221
/// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g.
2322
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
2423
pub enum LifetimeScopeForPath {
25-
// Contains all lifetime names that are in scope and could possibly be used in generics
26-
// arguments of path.
27-
NonElided(Vec<Symbol>),
24+
/// Contains all lifetime names that are in scope and could possibly be used in generics
25+
/// arguments of path.
26+
NonElided(Vec<LocalDefId>),
2827

29-
// Information that allows us to suggest args of the form `<'_>` in case
30-
// no generic arguments were provided for a path.
28+
/// Information that allows us to suggest args of the form `<'_>` in case
29+
/// no generic arguments were provided for a path.
3130
Elided,
3231
}
3332

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,7 @@ rustc_queries! {
15841584
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
15851585
desc { "looking up a named region" }
15861586
}
1587-
query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
1587+
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet<LocalDefId>> {
15881588
desc { "testing if a region is late bound" }
15891589
}
15901590
/// For a given item (like a struct), gets the default lifetimes to be used

compiler/rustc_middle/src/ty/context.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2803,6 +2803,13 @@ impl<'tcx> TyCtxt<'tcx> {
28032803
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
28042804
}
28052805

2806+
pub fn is_late_bound(self, id: HirId) -> bool {
2807+
self.is_late_bound_map(id.owner).map_or(false, |set| {
2808+
let def_id = self.hir().local_def_id(id);
2809+
set.contains(&def_id)
2810+
})
2811+
}
2812+
28062813
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
28072814
self.mk_bound_variable_kinds(
28082815
self.late_bound_vars_map(id.owner)

0 commit comments

Comments
 (0)