Arena allocate LifetimeRefs

This commit is contained in:
Lukas Wirth 2025-04-24 09:55:06 +02:00
parent 99a7e423e2
commit 61df8ec4b8
13 changed files with 126 additions and 60 deletions

View File

@ -31,7 +31,7 @@ use crate::{
PatId, RecordFieldPat, Statement, PatId, RecordFieldPat, Statement,
}, },
nameres::DefMap, nameres::DefMap,
type_ref::{PathId, TypeRef, TypeRefId}, type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId},
}; };
pub use self::body::{Body, BodySourceMap}; pub use self::body::{Body, BodySourceMap};
@ -87,6 +87,9 @@ pub type MacroCallPtr = AstPtr<ast::MacroCall>;
pub type TypePtr = AstPtr<ast::Type>; pub type TypePtr = AstPtr<ast::Type>;
pub type TypeSource = InFile<TypePtr>; pub type TypeSource = InFile<TypePtr>;
pub type LifetimePtr = AstPtr<ast::Lifetime>;
pub type LifetimeSource = InFile<LifetimePtr>;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct ExpressionStore { pub struct ExpressionStore {
pub exprs: Arena<Expr>, pub exprs: Arena<Expr>,
@ -94,6 +97,7 @@ pub struct ExpressionStore {
pub bindings: Arena<Binding>, pub bindings: Arena<Binding>,
pub labels: Arena<Label>, pub labels: Arena<Label>,
pub types: Arena<TypeRef>, pub types: Arena<TypeRef>,
pub lifetimes: Arena<LifetimeRef>,
/// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the /// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the
/// top level expression, it will not be listed in here. /// top level expression, it will not be listed in here.
pub binding_owners: FxHashMap<BindingId, ExprId>, pub binding_owners: FxHashMap<BindingId, ExprId>,
@ -130,6 +134,9 @@ pub struct ExpressionStoreSourceMap {
types_map_back: ArenaMap<TypeRefId, TypeSource>, types_map_back: ArenaMap<TypeRefId, TypeSource>,
types_map: FxHashMap<TypeSource, TypeRefId>, types_map: FxHashMap<TypeSource, TypeRefId>,
lifetime_map_back: ArenaMap<LifetimeRefId, LifetimeSource>,
lifetime_map: FxHashMap<LifetimeSource, LifetimeRefId>,
template_map: Option<Box<FormatTemplate>>, template_map: Option<Box<FormatTemplate>>,
pub expansions: FxHashMap<InFile<MacroCallPtr>, MacroCallId>, pub expansions: FxHashMap<InFile<MacroCallPtr>, MacroCallId>,
@ -146,6 +153,7 @@ pub struct ExpressionStoreBuilder {
pub pats: Arena<Pat>, pub pats: Arena<Pat>,
pub bindings: Arena<Binding>, pub bindings: Arena<Binding>,
pub labels: Arena<Label>, pub labels: Arena<Label>,
pub lifetimes: Arena<LifetimeRef>,
pub binding_owners: FxHashMap<BindingId, ExprId>, pub binding_owners: FxHashMap<BindingId, ExprId>,
pub types: Arena<TypeRef>, pub types: Arena<TypeRef>,
block_scopes: Vec<BlockId>, block_scopes: Vec<BlockId>,
@ -187,6 +195,7 @@ impl ExpressionStoreBuilder {
mut binding_owners, mut binding_owners,
mut ident_hygiene, mut ident_hygiene,
mut types, mut types,
mut lifetimes,
} = self; } = self;
exprs.shrink_to_fit(); exprs.shrink_to_fit();
labels.shrink_to_fit(); labels.shrink_to_fit();
@ -195,6 +204,7 @@ impl ExpressionStoreBuilder {
binding_owners.shrink_to_fit(); binding_owners.shrink_to_fit();
ident_hygiene.shrink_to_fit(); ident_hygiene.shrink_to_fit();
types.shrink_to_fit(); types.shrink_to_fit();
lifetimes.shrink_to_fit();
ExpressionStore { ExpressionStore {
exprs, exprs,
@ -203,6 +213,7 @@ impl ExpressionStoreBuilder {
labels, labels,
binding_owners, binding_owners,
types, types,
lifetimes,
block_scopes: block_scopes.into_boxed_slice(), block_scopes: block_scopes.into_boxed_slice(),
ident_hygiene, ident_hygiene,
} }
@ -604,6 +615,15 @@ impl Index<TypeRefId> for ExpressionStore {
&self.types[b] &self.types[b]
} }
} }
impl Index<LifetimeRefId> for ExpressionStore {
type Output = LifetimeRef;
fn index(&self, b: LifetimeRefId) -> &LifetimeRef {
&self.lifetimes[b]
}
}
impl Index<PathId> for ExpressionStore { impl Index<PathId> for ExpressionStore {
type Output = Path; type Output = Path;
@ -745,6 +765,8 @@ impl ExpressionStoreSourceMap {
binding_definitions, binding_definitions,
types_map, types_map,
types_map_back, types_map_back,
lifetime_map_back,
lifetime_map,
} = self; } = self;
if let Some(template_map) = template_map { if let Some(template_map) = template_map {
let FormatTemplate { let FormatTemplate {
@ -769,5 +791,7 @@ impl ExpressionStoreSourceMap {
binding_definitions.shrink_to_fit(); binding_definitions.shrink_to_fit();
types_map.shrink_to_fit(); types_map.shrink_to_fit();
types_map_back.shrink_to_fit(); types_map_back.shrink_to_fit();
lifetime_map.shrink_to_fit();
lifetime_map_back.shrink_to_fit();
} }
} }

View File

@ -35,7 +35,8 @@ use crate::{
db::DefDatabase, db::DefDatabase,
expr_store::{ expr_store::{
Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder, Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr, TypePtr, ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr,
PatPtr, TypePtr,
expander::Expander, expander::Expander,
lower::generics::ImplTraitLowerFn, lower::generics::ImplTraitLowerFn,
path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path}, path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path},
@ -56,8 +57,8 @@ use crate::{
lang_item::LangItem, lang_item::LangItem,
nameres::{DefMap, LocalDefMap, MacroSubNs}, nameres::{DefMap, LocalDefMap, MacroSubNs},
type_ref::{ type_ref::{
ArrayType, ConstRef, FnType, LifetimeRef, Mutability, PathId, Rawness, RefType, ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness,
TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
}, },
}; };
@ -568,20 +569,21 @@ impl ExprCollector<'_> {
} }
} }
pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRef { pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId {
// FIXME: Keyword check? // FIXME: Keyword check?
match &*lifetime.text() { let lifetime_ref = match &*lifetime.text() {
"" | "'" => LifetimeRef::Error, "" | "'" => LifetimeRef::Error,
"'static" => LifetimeRef::Static, "'static" => LifetimeRef::Static,
"'_" => LifetimeRef::Placeholder, "'_" => LifetimeRef::Placeholder,
text => LifetimeRef::Named(Name::new_lifetime(text)), text => LifetimeRef::Named(Name::new_lifetime(text)),
} };
self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime))
} }
pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRef { pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRefId {
match lifetime { match lifetime {
Some(lifetime) => self.lower_lifetime_ref(lifetime), Some(lifetime) => self.lower_lifetime_ref(lifetime),
None => LifetimeRef::Placeholder, None => self.alloc_lifetime_ref_desugared(LifetimeRef::Placeholder),
} }
} }
@ -735,6 +737,30 @@ impl ExprCollector<'_> {
id id
} }
fn alloc_lifetime_ref(
&mut self,
lifetime_ref: LifetimeRef,
node: LifetimePtr,
) -> LifetimeRefId {
let id = self.store.lifetimes.alloc(lifetime_ref);
let ptr = self.expander.in_file(node);
self.source_map.lifetime_map_back.insert(id, ptr);
self.source_map.lifetime_map.insert(ptr, id);
id
}
fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
self.store.types.alloc(type_ref)
}
fn alloc_lifetime_ref_desugared(&mut self, lifetime_ref: LifetimeRef) -> LifetimeRefId {
self.store.lifetimes.alloc(lifetime_ref)
}
fn alloc_error_type(&mut self) -> TypeRefId {
self.store.types.alloc(TypeRef::Error)
}
pub fn lower_path( pub fn lower_path(
&mut self, &mut self,
ast: ast::Path, ast: ast::Path,
@ -754,14 +780,6 @@ impl ExprCollector<'_> {
result result
} }
fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
self.store.types.alloc(type_ref)
}
fn alloc_error_type(&mut self) -> TypeRefId {
self.store.types.alloc(TypeRef::Error)
}
pub fn impl_trait_error_allocator( pub fn impl_trait_error_allocator(
ec: &mut ExprCollector<'_>, ec: &mut ExprCollector<'_>,
ptr: TypePtr, ptr: TypePtr,
@ -962,7 +980,7 @@ impl ExprCollector<'_> {
.lifetime_params() .lifetime_params()
.flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text()))) .flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
.collect(), .collect(),
None => Box::default(), None => ThinVec::default(),
}; };
let path = for_type.ty().and_then(|ty| match &ty { let path = for_type.ty().and_then(|ty| match &ty {
ast::Type::PathType(path_type) => { ast::Type::PathType(path_type) => {

View File

@ -20,7 +20,7 @@ use crate::{
ConstParamData, GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamData, ConstParamData, GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamData,
TypeParamProvenance, WherePredicate, TypeParamProvenance, WherePredicate,
}, },
type_ref::{LifetimeRef, TypeBound, TypeRef, TypeRefId}, type_ref::{LifetimeRef, LifetimeRefId, TypeBound, TypeRef, TypeRefId},
}; };
pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db> FnMut( pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db> FnMut(
@ -149,14 +149,14 @@ impl GenericParamsCollector {
let _idx = self.type_or_consts.alloc(param.into()); let _idx = self.type_or_consts.alloc(param.into());
} }
ast::GenericParam::LifetimeParam(lifetime_param) => { ast::GenericParam::LifetimeParam(lifetime_param) => {
let lifetime_ref = ec.lower_lifetime_ref_opt(lifetime_param.lifetime()); let lifetime = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
if let LifetimeRef::Named(name) = &lifetime_ref { if let LifetimeRef::Named(name) = &ec.store.lifetimes[lifetime] {
let param = LifetimeParamData { name: name.clone() }; let param = LifetimeParamData { name: name.clone() };
let _idx = self.lifetimes.alloc(param); let _idx = self.lifetimes.alloc(param);
self.lower_bounds( self.lower_bounds(
ec, ec,
lifetime_param.type_bound_list(), lifetime_param.type_bound_list(),
Either::Right(lifetime_ref), Either::Right(lifetime),
); );
} }
} }
@ -192,7 +192,7 @@ impl GenericParamsCollector {
.collect() .collect()
}); });
for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target.clone()); self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target);
} }
} }
} }
@ -201,10 +201,10 @@ impl GenericParamsCollector {
&mut self, &mut self,
ec: &mut ExprCollector<'_>, ec: &mut ExprCollector<'_>,
type_bounds: Option<ast::TypeBoundList>, type_bounds: Option<ast::TypeBoundList>,
target: Either<TypeRefId, LifetimeRef>, target: Either<TypeRefId, LifetimeRefId>,
) { ) {
for bound in type_bounds.iter().flat_map(|type_bound_list| type_bound_list.bounds()) { for bound in type_bounds.iter().flat_map(|type_bound_list| type_bound_list.bounds()) {
self.lower_type_bound_as_predicate(ec, bound, None, target.clone()); self.lower_type_bound_as_predicate(ec, bound, None, target);
} }
} }
@ -213,7 +213,7 @@ impl GenericParamsCollector {
ec: &mut ExprCollector<'_>, ec: &mut ExprCollector<'_>,
bound: ast::TypeBound, bound: ast::TypeBound,
hrtb_lifetimes: Option<&[Name]>, hrtb_lifetimes: Option<&[Name]>,
target: Either<TypeRefId, LifetimeRef>, target: Either<TypeRefId, LifetimeRefId>,
) { ) {
let bound = ec.lower_type_bound( let bound = ec.lower_type_bound(
bound, bound,

View File

@ -4,7 +4,7 @@ use std::iter;
use crate::{ use crate::{
lang_item::LangItemTarget, lang_item::LangItemTarget,
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId}, type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
}; };
use hir_expand::{ use hir_expand::{
mod_path::{ModPath, PathKind}, mod_path::{ModPath, PathKind},
@ -91,7 +91,7 @@ pub struct AssociatedTypeBinding {
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum GenericArg { pub enum GenericArg {
Type(TypeRefId), Type(TypeRefId),
Lifetime(LifetimeRef), Lifetime(LifetimeRefId),
Const(ConstRef), Const(ConstRef),
} }

View File

@ -10,7 +10,6 @@ use hir_expand::{Lookup, mod_path::PathKind};
use itertools::Itertools; use itertools::Itertools;
use span::Edition; use span::Edition;
use crate::signatures::StructFlags;
use crate::{ use crate::{
AdtId, DefWithBodyId, GenericDefId, ItemTreeLoc, TypeParamId, VariantId, AdtId, DefWithBodyId, GenericDefId, ItemTreeLoc, TypeParamId, VariantId,
expr_store::path::{GenericArg, GenericArgs}, expr_store::path::{GenericArg, GenericArgs},
@ -22,6 +21,7 @@ use crate::{
signatures::{FnFlags, FunctionSignature, StructSignature}, signatures::{FnFlags, FunctionSignature, StructSignature},
type_ref::{ConstRef, LifetimeRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef}, type_ref::{ConstRef, LifetimeRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef},
}; };
use crate::{LifetimeParamId, signatures::StructFlags};
use crate::{item_tree::FieldsShape, signatures::FieldData}; use crate::{item_tree::FieldsShape, signatures::FieldData};
use super::*; use super::*;
@ -342,9 +342,9 @@ fn print_where_clauses(db: &dyn DefDatabase, generic_params: &GenericParams, p:
p.print_type_bounds(std::slice::from_ref(bound)); p.print_type_bounds(std::slice::from_ref(bound));
} }
WherePredicate::Lifetime { target, bound } => { WherePredicate::Lifetime { target, bound } => {
p.print_lifetime_ref(target); p.print_lifetime_ref(*target);
w!(p, ": "); w!(p, ": ");
p.print_lifetime_ref(bound); p.print_lifetime_ref(*bound);
} }
WherePredicate::ForLifetime { lifetimes, target, bound } => { WherePredicate::ForLifetime { lifetimes, target, bound } => {
w!(p, "for<"); w!(p, "for<");
@ -1199,7 +1199,7 @@ impl Printer<'_> {
match arg { match arg {
GenericArg::Type(ty) => self.print_type_ref(*ty), GenericArg::Type(ty) => self.print_type_ref(*ty),
GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr), GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr),
GenericArg::Lifetime(lt) => self.print_lifetime_ref(lt), GenericArg::Lifetime(lt) => self.print_lifetime_ref(*lt),
} }
} }
@ -1212,14 +1212,20 @@ impl Printer<'_> {
} }
} }
pub(crate) fn print_lifetime_ref(&mut self, lt_ref: &LifetimeRef) { pub(crate) fn print_lifetime_param(&mut self, param: LifetimeParamId) {
match lt_ref { let generic_params = self.db.generic_params(param.parent);
w!(self, "{}", generic_params[param.local_id].name.display(self.db, self.edition))
}
pub(crate) fn print_lifetime_ref(&mut self, lt_ref: LifetimeRefId) {
match &self.store[lt_ref] {
LifetimeRef::Static => w!(self, "'static"), LifetimeRef::Static => w!(self, "'static"),
LifetimeRef::Named(lt) => { LifetimeRef::Named(lt) => {
w!(self, "{}", lt.display(self.db, self.edition)) w!(self, "{}", lt.display(self.db, self.edition))
} }
LifetimeRef::Placeholder => w!(self, "'_"), LifetimeRef::Placeholder => w!(self, "'_"),
LifetimeRef::Error => w!(self, "'{{error}}"), LifetimeRef::Error => w!(self, "'{{error}}"),
&LifetimeRef::Param(p) => self.print_lifetime_param(p),
} }
} }
@ -1255,7 +1261,7 @@ impl Printer<'_> {
}; };
w!(self, "&"); w!(self, "&");
if let Some(lt) = &ref_.lifetime { if let Some(lt) = &ref_.lifetime {
self.print_lifetime_ref(lt); self.print_lifetime_ref(*lt);
w!(self, " "); w!(self, " ");
} }
w!(self, "{mtbl}"); w!(self, "{mtbl}");
@ -1338,7 +1344,7 @@ impl Printer<'_> {
); );
self.print_path(&self.store[*path]); self.print_path(&self.store[*path]);
} }
TypeBound::Lifetime(lt) => self.print_lifetime_ref(lt), TypeBound::Lifetime(lt) => self.print_lifetime_ref(*lt),
TypeBound::Use(args) => { TypeBound::Use(args) => {
w!(self, "use<"); w!(self, "use<");
let mut first = true; let mut first = true;
@ -1350,7 +1356,7 @@ impl Printer<'_> {
UseArgRef::Name(it) => { UseArgRef::Name(it) => {
w!(self, "{}", it.display(self.db, self.edition)) w!(self, "{}", it.display(self.db, self.edition))
} }
UseArgRef::Lifetime(it) => self.print_lifetime_ref(it), UseArgRef::Lifetime(it) => self.print_lifetime_ref(*it),
} }
} }
w!(self, ">") w!(self, ">")

View File

@ -11,7 +11,7 @@ use crate::{
AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId, AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
db::DefDatabase, db::DefDatabase,
expr_store::{ExpressionStore, ExpressionStoreSourceMap}, expr_store::{ExpressionStore, ExpressionStoreSourceMap},
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId}, type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
}; };
pub type LocalTypeOrConstParamId = Idx<TypeOrConstParamData>; pub type LocalTypeOrConstParamId = Idx<TypeOrConstParamData>;
@ -171,7 +171,7 @@ impl ops::Index<LocalLifetimeParamId> for GenericParams {
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum WherePredicate { pub enum WherePredicate {
TypeBound { target: TypeRefId, bound: TypeBound }, TypeBound { target: TypeRefId, bound: TypeBound },
Lifetime { target: LifetimeRef, bound: LifetimeRef }, Lifetime { target: LifetimeRefId, bound: LifetimeRefId },
ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound }, ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound },
} }

View File

@ -9,7 +9,7 @@ use la_arena::Idx;
use thin_vec::ThinVec; use thin_vec::ThinVec;
use crate::{ use crate::{
TypeParamId, LifetimeParamId, TypeParamId,
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
expr_store::{ expr_store::{
ExpressionStore, ExpressionStore,
@ -123,7 +123,7 @@ pub struct ArrayType {
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct RefType { pub struct RefType {
pub ty: TypeRefId, pub ty: TypeRefId,
pub lifetime: Option<LifetimeRef>, pub lifetime: Option<LifetimeRefId>,
pub mutability: Mutability, pub mutability: Mutability,
} }
@ -135,6 +135,8 @@ pub enum TypeRef {
Tuple(ThinVec<TypeRefId>), Tuple(ThinVec<TypeRefId>),
Path(Path), Path(Path),
RawPtr(TypeRefId, Mutability), RawPtr(TypeRefId, Mutability),
// FIXME: Unbox this once `Idx` has a niche,
// as `RefType` should shrink by 4 bytes then
Reference(Box<RefType>), Reference(Box<RefType>),
Array(ArrayType), Array(ArrayType),
Slice(TypeRefId), Slice(TypeRefId),
@ -151,30 +153,33 @@ const _: () = assert!(size_of::<TypeRef>() == 16);
pub type TypeRefId = Idx<TypeRef>; pub type TypeRefId = Idx<TypeRef>;
pub type LifetimeRefId = Idx<LifetimeRef>;
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum LifetimeRef { pub enum LifetimeRef {
Named(Name), Named(Name),
Static, Static,
Placeholder, Placeholder,
Param(LifetimeParamId),
Error, Error,
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum TypeBound { pub enum TypeBound {
Path(PathId, TraitBoundModifier), Path(PathId, TraitBoundModifier),
ForLifetime(Box<[Name]>, PathId), ForLifetime(ThinVec<Name>, PathId),
Lifetime(LifetimeRef), Lifetime(LifetimeRefId),
Use(Box<[UseArgRef]>), Use(ThinVec<UseArgRef>),
Error, Error,
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
const _: [(); 24] = [(); size_of::<TypeBound>()]; const _: [(); 16] = [(); size_of::<TypeBound>()];
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum UseArgRef { pub enum UseArgRef {
Name(Name), Name(Name),
Lifetime(LifetimeRef), Lifetime(LifetimeRefId),
} }
/// A modifier on a bound, currently this is only used for `?Sized`, where the /// A modifier on a bound, currently this is only used for `?Sized`, where the

View File

@ -527,6 +527,9 @@ impl Resolver {
_ => None, _ => None,
}), }),
LifetimeRef::Placeholder | LifetimeRef::Error => None, LifetimeRef::Placeholder | LifetimeRef::Error => None,
LifetimeRef::Param(lifetime_param_id) => {
Some(LifetimeNs::LifetimeParam(*lifetime_param_id))
}
} }
} }

View File

@ -23,7 +23,8 @@ use hir_def::{
nameres::DefMap, nameres::DefMap,
signatures::VariantFields, signatures::VariantFields,
type_ref::{ type_ref::{
ConstRef, LifetimeRef, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef, ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId,
UseArgRef,
}, },
visibility::Visibility, visibility::Visibility,
}; };
@ -2085,20 +2086,29 @@ impl<T: HirDisplayWithExpressionStore> HirDisplay for ExpressionStoreAdapter<'_,
T::hir_fmt(&self.0, f, self.1) T::hir_fmt(&self.0, f, self.1)
} }
} }
impl HirDisplayWithExpressionStore for LifetimeRef { impl HirDisplayWithExpressionStore for LifetimeRefId {
fn hir_fmt( fn hir_fmt(
&self, &self,
f: &mut HirFormatter<'_>, f: &mut HirFormatter<'_>,
_store: &ExpressionStore, store: &ExpressionStore,
) -> Result<(), HirDisplayError> { ) -> Result<(), HirDisplayError> {
match self { match &store[*self] {
LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db, f.edition())), LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db, f.edition())),
LifetimeRef::Static => write!(f, "'static"), LifetimeRef::Static => write!(f, "'static"),
LifetimeRef::Placeholder => write!(f, "'_"), LifetimeRef::Placeholder => write!(f, "'_"),
LifetimeRef::Error => write!(f, "'{{error}}"), LifetimeRef::Error => write!(f, "'{{error}}"),
&LifetimeRef::Param(lifetime_param_id) => {
let generic_params = f.db.generic_params(lifetime_param_id.parent);
write!(
f,
"{}",
generic_params[lifetime_param_id.local_id].name.display(f.db, f.edition())
)
} }
} }
} }
}
impl HirDisplayWithExpressionStore for TypeRefId { impl HirDisplayWithExpressionStore for TypeRefId {
fn hir_fmt( fn hir_fmt(
&self, &self,

View File

@ -43,7 +43,7 @@ use hir_def::{
layout::Integer, layout::Integer,
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
signatures::{ConstSignature, StaticSignature}, signatures::{ConstSignature, StaticSignature},
type_ref::{ConstRef, LifetimeRef, TypeRefId}, type_ref::{ConstRef, LifetimeRefId, TypeRefId},
}; };
use hir_expand::{mod_path::ModPath, name::Name}; use hir_expand::{mod_path::ModPath, name::Name};
use indexmap::IndexSet; use indexmap::IndexSet;
@ -1391,7 +1391,7 @@ impl<'a> InferenceContext<'a> {
self.result.standard_types.unknown.clone() self.result.standard_types.unknown.clone()
} }
fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime { fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime {
let lt = self.with_ty_lowering( let lt = self.with_ty_lowering(
self.body, self.body,
InferenceTyDiagnosticSource::Body, InferenceTyDiagnosticSource::Body,

View File

@ -2099,7 +2099,7 @@ impl InferenceContext<'_> {
) -> crate::GenericArg { ) -> crate::GenericArg {
match (param, arg) { match (param, arg) {
(GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => { (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
self.ctx.make_body_lifetime(lifetime).cast(Interner) self.ctx.make_body_lifetime(*lifetime).cast(Interner)
} }
(GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => { (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
self.ctx.make_body_ty(*type_ref).cast(Interner) self.ctx.make_body_ty(*type_ref).cast(Interner)

View File

@ -35,7 +35,7 @@ use hir_def::{
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs}, resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
type_ref::{ type_ref::{
ConstRef, LifetimeRef, LiteralConstRef, PathId, TraitBoundModifier, ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
}, },
}; };
@ -370,7 +370,7 @@ impl<'a> TyLoweringContext<'a> {
let lifetime = ref_ let lifetime = ref_
.lifetime .lifetime
.as_ref() .as_ref()
.map_or_else(error_lifetime, |lr| self.lower_lifetime(lr)); .map_or_else(error_lifetime, |&lr| self.lower_lifetime(lr));
TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty) TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
.intern(Interner) .intern(Interner)
} }
@ -561,7 +561,7 @@ impl<'a> TyLoweringContext<'a> {
let self_ty = self.lower_ty(*target); let self_ty = self.lower_ty(*target);
Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings)) Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings))
} }
WherePredicate::Lifetime { bound, target } => Either::Right(iter::once( &WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives { crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
a: self.lower_lifetime(bound), a: self.lower_lifetime(bound),
b: self.lower_lifetime(target), b: self.lower_lifetime(target),
@ -604,7 +604,7 @@ impl<'a> TyLoweringContext<'a> {
self.unsized_types.insert(self_ty); self.unsized_types.insert(self_ty);
} }
} }
TypeBound::Lifetime(l) => { &TypeBound::Lifetime(l) => {
let lifetime = self.lower_lifetime(l); let lifetime = self.lower_lifetime(l);
clause = Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives { clause = Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives {
ty: self_ty, ty: self_ty,
@ -755,8 +755,8 @@ impl<'a> TyLoweringContext<'a> {
ImplTrait { bounds: crate::make_single_type_binders(predicates) } ImplTrait { bounds: crate::make_single_type_binders(predicates) }
} }
pub fn lower_lifetime(&self, lifetime: &LifetimeRef) -> Lifetime { pub fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Lifetime {
match self.resolver.resolve_lifetime(lifetime) { match self.resolver.resolve_lifetime(&self.store[lifetime]) {
Some(resolution) => match resolution { Some(resolution) => match resolution {
LifetimeNs::Static => static_lifetime(), LifetimeNs::Static => static_lifetime(),
LifetimeNs::LifetimeParam(id) => match self.type_param_mode { LifetimeNs::LifetimeParam(id) => match self.type_param_mode {

View File

@ -702,7 +702,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
) -> crate::GenericArg { ) -> crate::GenericArg {
match (param, arg) { match (param, arg) {
(GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => { (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
self.ctx.ctx.lower_lifetime(lifetime).cast(Interner) self.ctx.ctx.lower_lifetime(*lifetime).cast(Interner)
} }
(GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => { (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
self.ctx.ctx.lower_ty(*type_ref).cast(Interner) self.ctx.ctx.lower_ty(*type_ref).cast(Interner)