add a helper function maybe_collect_in_band_lifetime
This commit is contained in:
parent
f71807d507
commit
f07ebc5df8
1 changed files with 44 additions and 15 deletions
|
@ -600,6 +600,29 @@ impl<'a> LoweringContext<'a> {
|
||||||
(params, res)
|
(params, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When there is a reference to some lifetime `'a`, and in-band
|
||||||
|
/// lifetimes are enabled, then we want to push that lifetime into
|
||||||
|
/// the vector of names to define later. In that case, it will get
|
||||||
|
/// added to the appropriate generics.
|
||||||
|
fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
|
||||||
|
if !self.is_collecting_in_band_lifetimes {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.in_scope_lifetimes.contains(&name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.lifetimes_to_define
|
||||||
|
.iter()
|
||||||
|
.any(|(_, lt_name)| *lt_name == name)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lifetimes_to_define.push((span, name));
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
|
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
|
||||||
// This is used to track which lifetimes have already been defined, and
|
// This is used to track which lifetimes have already been defined, and
|
||||||
// which are new in-band lifetimes that need to have a definition created
|
// which are new in-band lifetimes that need to have a definition created
|
||||||
|
@ -1726,15 +1749,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
x if x == "'_" => hir::LifetimeName::Underscore,
|
x if x == "'_" => hir::LifetimeName::Underscore,
|
||||||
x if x == "'static" => hir::LifetimeName::Static,
|
x if x == "'static" => hir::LifetimeName::Static,
|
||||||
name => {
|
name => {
|
||||||
if self.is_collecting_in_band_lifetimes && !self.in_scope_lifetimes.contains(&name)
|
self.maybe_collect_in_band_lifetime(l.span, name);
|
||||||
&& self.lifetimes_to_define
|
|
||||||
.iter()
|
|
||||||
.find(|&&(_, lt_name)| lt_name == name)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
self.lifetimes_to_define.push((l.span, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::LifetimeName::Name(name)
|
hir::LifetimeName::Name(name)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2132,18 +2147,32 @@ impl<'a> LoweringContext<'a> {
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
ref ast_generics,
|
ref ast_generics,
|
||||||
ref ifce,
|
ref trait_ref,
|
||||||
ref ty,
|
ref ty,
|
||||||
ref impl_items,
|
ref impl_items,
|
||||||
) => {
|
) => {
|
||||||
let def_id = self.resolver.definitions().local_def_id(id);
|
let def_id = self.resolver.definitions().local_def_id(id);
|
||||||
let (generics, (ifce, lowered_ty)) =
|
|
||||||
|
// Lower the "impl header" first. This ordering is important
|
||||||
|
// for in-band lifetimes! Consider `'a` here:
|
||||||
|
//
|
||||||
|
// impl Foo<'a> for u32 {
|
||||||
|
// fn method(&'a self) { .. }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Because we start by lowering the `Foo<'a> for u32`
|
||||||
|
// part, we will add `'a` to the list of generics on
|
||||||
|
// the impl. When we then encounter it later in the
|
||||||
|
// method, it will not be considered an in-band
|
||||||
|
// lifetime to be added, but rather a reference to a
|
||||||
|
// parent lifetime.
|
||||||
|
let (generics, (trait_ref, lowered_ty)) =
|
||||||
self.add_in_band_defs(ast_generics, def_id, |this| {
|
self.add_in_band_defs(ast_generics, def_id, |this| {
|
||||||
let ifce = ifce.as_ref().map(|trait_ref| {
|
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
|
||||||
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
|
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref trait_ref) = ifce {
|
if let Some(ref trait_ref) = trait_ref {
|
||||||
if let Def::Trait(def_id) = trait_ref.path.def {
|
if let Def::Trait(def_id) = trait_ref.path.def {
|
||||||
this.trait_impls.entry(def_id).or_insert(vec![]).push(id);
|
this.trait_impls.entry(def_id).or_insert(vec![]).push(id);
|
||||||
}
|
}
|
||||||
|
@ -2151,7 +2180,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
|
let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
|
||||||
|
|
||||||
(ifce, lowered_ty)
|
(trait_ref, lowered_ty)
|
||||||
});
|
});
|
||||||
|
|
||||||
let new_impl_items = self.with_in_scope_lifetime_defs(
|
let new_impl_items = self.with_in_scope_lifetime_defs(
|
||||||
|
@ -2172,7 +2201,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
self.lower_impl_polarity(polarity),
|
self.lower_impl_polarity(polarity),
|
||||||
self.lower_defaultness(defaultness, true /* [1] */),
|
self.lower_defaultness(defaultness, true /* [1] */),
|
||||||
generics,
|
generics,
|
||||||
ifce,
|
trait_ref,
|
||||||
lowered_ty,
|
lowered_ty,
|
||||||
new_impl_items,
|
new_impl_items,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue