Use LifetimeRes during lowering.
This commit is contained in:
parent
69985f0175
commit
f385f856cd
9 changed files with 709 additions and 799 deletions
|
@ -14,13 +14,15 @@ use crate::{ResolutionError, Resolver, Segment, UseError};
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::*;
|
||||
use rustc_ast_lowering::ResolverAstLowering;
|
||||
use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::DiagnosticId;
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_hir::{PrimTy, TraitCandidate};
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
|
@ -195,7 +197,7 @@ enum LifetimeRibKind {
|
|||
Item,
|
||||
|
||||
/// This rib declares generic parameters.
|
||||
Generics { span: Span, kind: LifetimeBinderKind },
|
||||
Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind },
|
||||
|
||||
/// For **Modern** cases, create a new anonymous region parameter
|
||||
/// and reference that.
|
||||
|
@ -204,7 +206,7 @@ enum LifetimeRibKind {
|
|||
/// `resolve_lifetime` code.
|
||||
///
|
||||
/// For **Deprecated** cases, report an error.
|
||||
AnonymousCreateParameter,
|
||||
AnonymousCreateParameter(NodeId),
|
||||
|
||||
/// Give a hard error when either `&` or `'_` is written. Used to
|
||||
/// rule out things like `where T: Foo<'_>`. Does not imply an
|
||||
|
@ -212,7 +214,7 @@ enum LifetimeRibKind {
|
|||
AnonymousReportError,
|
||||
|
||||
/// Pass responsibility to `resolve_lifetime` code for all cases.
|
||||
AnonymousPassThrough,
|
||||
AnonymousPassThrough(NodeId),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -242,7 +244,7 @@ impl LifetimeBinderKind {
|
|||
#[derive(Debug)]
|
||||
struct LifetimeRib {
|
||||
kind: LifetimeRibKind,
|
||||
bindings: IdentMap<()>,
|
||||
bindings: IdentMap<LifetimeRes>,
|
||||
}
|
||||
|
||||
impl LifetimeRib {
|
||||
|
@ -581,12 +583,19 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
self.with_generic_param_rib(
|
||||
&bare_fn.generic_params,
|
||||
NormalRibKind,
|
||||
LifetimeRibKind::Generics { kind: LifetimeBinderKind::BareFnType, span },
|
||||
LifetimeRibKind::Generics {
|
||||
parent: ty.id,
|
||||
kind: LifetimeBinderKind::BareFnType,
|
||||
span,
|
||||
},
|
||||
|this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
|
||||
this.visit_generic_param_vec(&bare_fn.generic_params, false);
|
||||
visit::walk_fn_decl(this, &bare_fn.decl);
|
||||
});
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousPassThrough(ty.id),
|
||||
|this| {
|
||||
this.visit_generic_param_vec(&bare_fn.generic_params, false);
|
||||
visit::walk_fn_decl(this, &bare_fn.decl);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
self.diagnostic_metadata.current_trait_object = prev;
|
||||
|
@ -604,7 +613,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
self.with_generic_param_rib(
|
||||
&tref.bound_generic_params,
|
||||
NormalRibKind,
|
||||
LifetimeRibKind::Generics { kind: LifetimeBinderKind::PolyTrait, span },
|
||||
LifetimeRibKind::Generics {
|
||||
parent: tref.trait_ref.ref_id,
|
||||
kind: LifetimeBinderKind::PolyTrait,
|
||||
span,
|
||||
},
|
||||
|this| {
|
||||
this.visit_generic_param_vec(&tref.bound_generic_params, false);
|
||||
this.smart_resolve_path(
|
||||
|
@ -625,6 +638,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: foreign_item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -638,6 +652,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: foreign_item.id,
|
||||
kind: LifetimeBinderKind::Function,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -655,13 +670,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) {
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) {
|
||||
let rib_kind = match fn_kind {
|
||||
// Bail if the function is foreign, and thus cannot validly have
|
||||
// a body, or if there's no body for some other reason.
|
||||
FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
|
||||
| FnKind::Fn(_, _, sig, _, generics, None) => {
|
||||
self.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
|
||||
self.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
|
||||
// We don't need to deal with patterns in parameters, because
|
||||
// they are not possible for foreign or bodiless functions.
|
||||
this.visit_fn_header(&sig.header);
|
||||
|
@ -691,20 +706,24 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
this.visit_generics(generics);
|
||||
}
|
||||
|
||||
if async_node_id.is_some() {
|
||||
if let Some(async_node_id) = async_node_id {
|
||||
// In `async fn`, argument-position elided lifetimes
|
||||
// must be transformed into fresh generic parameters so that
|
||||
// they can be applied to the opaque `impl Trait` return type.
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter, |this| {
|
||||
// Add each argument to the rib.
|
||||
this.resolve_params(&declaration.inputs)
|
||||
});
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousCreateParameter(fn_id),
|
||||
|this| {
|
||||
// Add each argument to the rib.
|
||||
this.resolve_params(&declaration.inputs)
|
||||
},
|
||||
);
|
||||
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
|
||||
visit::walk_fn_ret_ty(this, &declaration.output)
|
||||
});
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousPassThrough(async_node_id),
|
||||
|this| visit::walk_fn_ret_ty(this, &declaration.output),
|
||||
);
|
||||
} else {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
|
||||
// Add each argument to the rib.
|
||||
this.resolve_params(&declaration.inputs);
|
||||
|
||||
|
@ -716,13 +735,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
// Be sure not to set this until the function signature has been resolved.
|
||||
let previous_state = replace(&mut this.in_func_body, true);
|
||||
// Resolve the function body, potentially inside the body of an async closure
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousPassThrough,
|
||||
|this| match fn_kind {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
|
||||
match fn_kind {
|
||||
FnKind::Fn(.., body) => walk_list!(this, visit_block, body),
|
||||
FnKind::Closure(_, body) => this.visit_expr(body),
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
debug!("(resolving function) leaving function");
|
||||
this.in_func_body = previous_state;
|
||||
|
@ -801,10 +819,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
if let Some(ref args) = path_segment.args {
|
||||
match &**args {
|
||||
GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, path_span, args),
|
||||
GenericArgs::Parenthesized(..) => self
|
||||
.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
|
||||
visit::walk_generic_args(this, path_span, args)
|
||||
}),
|
||||
GenericArgs::Parenthesized(..) => self.with_lifetime_rib(
|
||||
LifetimeRibKind::AnonymousPassThrough(path_segment.id),
|
||||
|this| visit::walk_generic_args(this, path_span, args),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -830,7 +848,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
this.with_generic_param_rib(
|
||||
&bound_generic_params,
|
||||
NormalRibKind,
|
||||
LifetimeRibKind::Generics { kind: LifetimeBinderKind::WhereBound, span },
|
||||
LifetimeRibKind::Generics {
|
||||
parent: bounded_ty.id,
|
||||
kind: LifetimeBinderKind::WhereBound,
|
||||
span,
|
||||
},
|
||||
|this| {
|
||||
this.visit_generic_param_vec(&bound_generic_params, false);
|
||||
this.visit_ty(bounded_ty);
|
||||
|
@ -1092,6 +1114,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
let ident = lifetime.ident;
|
||||
|
||||
if ident.name == kw::StaticLifetime {
|
||||
self.record_lifetime_res(lifetime.id, LifetimeRes::Static);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1126,8 @@ 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(_) = rib.bindings.get_key_value(&normalized_ident) {
|
||||
if let Some(®ion) = rib.bindings.get(&normalized_ident) {
|
||||
self.record_lifetime_res(lifetime.id, region);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1123,6 +1147,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
}
|
||||
|
||||
self.emit_undeclared_lifetime_error(lifetime, outer_res);
|
||||
self.record_lifetime_res(lifetime.id, LifetimeRes::Error);
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
|
@ -1132,6 +1157,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
for i in (0..self.lifetime_ribs.len()).rev() {
|
||||
let rib = &mut self.lifetime_ribs[i];
|
||||
match rib.kind {
|
||||
LifetimeRibKind::AnonymousCreateParameter(item_node_id) => {
|
||||
self.create_fresh_lifetime(lifetime.id, lifetime.ident, item_node_id);
|
||||
return;
|
||||
}
|
||||
LifetimeRibKind::AnonymousReportError => {
|
||||
let (msg, note) = if elided {
|
||||
(
|
||||
|
@ -1151,23 +1180,63 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
.span_label(lifetime.ident.span, note)
|
||||
.emit();
|
||||
|
||||
self.record_lifetime_res(lifetime.id, LifetimeRes::Error);
|
||||
return;
|
||||
}
|
||||
LifetimeRibKind::AnonymousCreateParameter
|
||||
| LifetimeRibKind::AnonymousPassThrough
|
||||
| LifetimeRibKind::Item => return,
|
||||
LifetimeRibKind::AnonymousPassThrough(node_id) => {
|
||||
self.record_lifetime_res(
|
||||
lifetime.id,
|
||||
LifetimeRes::Anonymous { binder: node_id, elided },
|
||||
);
|
||||
return;
|
||||
}
|
||||
LifetimeRibKind::Item => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// This resolution is wrong, it passes the work to HIR lifetime resolution.
|
||||
// We cannot use `LifetimeRes::Error` because we do not emit a diagnostic.
|
||||
self.record_lifetime_res(
|
||||
lifetime.id,
|
||||
LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided },
|
||||
);
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
|
||||
let id = self.r.next_node_id();
|
||||
self.record_lifetime_res(
|
||||
anchor_id,
|
||||
LifetimeRes::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) },
|
||||
);
|
||||
|
||||
let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) };
|
||||
self.resolve_anonymous_lifetime(<, true);
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn create_fresh_lifetime(&mut self, id: NodeId, ident: Ident, item_node_id: NodeId) {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
debug!(?ident.span);
|
||||
let item_def_id = self.r.local_def_id(item_node_id);
|
||||
let def_node_id = self.r.next_node_id();
|
||||
let def_id = self.r.create_def(
|
||||
item_def_id,
|
||||
def_node_id,
|
||||
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
|
||||
self.parent_scope.expansion.to_expn_id(),
|
||||
ident.span,
|
||||
);
|
||||
debug!(?def_id);
|
||||
|
||||
let region = LifetimeRes::Fresh {
|
||||
param: def_id,
|
||||
introducer: Some(def_node_id),
|
||||
binder: item_node_id,
|
||||
};
|
||||
self.record_lifetime_res(id, region);
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn resolve_elided_lifetimes_in_path(
|
||||
&mut self,
|
||||
|
@ -1231,7 +1300,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
//
|
||||
// impl Foo for std::cell::Ref<u32> // note lack of '_
|
||||
// async fn foo(_: std::cell::Ref<u32>) { ... }
|
||||
LifetimeRibKind::AnonymousCreateParameter => {
|
||||
LifetimeRibKind::AnonymousCreateParameter(_) => {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1241,13 +1310,29 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
|
||||
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
|
||||
// later, at which point a suitable error will be emitted.
|
||||
LifetimeRibKind::AnonymousPassThrough
|
||||
LifetimeRibKind::AnonymousPassThrough(..)
|
||||
| LifetimeRibKind::AnonymousReportError
|
||||
| LifetimeRibKind::Item => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let res = if error {
|
||||
LifetimeRes::Error
|
||||
} else {
|
||||
LifetimeRes::Anonymous { binder: segment_id, elided: true }
|
||||
};
|
||||
|
||||
let node_ids = self.r.next_node_ids(expected_lifetimes);
|
||||
self.record_lifetime_res(
|
||||
segment_id,
|
||||
LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end },
|
||||
);
|
||||
for i in 0..expected_lifetimes {
|
||||
let id = node_ids.start.plus(i);
|
||||
self.record_lifetime_res(id, res);
|
||||
}
|
||||
|
||||
if !missing {
|
||||
continue;
|
||||
}
|
||||
|
@ -1296,6 +1381,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn record_lifetime_res(&mut self, id: NodeId, res: LifetimeRes) {
|
||||
if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
|
||||
panic!(
|
||||
"lifetime {:?} resolved multiple times ({:?} before, {:?} now)",
|
||||
id, prev_res, res
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
|
||||
/// label and reports an error if the label is not found or is unreachable.
|
||||
fn resolve_label(&self, mut label: Ident) -> Option<NodeId> {
|
||||
|
@ -1379,7 +1474,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
this.with_generic_param_rib(
|
||||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics { kind: LifetimeBinderKind::Item, span: generics.span },
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
span: generics.span,
|
||||
},
|
||||
|this| {
|
||||
let item_def_id = this.r.local_def_id(item.id).to_def_id();
|
||||
this.with_self_rib(
|
||||
|
@ -1446,6 +1545,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -1458,6 +1558,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
kind: LifetimeBinderKind::Function,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -1487,6 +1588,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -1506,7 +1608,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
this.with_generic_param_rib(
|
||||
&generics.params,
|
||||
AssocItemRibKind,
|
||||
LifetimeRibKind::Generics { span: generics.span, kind },
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
span: generics.span,
|
||||
kind,
|
||||
},
|
||||
|this| {
|
||||
visit::walk_assoc_item(this, item, AssocCtxt::Trait)
|
||||
},
|
||||
|
@ -1571,6 +1677,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
&generics.params,
|
||||
ItemRibKind(HasGenericParams::Yes),
|
||||
LifetimeRibKind::Generics {
|
||||
parent: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
span: generics.span,
|
||||
},
|
||||
|
@ -1708,7 +1815,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
|
||||
GenericParamKind::Const { .. } => (&mut function_value_rib, DefKind::ConstParam),
|
||||
GenericParamKind::Lifetime => {
|
||||
function_lifetime_rib.bindings.insert(ident, ());
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
@ -1849,10 +1959,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
) {
|
||||
debug!("resolve_implementation");
|
||||
// If applicable, create a rib for the type parameters.
|
||||
self.with_generic_param_rib(&generics.params, ItemRibKind(HasGenericParams::Yes), LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::ImplBlock }, |this| {
|
||||
self.with_generic_param_rib(&generics.params, ItemRibKind(HasGenericParams::Yes), LifetimeRibKind::Generics { span: generics.span, parent: item_id, kind: LifetimeBinderKind::ImplBlock }, |this| {
|
||||
// Dummy self type for better errors if `Self` is used in the trait path.
|
||||
this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter(item_id), |this| {
|
||||
// Resolve the trait reference, if necessary.
|
||||
this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
|
||||
let item_def_id = this.r.local_def_id(item_id);
|
||||
|
@ -1876,7 +1986,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
this.visit_generics(generics);
|
||||
|
||||
// Resolve the items within the impl.
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough,
|
||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(item_id),
|
||||
|this| {
|
||||
this.with_current_self_type(self_type, |this| {
|
||||
this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
|
||||
|
@ -1921,7 +2031,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
this.with_generic_param_rib(
|
||||
&generics.params,
|
||||
AssocItemRibKind,
|
||||
LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::Function },
|
||||
LifetimeRibKind::Generics { parent: item.id, span: generics.span, kind: LifetimeBinderKind::Function },
|
||||
|this| {
|
||||
// If this is a trait impl, ensure the method
|
||||
// exists in trait
|
||||
|
@ -1950,7 +2060,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
this.with_generic_param_rib(
|
||||
&generics.params,
|
||||
AssocItemRibKind,
|
||||
LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::Item },
|
||||
LifetimeRibKind::Generics { parent: item.id, span: generics.span, kind: LifetimeBinderKind::Item },
|
||||
|this| {
|
||||
// If this is a trait impl, ensure the type
|
||||
// exists in trait
|
||||
|
|
|
@ -1824,7 +1824,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
|
||||
for rib in self.lifetime_ribs.iter().rev() {
|
||||
match rib.kind {
|
||||
LifetimeRibKind::Generics { span, kind } => {
|
||||
LifetimeRibKind::Generics { parent: _, span, kind } => {
|
||||
if !span.can_be_used_for_suggestions() && suggest_note {
|
||||
suggest_note = false; // Avoid displaying the same help multiple times.
|
||||
err.span_label(
|
||||
|
|
|
@ -29,7 +29,7 @@ use rustc_arena::{DroplessArena, TypedArena};
|
|||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
|
||||
use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
|
||||
use rustc_ast_lowering::ResolverAstLowering;
|
||||
use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -901,6 +901,8 @@ pub struct Resolver<'a> {
|
|||
import_res_map: NodeMap<PerNS<Option<Res>>>,
|
||||
/// Resolutions for labels (node IDs of their corresponding blocks or loops).
|
||||
label_res_map: NodeMap<NodeId>,
|
||||
/// Resolutions for lifetimes.
|
||||
lifetimes_res_map: NodeMap<LifetimeRes>,
|
||||
|
||||
/// `CrateNum` resolutions of `extern crate` items.
|
||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
|
@ -1153,6 +1155,10 @@ impl ResolverAstLowering for Resolver<'_> {
|
|||
self.label_res_map.get(&id).cloned()
|
||||
}
|
||||
|
||||
fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
|
||||
self.lifetimes_res_map.get(&id).copied()
|
||||
}
|
||||
|
||||
fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
|
||||
StableHashingContext::new(self.session, &self.definitions, self.crate_loader.cstore())
|
||||
}
|
||||
|
@ -1301,6 +1307,7 @@ impl<'a> Resolver<'a> {
|
|||
partial_res_map: Default::default(),
|
||||
import_res_map: Default::default(),
|
||||
label_res_map: Default::default(),
|
||||
lifetimes_res_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