Replace LifetimeRes::Anonymous by LifetimeRes::Infer.
This commit is contained in:
parent
ab63591f00
commit
10be0dd8df
@ -1883,25 +1883,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
hir::LifetimeName::Param(param, ParamName::Fresh)
|
hir::LifetimeName::Param(param, ParamName::Fresh)
|
||||||
}
|
}
|
||||||
LifetimeRes::Anonymous { binder } => {
|
LifetimeRes::Infer => hir::LifetimeName::Infer,
|
||||||
let mut l_name = None;
|
|
||||||
if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
|
|
||||||
if !captured_lifetimes.binders_to_ignore.contains(&binder) {
|
|
||||||
let p_id = self.next_node_id();
|
|
||||||
let p_def_id = self.create_def(
|
|
||||||
captured_lifetimes.parent_def_id,
|
|
||||||
p_id,
|
|
||||||
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
|
|
||||||
);
|
|
||||||
captured_lifetimes
|
|
||||||
.captures
|
|
||||||
.insert(p_def_id, (span, p_id, ParamName::Fresh, res));
|
|
||||||
l_name = Some(hir::LifetimeName::Param(p_def_id, ParamName::Fresh));
|
|
||||||
}
|
|
||||||
self.captured_lifetimes = Some(captured_lifetimes);
|
|
||||||
};
|
|
||||||
l_name.unwrap_or(hir::LifetimeName::Underscore)
|
|
||||||
}
|
|
||||||
LifetimeRes::Static => hir::LifetimeName::Static,
|
LifetimeRes::Static => hir::LifetimeName::Static,
|
||||||
LifetimeRes::Error => hir::LifetimeName::Error,
|
LifetimeRes::Error => hir::LifetimeName::Error,
|
||||||
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
|
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
|
||||||
|
@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
|
|
||||||
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
|
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
|
||||||
| hir::LifetimeName::ImplicitObjectLifetimeDefault
|
| hir::LifetimeName::ImplicitObjectLifetimeDefault
|
||||||
| hir::LifetimeName::Underscore => {
|
| hir::LifetimeName::Infer => {
|
||||||
// In this case, the user left off the lifetime; so
|
// In this case, the user left off the lifetime; so
|
||||||
// they wrote something like:
|
// they wrote something like:
|
||||||
//
|
//
|
||||||
|
@ -738,11 +738,8 @@ pub enum LifetimeRes {
|
|||||||
binder: NodeId,
|
binder: NodeId,
|
||||||
},
|
},
|
||||||
/// This variant is used for anonymous lifetimes that we did not resolve during
|
/// This variant is used for anonymous lifetimes that we did not resolve during
|
||||||
/// late resolution. Shifting the work to the HIR lifetime resolver.
|
/// late resolution. Those lifetimes will be inferred by typechecking.
|
||||||
Anonymous {
|
Infer,
|
||||||
/// Id of the introducing place. See `Param`.
|
|
||||||
binder: NodeId,
|
|
||||||
},
|
|
||||||
/// Explicit `'static` lifetime.
|
/// Explicit `'static` lifetime.
|
||||||
Static,
|
Static,
|
||||||
/// Resolution failure.
|
/// Resolution failure.
|
||||||
|
@ -108,7 +108,8 @@ pub enum LifetimeName {
|
|||||||
Error,
|
Error,
|
||||||
|
|
||||||
/// User wrote an anonymous lifetime, either `'_` or nothing.
|
/// User wrote an anonymous lifetime, either `'_` or nothing.
|
||||||
Underscore,
|
/// The semantics of this lifetime should be inferred by typechecking code.
|
||||||
|
Infer,
|
||||||
|
|
||||||
/// User wrote `'static`.
|
/// User wrote `'static`.
|
||||||
Static,
|
Static,
|
||||||
@ -118,7 +119,7 @@ impl LifetimeName {
|
|||||||
pub fn ident(&self) -> Ident {
|
pub fn ident(&self) -> Ident {
|
||||||
match *self {
|
match *self {
|
||||||
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(),
|
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(),
|
||||||
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
|
LifetimeName::Infer => Ident::with_dummy_span(kw::UnderscoreLifetime),
|
||||||
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
|
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
|
||||||
LifetimeName::Param(_, param_name) => param_name.ident(),
|
LifetimeName::Param(_, param_name) => param_name.ident(),
|
||||||
}
|
}
|
||||||
@ -127,7 +128,7 @@ impl LifetimeName {
|
|||||||
pub fn is_anonymous(&self) -> bool {
|
pub fn is_anonymous(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
LifetimeName::ImplicitObjectLifetimeDefault
|
LifetimeName::ImplicitObjectLifetimeDefault
|
||||||
| LifetimeName::Underscore
|
| LifetimeName::Infer
|
||||||
| LifetimeName::Param(_, ParamName::Fresh)
|
| LifetimeName::Param(_, ParamName::Fresh)
|
||||||
| LifetimeName::Error => true,
|
| LifetimeName::Error => true,
|
||||||
LifetimeName::Static | LifetimeName::Param(..) => false,
|
LifetimeName::Static | LifetimeName::Param(..) => false,
|
||||||
@ -136,7 +137,7 @@ impl LifetimeName {
|
|||||||
|
|
||||||
pub fn is_elided(&self) -> bool {
|
pub fn is_elided(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Underscore => true,
|
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
|
||||||
|
|
||||||
// It might seem surprising that `Fresh` counts as
|
// It might seem surprising that `Fresh` counts as
|
||||||
// *not* elided -- but this is because, as far as the code
|
// *not* elided -- but this is because, as far as the code
|
||||||
|
@ -497,7 +497,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
|
|||||||
| LifetimeName::Static
|
| LifetimeName::Static
|
||||||
| LifetimeName::Error
|
| LifetimeName::Error
|
||||||
| LifetimeName::ImplicitObjectLifetimeDefault
|
| LifetimeName::ImplicitObjectLifetimeDefault
|
||||||
| LifetimeName::Underscore => {}
|
| LifetimeName::Infer => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||||||
let previous_state = replace(&mut this.in_func_body, true);
|
let previous_state = replace(&mut this.in_func_body, true);
|
||||||
// Resolve the function body, potentially inside the body of an async closure
|
// Resolve the function body, potentially inside the body of an async closure
|
||||||
this.with_lifetime_rib(
|
this.with_lifetime_rib(
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }),
|
LifetimeRibKind::Elided(LifetimeRes::Infer),
|
||||||
|this| this.visit_block(body),
|
|this| this.visit_block(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -893,9 +893,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||||||
this.with_lifetime_rib(
|
this.with_lifetime_rib(
|
||||||
match binder {
|
match binder {
|
||||||
ClosureBinder::NotPresent => {
|
ClosureBinder::NotPresent => {
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous {
|
LifetimeRibKind::Elided(LifetimeRes::Infer)
|
||||||
binder: fn_id,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
|
ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
|
||||||
},
|
},
|
||||||
@ -907,7 +905,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||||||
let previous_state = replace(&mut this.in_func_body, true);
|
let previous_state = replace(&mut this.in_func_body, true);
|
||||||
// Resolve the function body, potentially inside the body of an async closure
|
// Resolve the function body, potentially inside the body of an async closure
|
||||||
this.with_lifetime_rib(
|
this.with_lifetime_rib(
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }),
|
LifetimeRibKind::Elided(LifetimeRes::Infer),
|
||||||
|this| this.visit_expr(body),
|
|this| this.visit_expr(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1645,35 +1643,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
|
|
||||||
if !missing {
|
if !missing {
|
||||||
// Do not create a parameter for patterns and expressions.
|
// Do not create a parameter for patterns and expressions.
|
||||||
for rib in self.lifetime_ribs.iter().rev() {
|
for id in node_ids {
|
||||||
match rib.kind {
|
self.record_lifetime_res(
|
||||||
LifetimeRibKind::Elided(res @ LifetimeRes::Anonymous { .. }) => {
|
id,
|
||||||
for id in node_ids {
|
LifetimeRes::Infer,
|
||||||
self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named);
|
LifetimeElisionCandidate::Named,
|
||||||
}
|
);
|
||||||
break;
|
|
||||||
}
|
|
||||||
// `LifetimeRes::Error`, which would usually be used in the case of
|
|
||||||
// `ReportError`, is unsuitable here, as we don't emit an error yet. Instead,
|
|
||||||
// we simply resolve to an implicit lifetime, which will be checked later, at
|
|
||||||
// which point a suitable error will be emitted.
|
|
||||||
LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
|
|
||||||
// FIXME(cjgillot) This resolution is wrong, but this does not matter
|
|
||||||
// since these cases are erroneous anyway. Lifetime resolution should
|
|
||||||
// emit a "missing lifetime specifier" diagnostic.
|
|
||||||
let res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID };
|
|
||||||
for id in node_ids {
|
|
||||||
self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
LifetimeRibKind::AnonymousCreateParameter { .. }
|
|
||||||
| LifetimeRibKind::Elided(_)
|
|
||||||
| LifetimeRibKind::ElisionFailure
|
|
||||||
| LifetimeRibKind::Generics { .. }
|
|
||||||
| LifetimeRibKind::ConstGeneric
|
|
||||||
| LifetimeRibKind::AnonConst => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1814,15 +1789,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
match res {
|
match res {
|
||||||
LifetimeRes::Param { .. }
|
LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
|
||||||
| LifetimeRes::Fresh { .. }
|
|
||||||
| LifetimeRes::Anonymous { .. }
|
|
||||||
| LifetimeRes::Static => {
|
|
||||||
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
|
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
|
||||||
candidates.insert(res, candidate);
|
candidates.insert(res, candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
|
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2245,26 +2217,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
|
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
|
||||||
this.visit_ty(ty);
|
this.visit_ty(ty);
|
||||||
});
|
});
|
||||||
this.with_lifetime_rib(
|
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }),
|
if let Some(expr) = expr {
|
||||||
|this| {
|
let constant_item_kind = match item.kind {
|
||||||
if let Some(expr) = expr {
|
ItemKind::Const(..) => ConstantItemKind::Const,
|
||||||
let constant_item_kind = match item.kind {
|
ItemKind::Static(..) => ConstantItemKind::Static,
|
||||||
ItemKind::Const(..) => ConstantItemKind::Const,
|
_ => unreachable!(),
|
||||||
ItemKind::Static(..) => ConstantItemKind::Static,
|
};
|
||||||
_ => unreachable!(),
|
// We already forbid generic params because of the above item rib,
|
||||||
};
|
// so it doesn't matter whether this is a trivial constant.
|
||||||
// We already forbid generic params because of the above item rib,
|
this.with_constant_rib(
|
||||||
// so it doesn't matter whether this is a trivial constant.
|
IsRepeatExpr::No,
|
||||||
this.with_constant_rib(
|
HasGenericParams::Yes,
|
||||||
IsRepeatExpr::No,
|
Some((item.ident, constant_item_kind)),
|
||||||
HasGenericParams::Yes,
|
|this| this.visit_expr(expr),
|
||||||
Some((item.ident, constant_item_kind)),
|
);
|
||||||
|this| this.visit_expr(expr),
|
}
|
||||||
);
|
});
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2521,7 +2490,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
// Type parameters can already be used and as associated consts are
|
// Type parameters can already be used and as associated consts are
|
||||||
// not used as part of the type system, this is far less surprising.
|
// not used as part of the type system, this is far less surprising.
|
||||||
self.with_lifetime_rib(
|
self.with_lifetime_rib(
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }),
|
LifetimeRibKind::Elided(LifetimeRes::Infer),
|
||||||
|this| {
|
|this| {
|
||||||
this.with_constant_rib(
|
this.with_constant_rib(
|
||||||
IsRepeatExpr::No,
|
IsRepeatExpr::No,
|
||||||
@ -2694,17 +2663,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
//
|
//
|
||||||
// Type parameters can already be used and as associated consts are
|
// Type parameters can already be used and as associated consts are
|
||||||
// not used as part of the type system, this is far less surprising.
|
// not used as part of the type system, this is far less surprising.
|
||||||
self.with_lifetime_rib(
|
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||||
LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }),
|
this.with_constant_rib(
|
||||||
|this| {
|
IsRepeatExpr::No,
|
||||||
this.with_constant_rib(
|
HasGenericParams::Yes,
|
||||||
IsRepeatExpr::No,
|
None,
|
||||||
HasGenericParams::Yes,
|
|this| this.visit_expr(expr),
|
||||||
None,
|
)
|
||||||
|this| this.visit_expr(expr),
|
});
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
||||||
|
@ -819,7 +819,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
// `Box<dyn Debug + 'static>`.
|
// `Box<dyn Debug + 'static>`.
|
||||||
self.resolve_object_lifetime_default(lifetime)
|
self.resolve_object_lifetime_default(lifetime)
|
||||||
}
|
}
|
||||||
LifetimeName::Underscore => {
|
LifetimeName::Infer => {
|
||||||
// If the user writes `'_`, we use the *ordinary* elision
|
// If the user writes `'_`, we use the *ordinary* elision
|
||||||
// rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
|
// rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
|
||||||
// resolved the same as the `'_` in `&'_ Foo`.
|
// resolved the same as the `'_` in `&'_ Foo`.
|
||||||
@ -1135,7 +1135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||||
match lifetime_ref.name {
|
match lifetime_ref.name {
|
||||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Underscore => {
|
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => {
|
||||||
self.resolve_elided_lifetimes(&[lifetime_ref])
|
self.resolve_elided_lifetimes(&[lifetime_ref])
|
||||||
}
|
}
|
||||||
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
|
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
|
||||||
|
@ -166,7 +166,7 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
|
|||||||
// - There's only one output lifetime bound using `+ '_`
|
// - There's only one output lifetime bound using `+ '_`
|
||||||
// - All input lifetimes are explicitly bound to the output
|
// - All input lifetimes are explicitly bound to the output
|
||||||
input_lifetimes.is_empty()
|
input_lifetimes.is_empty()
|
||||||
|| (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Underscore))
|
|| (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Infer))
|
||||||
|| input_lifetimes
|
|| input_lifetimes
|
||||||
.iter()
|
.iter()
|
||||||
.all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
|
.all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
|
||||||
|
@ -351,7 +351,7 @@ impl fmt::Display for RefPrefix {
|
|||||||
name.fmt(f)?;
|
name.fmt(f)?;
|
||||||
f.write_char(' ')?;
|
f.write_char(' ')?;
|
||||||
},
|
},
|
||||||
LifetimeName::Underscore => f.write_str("'_ ")?,
|
LifetimeName::Infer => f.write_str("'_ ")?,
|
||||||
LifetimeName::Static => f.write_str("'static ")?,
|
LifetimeName::Static => f.write_str("'static ")?,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user