-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove in band lifetimes #93845
Remove in band lifetimes #93845
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,13 +142,9 @@ struct LoweringContext<'a, 'hir: 'a> { | |
/// indicate whether or not we're in a place where new lifetimes will result | ||
/// in in-band lifetime definitions, such a function or an impl header, | ||
/// including implicit lifetimes from `impl_header_lifetime_elision`. | ||
is_collecting_in_band_lifetimes: bool, | ||
is_collecting_anonymous_lifetimes: bool, | ||
|
||
/// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB. | ||
/// When `is_collecting_in_band_lifetimes` is true, each lifetime is checked | ||
/// against this list to see if it is already in-scope, or if a definition | ||
/// needs to be created for it. | ||
/// | ||
/// We always store a `normalize_to_macros_2_0()` version of the param-name in this | ||
/// vector. | ||
in_scope_lifetimes: Vec<ParamName>, | ||
|
@@ -379,7 +375,7 @@ pub fn lower_crate<'a, 'hir>( | |
task_context: None, | ||
current_item: None, | ||
lifetimes_to_define: Vec::new(), | ||
is_collecting_in_band_lifetimes: false, | ||
is_collecting_anonymous_lifetimes: false, | ||
in_scope_lifetimes: Vec::new(), | ||
allow_try_trait: Some([sym::try_trait_v2][..].into()), | ||
allow_gen_future: Some([sym::gen_future][..].into()), | ||
|
@@ -726,13 +722,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
&mut self, | ||
f: impl FnOnce(&mut Self) -> T, | ||
) -> (Vec<(Span, ParamName)>, T) { | ||
let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true); | ||
let was_collecting = std::mem::replace(&mut self.is_collecting_anonymous_lifetimes, true); | ||
let len = self.lifetimes_to_define.len(); | ||
|
||
let res = f(self); | ||
|
||
let lifetimes_to_define = self.lifetimes_to_define.split_off(len); | ||
self.is_collecting_in_band_lifetimes = was_collecting; | ||
self.is_collecting_anonymous_lifetimes = was_collecting; | ||
(lifetimes_to_define, res) | ||
} | ||
|
||
|
@@ -749,7 +745,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
// that collisions are ok here and this shouldn't | ||
// really show up for end-user. | ||
let (str_name, kind) = match hir_name { | ||
ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::InBand), | ||
ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::Explicit), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only suspicious change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Async blocks, for example, declare named elided lifetimes (idk if that's the only one, perhaps closures?). We should give them a category here -- not sure if it's correct to use It all funnels into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This case should only happen when synthetizing lifetimes for an async fn return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once |
||
ParamName::Fresh(_) => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided), | ||
ParamName::Error => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Error), | ||
}; | ||
|
@@ -773,38 +769,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
} | ||
} | ||
|
||
/// 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, ident: Ident) { | ||
if !self.is_collecting_in_band_lifetimes { | ||
return; | ||
} | ||
|
||
if !self.sess.features_untracked().in_band_lifetimes { | ||
return; | ||
} | ||
|
||
if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.normalize_to_macros_2_0())) { | ||
return; | ||
} | ||
|
||
let hir_name = ParamName::Plain(ident); | ||
|
||
if self.lifetimes_to_define.iter().any(|(_, lt_name)| { | ||
lt_name.normalize_to_macros_2_0() == hir_name.normalize_to_macros_2_0() | ||
}) { | ||
return; | ||
} | ||
|
||
self.lifetimes_to_define.push((ident.span, hir_name)); | ||
} | ||
|
||
/// When we have either an elided or `'_` lifetime in an impl | ||
/// header, we convert it to an in-band lifetime. | ||
fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName { | ||
assert!(self.is_collecting_in_band_lifetimes); | ||
fn collect_fresh_anonymous_lifetime(&mut self, span: Span) -> ParamName { | ||
assert!(self.is_collecting_anonymous_lifetimes); | ||
let index = self.lifetimes_to_define.len() + self.in_scope_lifetimes.len(); | ||
let hir_name = ParamName::Fresh(index); | ||
self.lifetimes_to_define.push((span, hir_name)); | ||
|
@@ -1946,7 +1914,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
} | ||
ident if ident.name == kw::UnderscoreLifetime => match self.anonymous_lifetime_mode { | ||
AnonymousLifetimeMode::CreateParameter => { | ||
let fresh_name = self.collect_fresh_in_band_lifetime(span); | ||
let fresh_name = self.collect_fresh_anonymous_lifetime(span); | ||
self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name)) | ||
} | ||
|
||
|
@@ -1957,7 +1925,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span), | ||
}, | ||
ident => { | ||
self.maybe_collect_in_band_lifetime(ident); | ||
let param_name = ParamName::Plain(self.lower_ident(ident)); | ||
self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name)) | ||
} | ||
|
@@ -2001,8 +1968,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
|
||
let (name, kind) = match param.kind { | ||
GenericParamKind::Lifetime => { | ||
let was_collecting_in_band = self.is_collecting_in_band_lifetimes; | ||
self.is_collecting_in_band_lifetimes = false; | ||
let was_collecting_in_band = self.is_collecting_anonymous_lifetimes; | ||
self.is_collecting_anonymous_lifetimes = false; | ||
|
||
let lt = self | ||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| { | ||
|
@@ -2025,7 +1992,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
let kind = | ||
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; | ||
|
||
self.is_collecting_in_band_lifetimes = was_collecting_in_band; | ||
self.is_collecting_anonymous_lifetimes = was_collecting_in_band; | ||
|
||
(param_name, kind) | ||
} | ||
|
@@ -2384,7 +2351,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
// Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh | ||
// `'f`. | ||
AnonymousLifetimeMode::CreateParameter => { | ||
let fresh_name = self.collect_fresh_in_band_lifetime(span); | ||
let fresh_name = self.collect_fresh_anonymous_lifetime(span); | ||
hir::Lifetime { | ||
hir_id: self.next_id(), | ||
span: self.lower_span(span), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed this to
anonymous
, since this handles both elided and in-band lifetimes, but we now only have the former. Open to calling this something likeis_collecting_elided_lifetimes
tho!