Collect extra lifetime parameters during late resolution.
This commit is contained in:
parent
b590e3062c
commit
21b6d23890
4 changed files with 141 additions and 225 deletions
|
@ -15,7 +15,7 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::*;
|
||||
use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_errors::DiagnosticId;
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
|
||||
|
@ -244,7 +244,8 @@ impl LifetimeBinderKind {
|
|||
#[derive(Debug)]
|
||||
struct LifetimeRib {
|
||||
kind: LifetimeRibKind,
|
||||
bindings: IdentMap<LifetimeRes>,
|
||||
// We need to preserve insertion order for async fns.
|
||||
bindings: FxIndexMap<Ident, (NodeId, LifetimeRes)>,
|
||||
}
|
||||
|
||||
impl LifetimeRib {
|
||||
|
@ -718,6 +719,32 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
},
|
||||
);
|
||||
|
||||
// Construct the list of in-scope lifetime parameters for async lowering.
|
||||
// We include all lifetime parameters, either named or "Fresh".
|
||||
// The order of those parameters does not matter, as long as it is
|
||||
// deterministic.
|
||||
let mut extra_lifetime_params =
|
||||
this.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
|
||||
for rib in this.lifetime_ribs.iter().rev() {
|
||||
extra_lifetime_params.extend(
|
||||
rib.bindings
|
||||
.iter()
|
||||
.map(|(&ident, &(node_id, res))| (ident, node_id, res)),
|
||||
);
|
||||
match rib.kind {
|
||||
LifetimeRibKind::Item => break,
|
||||
LifetimeRibKind::AnonymousCreateParameter(id) => {
|
||||
if let Some(earlier_fresh) =
|
||||
this.r.extra_lifetime_params_map.get(&id)
|
||||
{
|
||||
extra_lifetime_params.extend(earlier_fresh);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
this.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
|
||||
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousPassThrough(async_node_id),
|
||||
|this| visit::walk_fn_ret_ty(this, &declaration.output),
|
||||
|
@ -1126,7 +1153,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
for i in &mut indices {
|
||||
let rib = &self.lifetime_ribs[i];
|
||||
let normalized_ident = ident.normalize_to_macros_2_0();
|
||||
if let Some(®ion) = rib.bindings.get(&normalized_ident) {
|
||||
if let Some(&(_, region)) = rib.bindings.get(&normalized_ident) {
|
||||
self.record_lifetime_res(lifetime.id, region);
|
||||
return;
|
||||
}
|
||||
|
@ -1229,12 +1256,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
);
|
||||
debug!(?def_id);
|
||||
|
||||
let region = LifetimeRes::Fresh {
|
||||
param: def_id,
|
||||
introducer: Some(def_node_id),
|
||||
binder: item_node_id,
|
||||
};
|
||||
let region = LifetimeRes::Fresh { param: def_id, binder: item_node_id };
|
||||
self.record_lifetime_res(id, region);
|
||||
self.r.extra_lifetime_params_map.entry(item_node_id).or_insert_with(Vec::new).push((
|
||||
ident,
|
||||
def_node_id,
|
||||
region,
|
||||
));
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
|
@ -1818,7 +1846,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
let LifetimeRibKind::Generics { parent, .. } = lifetime_kind else { panic!() };
|
||||
let res = LifetimeRes::Param { param: def_id, binder: parent };
|
||||
self.record_lifetime_res(param.id, res);
|
||||
function_lifetime_rib.bindings.insert(ident, res);
|
||||
function_lifetime_rib.bindings.insert(ident, (param.id, res));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -903,6 +903,8 @@ pub struct Resolver<'a> {
|
|||
label_res_map: NodeMap<NodeId>,
|
||||
/// Resolutions for lifetimes.
|
||||
lifetimes_res_map: NodeMap<LifetimeRes>,
|
||||
/// Lifetime parameters that lowering will have to introduce.
|
||||
extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
|
||||
|
||||
/// `CrateNum` resolutions of `extern crate` items.
|
||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
|
@ -1159,6 +1161,10 @@ impl ResolverAstLowering for Resolver<'_> {
|
|||
self.lifetimes_res_map.get(&id).copied()
|
||||
}
|
||||
|
||||
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
|
||||
self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
|
||||
}
|
||||
|
||||
fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
|
||||
StableHashingContext::new(self.session, &self.definitions, self.crate_loader.cstore())
|
||||
}
|
||||
|
@ -1308,6 +1314,7 @@ impl<'a> Resolver<'a> {
|
|||
import_res_map: Default::default(),
|
||||
label_res_map: Default::default(),
|
||||
lifetimes_res_map: Default::default(),
|
||||
extra_lifetime_params_map: Default::default(),
|
||||
extern_crate_map: Default::default(),
|
||||
reexport_map: FxHashMap::default(),
|
||||
trait_map: NodeMap::default(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue