Skip to content

Commit 1a928e6

Browse files
committed
Implement anonymous lifetime lowering as a query
1 parent 02982fa commit 1a928e6

File tree

11 files changed

+139
-67
lines changed

11 files changed

+139
-67
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
22
use super::ResolverAstLoweringExt;
3-
use super::{ImplTraitContext, ImplTraitPosition};
43
use super::{FnDeclKind, LoweringContext, ParamMode};
4+
use super::{ImplTraitContext, ImplTraitPosition};
55

66
use rustc_ast::ptr::P;
77
use rustc_ast::*;
@@ -52,10 +52,10 @@ impl<'hir> ItemLowerer<'hir> {
5252
f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>,
5353
) -> hir::MaybeOwner<'hir> {
5454
let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner);
55-
55+
5656
let item = f(&mut lctx);
5757
debug_assert_eq!(lctx.current_hir_id_owner, item.def_id());
58-
58+
5959
let info = lctx.make_owner_info(item);
6060

6161
hir::MaybeOwner::Owner(self.tcx.hir_arena.alloc(info))
@@ -707,13 +707,13 @@ impl<'hir> LoweringContext<'hir> {
707707
}
708708
}
709709

710-
fn lower_trait_item(
711-
&mut self,
712-
i: &AssocItem,
713-
) -> &'hir hir::TraitItem<'hir> {
710+
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
714711
let def_id = self.resolver.node_id_to_def_id[&i.id];
715712
let parent_id = self.tcx.local_parent(def_id);
716-
let constness = self.tcx.get_attr(parent_id, sym::const_trait).map_or(Const::No, |attr| Const::Yes(attr.span));
713+
let constness = self
714+
.tcx
715+
.get_attr(parent_id, sym::const_trait)
716+
.map_or(Const::No, |attr| Const::Yes(attr.span));
717717

718718
let hir_id = self.lower_node_id(i.id);
719719
self.lower_attrs(hir_id, &i.attrs);
@@ -847,10 +847,7 @@ impl<'hir> LoweringContext<'hir> {
847847
self.expr(span, hir::ExprKind::Err(guar))
848848
}
849849

850-
fn lower_impl_item(
851-
&mut self,
852-
i: &AssocItem,
853-
) -> &'hir hir::ImplItem<'hir> {
850+
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
854851
let def_id = self.resolver.node_id_to_def_id[&i.id];
855852
let parent_id = self.tcx.local_parent(def_id);
856853
let parent_item = self.tcx.hir().expect_item(parent_id);
@@ -862,10 +859,13 @@ impl<'hir> LoweringContext<'hir> {
862859
// is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
863860
// calling non-const impls are done through associated types.
864861
if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) {
865-
constness_of_trait = self.tcx.get_attr(def_id, sym::const_trait).map_or(Const::No, |attr| Const::Yes(attr.span))
862+
constness_of_trait = self
863+
.tcx
864+
.get_attr(def_id, sym::const_trait)
865+
.map_or(Const::No, |attr| Const::Yes(attr.span))
866866
}
867867
}
868-
_ => ()
868+
_ => (),
869869
}
870870

871871
// Since `default impl` is not yet implemented, this is always true in impls.

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ use rustc_ast_pretty::pprust;
4848
use rustc_data_structures::captures::Captures;
4949
use rustc_data_structures::fx::FxIndexSet;
5050
use rustc_data_structures::sorted_map::SortedMap;
51-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5251
use rustc_data_structures::steal::Steal;
5352
use rustc_data_structures::sync::Lrc;
5453
use rustc_data_structures::unord::ExtendUnord;
5554
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
56-
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
55+
use rustc_hir::def::{DefKind, FreshLifetimeResId, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5756
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, LOCAL_CRATE};
5857
use rustc_hir::{self as hir};
5958
use rustc_hir::{
@@ -156,11 +155,7 @@ struct LoweringContext<'hir> {
156155
}
157156

158157
impl<'hir> LoweringContext<'hir> {
159-
fn new(
160-
tcx: TyCtxt<'hir>,
161-
resolver: &'hir ResolverAstLowering,
162-
owner: NodeId,
163-
) -> Self {
158+
fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering, owner: NodeId) -> Self {
164159
let current_hir_id_owner = hir::OwnerId { def_id: resolver.node_id_to_def_id[&owner] };
165160
Self {
166161
// Pseudo-globals.
@@ -428,7 +423,6 @@ fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec<LocalDefId, Stea
428423
visit::walk_item(self, item);
429424
self.insert(item.id, AstOwnerRef::Item(item));
430425
}
431-
432426

433427
fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: visit::AssocCtxt) {
434428
visit::walk_item(self, item);
@@ -820,6 +814,14 @@ impl<'hir> LoweringContext<'hir> {
820814
Ident::new(ident.name, self.lower_span(ident.span))
821815
}
822816

817+
fn lower_fresh_lifetime_res(&mut self, id: FreshLifetimeResId, node_id: NodeId) -> LocalDefId {
818+
let def_id = self.tcx.fresh_lifetime_def_id(id);
819+
// make sure that this `NodeId` is known to us.
820+
self.node_id_to_def_id.insert(node_id, def_id);
821+
trace!(?self.current_hir_id_owner, ?def_id);
822+
def_id
823+
}
824+
823825
/// Converts a lifetime into a new generic parameter.
824826
#[instrument(level = "debug", skip(self))]
825827
fn lifetime_res_to_generic_param(
@@ -833,17 +835,9 @@ impl<'hir> LoweringContext<'hir> {
833835
LifetimeRes::Param { .. } => {
834836
(hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
835837
}
836-
LifetimeRes::Fresh { param, kind, .. } => {
837-
// Late resolution delegates to us the creation of the `LocalDefId`.
838-
let _def_id = self.create_def(
839-
self.current_hir_id_owner.def_id,
840-
param,
841-
kw::UnderscoreLifetime,
842-
DefKind::LifetimeParam,
843-
ident.span,
844-
);
845-
debug!(?_def_id);
846-
838+
LifetimeRes::Fresh { id, kind, param, .. } => {
839+
debug_assert_eq!(param, node_id);
840+
self.lower_fresh_lifetime_res(id, node_id);
847841
(hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
848842
}
849843
LifetimeRes::Static | LifetimeRes::Error => return None,
@@ -1697,15 +1691,9 @@ impl<'hir> LoweringContext<'hir> {
16971691
let (old_def_id, missing_kind) = match res {
16981692
LifetimeRes::Param { param: old_def_id, binder: _ } => (old_def_id, None),
16991693

1700-
LifetimeRes::Fresh { param, kind, .. } => {
1694+
LifetimeRes::Fresh { id, kind, param, .. } => {
17011695
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
1702-
if let Some(old_def_id) = self.orig_opt_local_def_id(param) {
1703-
(old_def_id, Some(kind))
1704-
} else {
1705-
self.dcx()
1706-
.span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime");
1707-
continue;
1708-
}
1696+
(self.tcx.fresh_lifetime_def_id(id), Some(kind))
17091697
}
17101698

17111699
// Opaques do not capture `'static`
@@ -2117,8 +2105,8 @@ impl<'hir> LoweringContext<'hir> {
21172105
let param = self.get_remapped_def_id(param);
21182106
hir::LifetimeName::Param(param)
21192107
}
2120-
LifetimeRes::Fresh { param, .. } => {
2121-
let param = self.local_def_id(param);
2108+
LifetimeRes::Fresh { id, .. } => {
2109+
let param = self.get_remapped_def_id(self.tcx.fresh_lifetime_def_id(id));
21222110
hir::LifetimeName::Param(param)
21232111
}
21242112
LifetimeRes::Infer => hir::LifetimeName::Infer,

compiler/rustc_ast_lowering/src/query.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use rustc_data_structures::fingerprint::Fingerprint;
22
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
33
use rustc_data_structures::svh::Svh;
4+
use rustc_hir::def::{DefKind, FreshLifetimeResId};
45
use rustc_hir::def_id::{LocalDefId, LocalModDefId, StableCrateId, LOCAL_CRATE};
56
use rustc_hir::intravisit::{self, Visitor};
67
use rustc_hir::*;
78
use rustc_middle::hir::{nested_filter, ModuleItems};
89
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
910
use rustc_middle::query::{LocalCrate, Providers};
1011
use rustc_middle::ty::TyCtxt;
12+
use rustc_span::symbol::kw;
1113
use rustc_span::DUMMY_SP;
1214

1315
use crate::{index_ast, lower_to_hir};
@@ -16,13 +18,25 @@ pub fn provide(providers: &mut Providers) {
1618
*providers = Providers {
1719
lower_to_hir,
1820
index_ast,
21+
fresh_lifetime_def_id,
1922
crate_hash,
2023
hir_module_items,
2124
hir_crate_items,
2225
..*providers
2326
};
2427
}
2528

29+
fn fresh_lifetime_def_id(tcx: TyCtxt<'_>, id: FreshLifetimeResId) -> LocalDefId {
30+
let (resolver, _) = tcx.resolver_for_lowering();
31+
let (span, node_id) = resolver.fresh_lifetime_res_info[id];
32+
let parent = *resolver
33+
.node_id_to_def_id
34+
.get(&node_id)
35+
.expect("binder for fresh lifetime is not associated with a DefId?");
36+
37+
tcx.at(span).create_def(parent, kw::UnderscoreLifetime, DefKind::LifetimeParam).def_id()
38+
}
39+
2640
fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
2741
let mut hir_body_nodes: Vec<_> = tcx
2842
.hir_crate_items(())

compiler/rustc_hir/src/def.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,15 @@ impl<Id> Res<Id> {
791791
}
792792
}
793793

794+
rustc_index::newtype_index! {
795+
/// Identifies a fresh lifetime, for example desugared from `'_`.
796+
#[encodable]
797+
#[orderable]
798+
#[debug_format = "FreshLifetimeResId({})"]
799+
#[derive(HashStable_Generic)]
800+
pub struct FreshLifetimeResId {}
801+
}
802+
794803
/// Resolution for a lifetime appearing in a type.
795804
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
796805
pub enum LifetimeRes {
@@ -809,9 +818,9 @@ pub enum LifetimeRes {
809818
},
810819
/// Created a generic parameter for an anonymous lifetime.
811820
Fresh {
812-
/// Id of the generic parameter that introduced it.
813-
///
814-
/// Creating the associated `LocalDefId` is the responsibility of lowering.
821+
/// The id for tracking creating the associated `LocalDefId`
822+
id: FreshLifetimeResId,
823+
/// The `NodeId` for ast lowering to link to the `LocalDefId`.
815824
param: NodeId,
816825
/// Id of the introducing place. See `Param`.
817826
binder: NodeId,

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2080,7 +2080,11 @@ pub fn deny_non_region_late_bound(
20802080

20812081
for (var, arg) in bound_vars {
20822082
let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else {
2083-
span_bug!(tcx.def_span(*var), "expected bound-var def-id to resolve to param");
2083+
span_bug!(
2084+
tcx.def_span(*var),
2085+
"expected bound-var def-id to resolve to param: {:?}",
2086+
tcx.hir_node_by_def_id(*var)
2087+
);
20842088
};
20852089

20862090
let what = match param.kind {

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ pub fn provide(providers: &mut Providers) {
174174
let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
175175
HirId {
176176
owner: parent_owner_id,
177-
local_id: tcx.lower_to_hir(parent_owner_id)
177+
local_id: tcx
178+
.lower_to_hir(parent_owner_id)
178179
.unwrap()
179180
.parenting
180181
.get(&owner_id.def_id)
@@ -183,9 +184,8 @@ pub fn provide(providers: &mut Providers) {
183184
}
184185
})
185186
};
186-
providers.hir_attrs = |tcx, id| {
187-
tcx.lower_to_hir(id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
188-
};
187+
providers.hir_attrs =
188+
|tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs);
189189
providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
190190
providers.def_ident_span = |tcx, def_id| {
191191
let hir_id = tcx.local_def_id_to_hir_id(def_id);
@@ -216,7 +216,6 @@ pub fn provide(providers: &mut Providers) {
216216
providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
217217
providers.expn_that_defined =
218218
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
219-
providers.in_scope_traits_map = |tcx, id| {
220-
tcx.lower_to_hir(id.def_id).as_owner().map(|owner_info| &owner_info.trait_map)
221-
};
219+
providers.in_scope_traits_map =
220+
|tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map(|owner_info| &owner_info.trait_map);
222221
}

compiler/rustc_middle/src/query/keys.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::ty::fast_reject::SimplifiedType;
77
use crate::ty::layout::{TyAndLayout, ValidityRequirement};
88
use crate::ty::{self, Ty, TyCtxt};
99
use crate::ty::{GenericArg, GenericArgsRef};
10+
use rustc_hir::def::FreshLifetimeResId;
1011
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, ModDefId, LOCAL_CRATE};
1112
use rustc_hir::hir_id::{HirId, OwnerId};
1213
use rustc_query_system::query::{DefIdCache, DefaultCache, SingleCache, VecCache};
@@ -563,6 +564,14 @@ impl Key for HirId {
563564
}
564565
}
565566

567+
impl Key for FreshLifetimeResId {
568+
type Cache<V> = DefaultCache<Self, V>;
569+
570+
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
571+
DUMMY_SP
572+
}
573+
}
574+
566575
impl Key for (LocalDefId, HirId) {
567576
type Cache<V> = DefaultCache<Self, V>;
568577

compiler/rustc_middle/src/query/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,13 @@ rustc_queries! {
153153
desc { "getting the source span" }
154154
}
155155

156+
query fresh_lifetime_def_id(key: rustc_hir::def::FreshLifetimeResId) -> LocalDefId {
157+
desc { "getting the DefId for a fresh lifetime created during resolution" }
158+
}
159+
156160
query lower_to_hir(key: LocalDefId) -> hir::MaybeOwner<'tcx> {
157161
eval_always
158-
desc { |tcx| "lower HIR for `{}`", tcx.def_path_str(key.to_def_id()) }
162+
desc { |tcx| "lowering HIR for `{}`", tcx.def_path_str(key.to_def_id()) }
159163
}
160164

161165
/// All items in the crate.

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
4343
use rustc_data_structures::unord::UnordMap;
4444
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
4545
use rustc_hir as hir;
46-
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
46+
use rustc_hir::def::{
47+
CtorKind, CtorOf, DefKind, DocLinkResMap, FreshLifetimeResId, LifetimeRes, Res,
48+
};
4749
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
4850
use rustc_index::IndexVec;
4951
use rustc_macros::{
@@ -212,6 +214,8 @@ pub struct ResolverAstLowering {
212214
pub lifetimes_res_map: NodeMap<LifetimeRes>,
213215
/// Lifetime parameters that lowering will have to introduce.
214216
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
217+
/// Lifetime parameters that resolver did not create `DefId`s for.
218+
pub fresh_lifetime_res_info: IndexVec<FreshLifetimeResId, (Span, ast::NodeId)>,
215219

216220
pub next_node_id: ast::NodeId,
217221

0 commit comments

Comments
 (0)