Introduce AnonymousLifetimeRib::Elided and use it for implied 'static.

This commit is contained in:
Camille GILLOT 2022-04-18 17:51:39 +02:00
parent a7468c60f8
commit bfd0435fd7
2 changed files with 29 additions and 3 deletions

View File

@ -713,7 +713,7 @@ impl<Id> Res<Id> {
}
/// Resolution for a lifetime appearing in a type.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LifetimeRes {
/// Successfully linked the lifetime to a generic parameter.
Param {

View File

@ -259,6 +259,9 @@ enum LifetimeRibKind {
/// Pass responsibility to `resolve_lifetime` code for all cases.
AnonymousPassThrough(NodeId, /* in_fn_return */ bool),
/// Replace all anonymous lifetimes by provided lifetime.
Elided(LifetimeRes),
}
#[derive(Copy, Clone, Debug)]
@ -580,7 +583,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
// We deal with repeat expressions explicitly in `resolve_expr`.
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
this.resolve_anon_const(constant, IsRepeatExpr::No);
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
this.resolve_anon_const(constant, IsRepeatExpr::No);
})
})
}
fn visit_expr(&mut self, expr: &'ast Expr) {
@ -1052,6 +1057,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
LifetimeRibKind::AnonymousPassThrough(..)
| LifetimeRibKind::AnonymousCreateParameter { .. }
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::AnonConst
| LifetimeRibKind::ConstGeneric => {}
}
@ -1408,6 +1414,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
| LifetimeRibKind::AnonymousCreateParameter { .. } => {
Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt })
}
// Only report if eliding the lifetime would have the same
// semantics.
LifetimeRibKind::Elided(r) => Some(if res == r {
LifetimeUseSet::One { use_span: ident.span, use_ctxt }
} else {
LifetimeUseSet::Many
}),
LifetimeRibKind::Generics { .. }
| LifetimeRibKind::ConstGeneric
| LifetimeRibKind::AnonConst => None,
@ -1496,6 +1509,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
);
return;
}
LifetimeRibKind::Elided(res) => {
self.record_lifetime_res(lifetime.id, res);
return;
}
LifetimeRibKind::Item => break,
LifetimeRibKind::Generics { .. }
| LifetimeRibKind::ConstGeneric
@ -1632,6 +1649,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
break;
}
LifetimeRibKind::AnonymousCreateParameter { .. }
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::Generics { .. }
| LifetimeRibKind::ConstGeneric
| LifetimeRibKind::AnonConst => {}
@ -1690,6 +1708,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
}
break;
}
LifetimeRibKind::Elided(res) => {
for id in node_ids {
self.record_lifetime_res(id, res);
}
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
@ -3581,7 +3605,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ExprKind::Repeat(ref elem, ref ct) => {
self.visit_expr(elem);
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
this.resolve_anon_const(ct, IsRepeatExpr::Yes)
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
this.resolve_anon_const(ct, IsRepeatExpr::Yes)
})
});
}
ExprKind::ConstBlock(ref ct) => {