#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
pub struct Lifetime {
pub hir_id: HirId,
- pub ident: Ident,
/// Either "`'a`", referring to a named lifetime definition,
- /// or "``" (i.e., `kw::Empty`), for elision placeholders.
+ /// `'_` referring to an anonymous lifetime (either explicitly `'_` or `&type`),
+ /// or "``" (i.e., `kw::Empty`) when appearing in path.
///
- /// HIR lowering inserts these placeholders in type paths that
- /// refer to type definitions needing lifetime parameters,
- /// `&T` and `&mut T`, and trait objects without `... + 'a`.
+ /// See `Lifetime::suggestion_position` for practical use.
+ pub ident: Ident,
+
+ /// Semantics of this lifetime.
pub res: LifetimeName,
}
impl fmt::Display for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.ident.fmt(f)
+ if self.ident.name != kw::Empty { self.ident.name.fmt(f) } else { "'_".fmt(f) }
}
}
+pub enum LifetimeSuggestionPosition {
+ /// The user wrote `'a` or `'_`.
+ Normal,
+ /// The user wrote `&type` or `&mut type`.
+ Ampersand,
+ /// The user wrote `Path` and omitted the `<'_>`.
+ ElidedPath,
+ /// The user wrote `Path<T>`, and omitted the `'_,`.
+ ElidedPathArgument,
+ /// The user wrote `dyn Trait` and omitted the `+ '_`.
+ ObjectDefault,
+}
+
impl Lifetime {
pub fn is_elided(&self) -> bool {
self.res.is_elided()
self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime
}
+ pub fn suggestion_position(&self) -> (LifetimeSuggestionPosition, Span) {
+ if self.ident.name == kw::Empty {
+ if self.ident.span.is_empty() {
+ (LifetimeSuggestionPosition::ElidedPathArgument, self.ident.span)
+ } else {
+ (LifetimeSuggestionPosition::ElidedPath, self.ident.span.shrink_to_hi())
+ }
+ } else if self.res == LifetimeName::ImplicitObjectLifetimeDefault {
+ (LifetimeSuggestionPosition::ObjectDefault, self.ident.span)
+ } else if self.ident.span.is_empty() {
+ (LifetimeSuggestionPosition::Ampersand, self.ident.span)
+ } else {
+ (LifetimeSuggestionPosition::Normal, self.ident.span)
+ }
+ }
+
pub fn is_static(&self) -> bool {
self.res == LifetimeName::Static
}
pub c_variadic: bool,
/// Does the function have an implicit self?
pub implicit_self: ImplicitSelfKind,
+ /// Is lifetime elision allowed.
+ pub lifetime_elision_allowed: bool,
}
/// Represents what type of implicit self a function has, if any.