From 59b3a79eba6e8c1fc8373b4233444600068fd0aa Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Wed, 26 Jun 2024 21:57:44 +0200 Subject: [PATCH] [WIP][ty] Update salsa --- crates/hir-analysis/src/lib.rs | 22 +- crates/hir-analysis/src/ty/adt_def.rs | 99 ++-- crates/hir-analysis/src/ty/binder.rs | 18 +- crates/hir-analysis/src/ty/canonical.rs | 57 +- crates/hir-analysis/src/ty/const_ty.rs | 60 ++- crates/hir-analysis/src/ty/def_analysis.rs | 186 +++---- crates/hir-analysis/src/ty/diagnostics.rs | 502 +++++++++--------- crates/hir-analysis/src/ty/fold.rs | 12 +- crates/hir-analysis/src/ty/func_def.rs | 58 +- crates/hir-analysis/src/ty/method_cmp.rs | 64 +-- crates/hir-analysis/src/ty/method_table.rs | 61 ++- crates/hir-analysis/src/ty/trait_def.rs | 107 ++-- crates/hir-analysis/src/ty/trait_lower.rs | 63 +-- .../src/ty/trait_resolution/mod.rs | 56 +- .../src/ty/trait_resolution/proof_forest.rs | 24 +- crates/hir-analysis/src/ty/ty_check/env.rs | 17 +- crates/hir-analysis/src/ty/ty_check/expr.rs | 16 +- crates/hir-analysis/src/ty/ty_def.rs | 202 +++---- crates/hir-analysis/src/ty/ty_lower.rs | 187 ++++--- crates/hir-analysis/src/ty/unify.rs | 84 +-- crates/hir-analysis/src/ty/visitor.rs | 36 +- crates/hir/src/hir_def/item.rs | 1 + crates/hir/src/hir_def/scope_graph.rs | 4 +- 23 files changed, 1013 insertions(+), 923 deletions(-) diff --git a/crates/hir-analysis/src/lib.rs b/crates/hir-analysis/src/lib.rs index ca66ede92..e24e95584 100644 --- a/crates/hir-analysis/src/lib.rs +++ b/crates/hir-analysis/src/lib.rs @@ -10,27 +10,27 @@ pub struct Jar( name_resolution::traits_in_scope::available_traits_in_scope_impl, name_resolution::traits_in_scope::TraitScope<'_>, // Type system. - ty::ty_def::TyId, + ty::ty_def::TyId<'_>, ty::ty_def::ty_kind, ty::ty_def::pretty_print_ty, ty::ty_def::decompose_ty_app, ty::ty_def::ty_flags, // Adt types. - ty::adt_def::AdtDef, - ty::adt_def::AdtRefId, + ty::adt_def::AdtDef<'_>, + ty::adt_def::AdtRefId<'_>, ty::adt_def::lower_adt, // Func type. - ty::func_def::FuncDef, + ty::func_def::FuncDef<'_>, ty::func_def::lower_func, // Const types. - ty::const_ty::ConstTyId, + ty::const_ty::ConstTyId<'_>, ty::const_ty::evaluate_const_ty, // Type lowering. ty::ty_lower::lower_hir_ty, ty::ty_lower::lower_type_alias, ty::ty_lower::collect_generic_params, - ty::ty_lower::GenericParamOwnerId, - ty::ty_lower::GenericParamTypeSet, + ty::ty_lower::GenericParamOwnerId<'_>, + ty::ty_lower::GenericParamTypeSet<'_>, ty::ty_lower::evaluate_params_precursor, // Trait lowering. ty::trait_lower::lower_trait, @@ -50,9 +50,9 @@ pub struct Jar( ty::def_analysis::analyze_impl_trait, ty::def_analysis::analyze_func, // Trait system. - ty::trait_def::TraitDef, - ty::trait_def::TraitInstId, - ty::trait_def::Implementor, + ty::trait_def::TraitDef<'_>, + ty::trait_def::TraitInstId<'_>, + ty::trait_def::Implementor<'_>, ty::trait_def::ingot_trait_env, ty::trait_def::impls_for_trait, ty::trait_def::impls_for_ty, @@ -65,7 +65,7 @@ pub struct Jar( ty::trait_resolution::constraint::collect_func_def_constraints, ty::trait_resolution::constraint::collect_func_def_constraints_impl, ty::trait_resolution::constraint::ty_constraints, - ty::trait_resolution::PredicateListId, + ty::trait_resolution::PredicateListId<'_>, ty::trait_resolution::is_goal_satisfiable, ty::trait_resolution::check_ty_wf, ty::trait_resolution::check_trait_inst_wf, diff --git a/crates/hir-analysis/src/ty/adt_def.rs b/crates/hir-analysis/src/ty/adt_def.rs index df4b5fdd1..3bcd22226 100644 --- a/crates/hir-analysis/src/ty/adt_def.rs +++ b/crates/hir-analysis/src/ty/adt_def.rs @@ -15,35 +15,35 @@ use crate::HirAnalysisDb; /// Lower HIR ADT definition(`struct/enum/contract`) to [`AdtDef`]. #[salsa::tracked] -pub fn lower_adt(db: &dyn HirAnalysisDb, adt: AdtRefId) -> AdtDef { +pub fn lower_adt<'db>(db: &'db dyn HirAnalysisDb, adt: AdtRefId<'db>) -> AdtDef<'db> { AdtTyBuilder::new(db, adt).build() } /// Represents a ADT type definition. #[salsa::tracked] -pub struct AdtDef { - pub adt_ref: AdtRefId, +pub struct AdtDef<'db> { + pub adt_ref: AdtRefId<'db>, /// Type parameters of the ADT. #[return_ref] - pub param_set: GenericParamTypeSet, + pub param_set: GenericParamTypeSet<'db>, /// Fields of the ADT, if the ADT is an enum, this represents variants. /// Otherwise, `fields[0]` represents all fields of the struct. #[return_ref] - pub fields: Vec, + pub fields: Vec>, } -impl AdtDef { - pub(crate) fn name(self, db: &dyn HirAnalysisDb) -> IdentId { +impl<'db> AdtDef<'db> { + pub(crate) fn name(self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> { self.adt_ref(db).name(db) } - pub(crate) fn params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub(crate) fn params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.param_set(db).params(db) } - pub(crate) fn original_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub(crate) fn original_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId] { self.param_set(db).explicit_params(db) } @@ -51,16 +51,16 @@ impl AdtDef { matches!(self.adt_ref(db).data(db), AdtRef::Struct(_)) } - pub fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId { + pub fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> { self.adt_ref(db).scope(db) } pub(crate) fn variant_ty_span( self, - db: &dyn HirAnalysisDb, + db: &'db dyn HirAnalysisDb, field_idx: usize, ty_idx: usize, - ) -> DynLazySpan { + ) -> DynLazySpan<'db> { match self.adt_ref(db).data(db) { AdtRef::Enum(e) => { let span = e.lazy_span().variants_moved().variant_moved(field_idx); @@ -89,7 +89,7 @@ impl AdtDef { } } - pub(crate) fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { + pub(crate) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> { let hir_db = db.as_hir_db(); match self.adt_ref(db).data(db) { AdtRef::Enum(e) => e.top_mod(hir_db).ingot(hir_db), @@ -100,28 +100,28 @@ impl AdtDef { pub(crate) fn as_generic_param_owner( self, - db: &dyn HirAnalysisDb, - ) -> Option { + db: &'db dyn HirAnalysisDb, + ) -> Option> { self.adt_ref(db).generic_owner_id(db) } } /// This struct represents a field of an ADT. If the ADT is an enum, this /// represents a variant. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AdtField { +#[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)] +pub struct AdtField<'db> { /// Fields of the variant. /// If the adt is an struct or contract, /// the length of the vector is always 1. /// /// To allow recursive types, the type of the field is represented as a HIR /// type and. - tys: Vec>, + tys: Vec>>, - scope: ScopeId, + scope: ScopeId<'db>, } -impl AdtField { - pub fn ty(&self, db: &dyn HirAnalysisDb, i: usize) -> Binder { +impl<'db> AdtField<'db> { + pub fn ty(&self, db: &'db dyn HirAnalysisDb, i: usize) -> Binder> { let ty = if let Some(ty) = self.tys[i].to_opt() { lower_hir_ty(db, ty, self.scope) } else { @@ -134,8 +134,8 @@ impl AdtField { /// Iterates all fields types of the `field`. pub fn iter_types<'a>( &'a self, - db: &'a dyn HirAnalysisDb, - ) -> impl Iterator> + 'a { + db: &'db dyn HirAnalysisDb, + ) -> impl Iterator>> + 'a { (0..self.num_types()).map(|i| self.ty(db, i)) } @@ -143,22 +143,22 @@ impl AdtField { self.tys.len() } - pub(super) fn new(tys: Vec>, scope: ScopeId) -> Self { + pub(super) fn new(tys: Vec>>, scope: ScopeId<'db>) -> Self { Self { tys, scope } } } #[salsa::interned] -pub struct AdtRefId { - pub data: AdtRef, +pub struct AdtRefId<'db> { + pub data: AdtRef<'db>, } -impl AdtRefId { - pub fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId { +impl<'db> AdtRefId<'db> { + pub fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> { self.data(db).scope() } - pub fn as_item(self, db: &dyn HirAnalysisDb) -> ItemKind { + pub fn as_item(self, db: &'db dyn HirAnalysisDb) -> ItemKind<'db> { match self.data(db) { AdtRef::Enum(e) => e.into(), AdtRef::Struct(s) => s.into(), @@ -166,7 +166,7 @@ impl AdtRefId { } } - pub fn name(self, db: &dyn HirAnalysisDb) -> IdentId { + pub fn name(self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> { let hir_db = db.as_hir_db(); match self.data(db) { AdtRef::Enum(e) => e.name(hir_db), @@ -181,25 +181,28 @@ impl AdtRefId { self.as_item(db).kind_name() } - pub fn name_span(self, db: &dyn HirAnalysisDb) -> DynLazySpan { + pub fn name_span(self, db: &'db dyn HirAnalysisDb) -> DynLazySpan<'db> { self.scope(db) .name_span(db.as_hir_db()) .unwrap_or_else(DynLazySpan::invalid) } - pub fn from_enum(db: &dyn HirAnalysisDb, enum_: Enum) -> Self { + pub fn from_enum(db: &'db dyn HirAnalysisDb, enum_: Enum<'db>) -> Self { Self::new(db, AdtRef::Enum(enum_)) } - pub fn from_struct(db: &dyn HirAnalysisDb, struct_: Struct) -> Self { + pub fn from_struct(db: &'db dyn HirAnalysisDb, struct_: Struct<'db>) -> Self { Self::new(db, AdtRef::Struct(struct_)) } - pub fn from_contract(db: &dyn HirAnalysisDb, contract: Contract) -> Self { + pub fn from_contract(db: &'db dyn HirAnalysisDb, contract: Contract<'db>) -> Self { Self::new(db, AdtRef::Contract(contract)) } - pub(crate) fn generic_owner_id(self, db: &dyn HirAnalysisDb) -> Option { + pub(crate) fn generic_owner_id( + self, + db: &'db dyn HirAnalysisDb, + ) -> Option { match self.data(db) { AdtRef::Enum(e) => Some(GenericParamOwnerId::new(db, e.into())), AdtRef::Struct(s) => Some(GenericParamOwnerId::new(db, s.into())), @@ -209,14 +212,14 @@ impl AdtRefId { } #[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::From)] -pub enum AdtRef { - Enum(Enum), - Struct(Struct), - Contract(Contract), +pub enum AdtRef<'db> { + Enum(Enum<'db>), + Struct(Struct<'db>), + Contract(Contract<'db>), } -impl AdtRef { - pub fn scope(self) -> ScopeId { +impl<'db> AdtRef<'db> { + pub fn scope(self) -> ScopeId<'db> { match self { Self::Enum(e) => e.scope(), Self::Struct(s) => s.scope(), @@ -227,13 +230,13 @@ impl AdtRef { struct AdtTyBuilder<'db> { db: &'db dyn HirAnalysisDb, - adt: AdtRefId, - params: GenericParamTypeSet, - variants: Vec, + adt: AdtRefId<'db>, + params: GenericParamTypeSet<'db>, + variants: Vec>, } impl<'db> AdtTyBuilder<'db> { - fn new(db: &'db dyn HirAnalysisDb, adt: AdtRefId) -> Self { + fn new(db: &'db dyn HirAnalysisDb, adt: AdtRefId<'db>) -> Self { Self { db, adt, @@ -242,7 +245,7 @@ impl<'db> AdtTyBuilder<'db> { } } - fn build(mut self) -> AdtDef { + fn build(mut self) -> AdtDef<'db> { self.collect_generic_params(); self.collect_variants(); AdtDef::new(self.db, self.adt, self.params, self.variants) @@ -275,7 +278,7 @@ impl<'db> AdtTyBuilder<'db> { }; } - fn collect_field_types(&mut self, fields: FieldDefListId) { + fn collect_field_types(&mut self, fields: FieldDefListId<'db>) { let scope = self.adt.scope(self.db); let fields = fields @@ -287,7 +290,7 @@ impl<'db> AdtTyBuilder<'db> { self.variants.push(AdtField::new(fields, scope)); } - fn collect_enum_variant_types(&mut self, variants: VariantDefListId) { + fn collect_enum_variant_types(&mut self, variants: VariantDefListId<'db>) { let scope = self.adt.scope(self.db); variants diff --git a/crates/hir-analysis/src/ty/binder.rs b/crates/hir-analysis/src/ty/binder.rs index bcc3c6b25..e1f533b39 100644 --- a/crates/hir-analysis/src/ty/binder.rs +++ b/crates/hir-analysis/src/ty/binder.rs @@ -14,7 +14,7 @@ use crate::HirAnalysisDb; /// /// # Type Parameters /// - `T`: The type being bound within the `Binder`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update)] pub struct Binder { value: T, } @@ -65,7 +65,7 @@ where /// # Returns /// A new instance of the type contained within the binder with the /// arguments applied. - pub fn instantiate(self, db: &'db dyn HirAnalysisDb, args: &[TyId]) -> T { + pub fn instantiate(self, db: &'db dyn HirAnalysisDb, args: &[TyId<'db>]) -> T { let mut folder = InstantiateFolder { db, args }; self.value.fold_with(&mut folder) } @@ -85,7 +85,7 @@ where /// function applied. pub fn instantiate_with(self, db: &'db dyn HirAnalysisDb, f: F) -> T where - F: FnMut(TyId) -> TyId, + F: FnMut(TyId<'db>) -> TyId<'db>, { let mut folder = InstantiateWithFolder { db, @@ -98,7 +98,7 @@ where struct InstantiateFolder<'db, 'a> { db: &'db dyn HirAnalysisDb, - args: &'a [TyId], + args: &'a [TyId<'db>], } impl<'db, 'a> TyFolder<'db> for InstantiateFolder<'db, 'a> { @@ -106,7 +106,7 @@ impl<'db, 'a> TyFolder<'db> for InstantiateFolder<'db, 'a> { self.db } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { match ty.data(self.db) { TyData::TyParam(param) => return self.args[param.idx], TyData::ConstTy(const_ty) => { @@ -124,22 +124,22 @@ impl<'db, 'a> TyFolder<'db> for InstantiateFolder<'db, 'a> { struct InstantiateWithFolder<'db, F> where - F: FnMut(TyId) -> TyId, + F: FnMut(TyId<'db>) -> TyId<'db>, { db: &'db dyn HirAnalysisDb, f: F, - params: FxHashMap, + params: FxHashMap>, } impl<'db, F> TyFolder<'db> for InstantiateWithFolder<'db, F> where - F: FnMut(TyId) -> TyId, + F: FnMut(TyId<'db>) -> TyId<'db>, { fn db(&self) -> &'db dyn HirAnalysisDb { self.db } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { match ty.data(self.db) { TyData::TyParam(param) => { match self.params.entry(param.idx) { diff --git a/crates/hir-analysis/src/ty/canonical.rs b/crates/hir-analysis/src/ty/canonical.rs index 754d91b3b..c7f7050a5 100644 --- a/crates/hir-analysis/src/ty/canonical.rs +++ b/crates/hir-analysis/src/ty/canonical.rs @@ -13,11 +13,11 @@ pub struct Canonical { pub value: T, } -impl Canonical +impl<'db, T> Canonical where - T: for<'db> TyFoldable<'db>, + T: TyFoldable<'db>, { - pub fn new(db: &dyn HirAnalysisDb, value: T) -> Self { + pub fn new(db: &'db dyn HirAnalysisDb, value: T) -> Self { let mut c = Canonicalizer::new(db); let value = value.fold_with(&mut c); Canonical { value } @@ -37,9 +37,9 @@ where /// /// # Panics /// This function will panic if the `table` is not empty. - pub(super) fn extract_identity(self, table: &mut UnificationTableBase) -> T + pub(super) fn extract_identity(self, table: &mut UnificationTableBase<'db, S>) -> T where - S: UnificationStore, + S: UnificationStore<'db>, { assert!(table.is_empty()); @@ -67,14 +67,14 @@ where /// canonicalized to the context of the canonical query. pub(super) fn canonicalize_solution( &self, - db: &dyn HirAnalysisDb, - table: &mut UnificationTableBase, + db: &'db dyn HirAnalysisDb, + table: &'db mut UnificationTableBase, solution: U, ) -> Solution where T: Copy, - S: UnificationStore, - U: for<'db> TyFoldable<'db> + Clone, + S: UnificationStore<'db>, + U: TyFoldable<'db> + Clone, { let solution = solution.fold_with(table); @@ -106,17 +106,17 @@ where /// This type contains [`Canonical`] type and auxiliary information to map back /// [`Solution`] that corresponds to [`Canonical`] query. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Canonicalized { +pub struct Canonicalized<'db, T> { pub value: Canonical, // A substitution from canonical type variables to original type variables. - subst: FxHashMap, + subst: FxHashMap, TyId<'db>>, } -impl Canonicalized +impl<'db, T> Canonicalized<'db, T> where - T: for<'db> TyFoldable<'db>, + T: TyFoldable<'db>, { - pub fn new(db: &dyn HirAnalysisDb, value: T) -> Self { + pub fn new(db: &'db dyn HirAnalysisDb, value: T) -> Self { let mut canonicalizer = Canonicalizer::new(db); let value = value.fold_with(&mut canonicalizer); let map = canonicalizer @@ -143,12 +143,12 @@ where /// The extracted solution in the context of the original query environment. pub fn extract_solution( &self, - table: &mut UnificationTableBase, + table: &mut UnificationTableBase<'db, S>, solution: Solution, ) -> U where - U: for<'db> TyFoldable<'db>, - S: UnificationStore, + U: TyFoldable<'db>, + S: UnificationStore<'db>, { let map = self.subst.clone(); let mut extractor = SolutionExtractor::new(table, map); @@ -176,7 +176,7 @@ pub struct Solution { struct Canonicalizer<'db> { db: &'db dyn HirAnalysisDb, // A substitution from original type variables to canonical variables. - subst: FxHashMap, + subst: FxHashMap, TyId<'db>>, } impl<'db> Canonicalizer<'db> { @@ -187,12 +187,12 @@ impl<'db> Canonicalizer<'db> { } } - fn canonical_var(&mut self, var: &TyVar) -> TyVar { + fn canonical_var(&mut self, var: &TyVar<'db>) -> TyVar<'db> { let key = self.subst.len() as u32; TyVar { sort: var.sort, kind: var.kind.clone(), - key: InferenceKey(key), + key: InferenceKey(key, Default::default()), } } } @@ -202,7 +202,7 @@ impl<'db> TyFolder<'db> for Canonicalizer<'db> { self.db } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { if let Some(&canonical) = self.subst.get(&ty) { return canonical; } @@ -237,32 +237,35 @@ impl<'db> TyFolder<'db> for Canonicalizer<'db> { struct SolutionExtractor<'a, 'db, S> where - S: UnificationStore, + S: UnificationStore<'db>, { table: &'a mut UnificationTableBase<'db, S>, /// A subst from canonical type variables to the variables in the current /// env. - subst: FxHashMap, + subst: FxHashMap, TyId<'db>>, } impl<'a, 'db, S> SolutionExtractor<'a, 'db, S> where - S: UnificationStore, + S: UnificationStore<'db>, { - fn new(table: &'a mut UnificationTableBase<'db, S>, subst: FxHashMap) -> Self { + fn new( + table: &'a mut UnificationTableBase<'db, S>, + subst: FxHashMap, TyId<'db>>, + ) -> Self { SolutionExtractor { table, subst } } } impl<'a, 'db, S> TyFolder<'db> for SolutionExtractor<'a, 'db, S> where - S: UnificationStore, + S: UnificationStore<'db>, { fn db(&self) -> &'db dyn HirAnalysisDb { self.table.db() } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { if let Some(&ty) = self.subst.get(&ty) { return ty; } diff --git a/crates/hir-analysis/src/ty/const_ty.rs b/crates/hir-analysis/src/ty/const_ty.rs index 4b2feb635..d07fcc33a 100644 --- a/crates/hir-analysis/src/ty/const_ty.rs +++ b/crates/hir-analysis/src/ty/const_ty.rs @@ -10,17 +10,17 @@ use crate::{ }; #[salsa::interned] -pub struct ConstTyId { +pub struct ConstTyId<'db> { #[return_ref] - pub(super) data: ConstTyData, + pub(super) data: ConstTyData<'db>, } #[salsa::tracked] -pub(crate) fn evaluate_const_ty( - db: &dyn HirAnalysisDb, - const_ty: ConstTyId, - expected_ty: Option, -) -> ConstTyId { +pub(crate) fn evaluate_const_ty<'db>( + db: &'db dyn HirAnalysisDb, + const_ty: ConstTyId<'db>, + expected_ty: Option>, +) -> ConstTyId<'db> { let ConstTyData::UnEvaluated(body) = const_ty.data(db) else { let const_ty_ty = const_ty.ty(db); return match check_const_ty(db, const_ty_ty, expected_ty, &mut UnificationTable::new(db)) { @@ -73,12 +73,12 @@ pub(crate) fn evaluate_const_ty( // FIXME: When we add type inference, we need to use the inference engine to // check the type of the expression instead of this function. -fn check_const_ty( - db: &dyn HirAnalysisDb, - const_ty_ty: TyId, - expected_ty: Option, - table: &mut UnificationTable, -) -> Result { +fn check_const_ty<'db>( + db: &'db dyn HirAnalysisDb, + const_ty_ty: TyId<'db>, + expected_ty: Option>, + table: &mut UnificationTable<'db>, +) -> Result, InvalidCause<'db>> { if const_ty_ty.has_invalid(db) { return Err(InvalidCause::Other); } @@ -98,8 +98,8 @@ fn check_const_ty( } } -impl ConstTyId { - pub fn ty(self, db: &dyn HirAnalysisDb) -> TyId { +impl<'db> ConstTyId<'db> { + pub fn ty(self, db: &'db dyn HirAnalysisDb) -> TyId<'db> { match self.data(db) { ConstTyData::TyVar(_, ty) => *ty, ConstTyData::TyParam(_, ty) => *ty, @@ -119,30 +119,34 @@ impl ConstTyId { } } - pub(super) fn evaluate(self, db: &dyn HirAnalysisDb, expected_ty: Option) -> Self { + pub(super) fn evaluate( + self, + db: &'db dyn HirAnalysisDb, + expected_ty: Option>, + ) -> Self { evaluate_const_ty(db, self, expected_ty) } - pub(super) fn from_body(db: &dyn HirAnalysisDb, body: Body) -> Self { + pub(super) fn from_body(db: &'db dyn HirAnalysisDb, body: Body<'db>) -> Self { let data = ConstTyData::UnEvaluated(body); Self::new(db, data) } - pub(super) fn from_opt_body(db: &dyn HirAnalysisDb, body: Partial) -> Self { + pub(super) fn from_opt_body(db: &'db dyn HirAnalysisDb, body: Partial>) -> Self { match body { Partial::Present(body) => Self::from_body(db, body), Partial::Absent => Self::invalid(db, InvalidCause::Other), } } - pub(super) fn invalid(db: &dyn HirAnalysisDb, cause: InvalidCause) -> Self { + pub(super) fn invalid(db: &'db dyn HirAnalysisDb, cause: InvalidCause<'db>) -> Self { let resolved = EvaluatedConstTy::Invalid; let ty = TyId::invalid(db, cause); let data = ConstTyData::Evaluated(resolved, ty); Self::new(db, data) } - fn swap_ty(self, db: &dyn HirAnalysisDb, ty: TyId) -> Self { + fn swap_ty(self, db: &'db dyn HirAnalysisDb, ty: TyId<'db>) -> Self { let data = match self.data(db) { ConstTyData::TyVar(var, _) => ConstTyData::TyVar(var.clone(), ty), ConstTyData::TyParam(param, _) => ConstTyData::TyParam(param.clone(), ty), @@ -157,21 +161,21 @@ impl ConstTyId { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ConstTyData { - TyVar(TyVar, TyId), - TyParam(TyParam, TyId), - Evaluated(EvaluatedConstTy, TyId), - UnEvaluated(Body), +pub enum ConstTyData<'db> { + TyVar(TyVar, TyId<'db>), + TyParam(TyParam<'db>, TyId<'db>), + Evaluated(EvaluatedConstTy<'db>, TyId<'db>), + UnEvaluated(Body<'db>), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum EvaluatedConstTy { - LitInt(IntegerId), +pub enum EvaluatedConstTy<'db> { + LitInt(IntegerId<'db>), LitBool(bool), Invalid, } -impl EvaluatedConstTy { +impl<'db> EvaluatedConstTy<'db> { pub fn pretty_print(&self, db: &dyn HirAnalysisDb) -> String { match self { EvaluatedConstTy::LitInt(val) => { diff --git a/crates/hir-analysis/src/ty/def_analysis.rs b/crates/hir-analysis/src/ty/def_analysis.rs index 64d14d57d..1249eb59a 100644 --- a/crates/hir-analysis/src/ty/def_analysis.rs +++ b/crates/hir-analysis/src/ty/def_analysis.rs @@ -69,7 +69,7 @@ use crate::{ /// - Check if the trait instantiations in the ADT satisfies the constraints. /// - Check if the recursive types has indirect type wrapper like pointer. #[salsa::tracked] -pub fn analyze_adt(db: &dyn HirAnalysisDb, adt_ref: AdtRefId) { +pub fn analyze_adt<'db>(db: &'db dyn HirAnalysisDb, adt_ref: AdtRefId<'db>) { let analyzer = DefAnalyzer::for_adt(db, adt_ref); let diags = analyzer.analyze(); @@ -90,7 +90,7 @@ pub fn analyze_adt(db: &dyn HirAnalysisDb, adt_ref: AdtRefId) { /// in type application. /// - Check if the trait instantiations in the trait satisfies the constraints. #[salsa::tracked] -pub fn analyze_trait(db: &dyn HirAnalysisDb, trait_: Trait) { +pub fn analyze_trait<'db>(db: &'db dyn HirAnalysisDb, trait_: Trait<'db>) { let analyzer = DefAnalyzer::for_trait(db, trait_); let diags = analyzer.analyze(); @@ -111,7 +111,7 @@ pub fn analyze_trait(db: &dyn HirAnalysisDb, trait_: Trait) { /// - Check if the trait or type is included in the ingot which contains the /// impl trait. #[salsa::tracked] -pub fn analyze_impl_trait(db: &dyn HirAnalysisDb, impl_trait: ImplTrait) { +pub fn analyze_impl_trait<'db>(db: &'db dyn HirAnalysisDb, impl_trait: ImplTrait<'db>) { let implementor = match analyze_impl_trait_specific_error(db, impl_trait) { Ok(implementor) => implementor, Err(diags) => { @@ -133,7 +133,7 @@ pub fn analyze_impl_trait(db: &dyn HirAnalysisDb, impl_trait: ImplTrait) { } #[salsa::tracked] -pub fn analyze_impl(db: &dyn HirAnalysisDb, impl_: HirImpl) { +pub fn analyze_impl<'db>(db: &'db dyn HirAnalysisDb, impl_: HirImpl<'db>) { let Some(hir_ty) = impl_.ty(db.as_hir_db()).to_opt() else { return; }; @@ -148,7 +148,7 @@ pub fn analyze_impl(db: &dyn HirAnalysisDb, impl_: HirImpl) { } #[salsa::tracked] -pub fn analyze_func(db: &dyn HirAnalysisDb, func: Func) { +pub fn analyze_func<'db>(db: &'db dyn HirAnalysisDb, func: Func<'db>) { let Some(func_def) = lower_func(db, func) else { return; }; @@ -170,7 +170,7 @@ pub fn analyze_func(db: &dyn HirAnalysisDb, func: Func) { /// included in the type system. Satisfiability is checked where the type alias /// is used. #[salsa::tracked] -pub fn analyze_type_alias(db: &dyn HirAnalysisDb, alias: TypeAlias) { +pub fn analyze_type_alias<'db>(db: &'db dyn HirAnalysisDb, alias: TypeAlias<'db>) { let Some(hir_ty) = alias.ty(db.as_hir_db()).to_opt() else { return; }; @@ -200,15 +200,15 @@ pub fn analyze_type_alias(db: &dyn HirAnalysisDb, alias: TypeAlias) { pub struct DefAnalyzer<'db> { db: &'db dyn HirAnalysisDb, - def: DefKind, - self_ty: Option, - diags: Vec, - assumptions: PredicateListId, - current_ty: Option<(TyId, DynLazySpan)>, + def: DefKind<'db>, + self_ty: Option>, + diags: Vec>, + assumptions: PredicateListId<'db>, + current_ty: Option<(TyId<'db>, DynLazySpan<'db>)>, } impl<'db> DefAnalyzer<'db> { - fn for_adt(db: &'db dyn HirAnalysisDb, adt: AdtRefId) -> Self { + fn for_adt(db: &'db dyn HirAnalysisDb, adt: AdtRefId<'db>) -> Self { let def = lower_adt(db, adt); let assumptions = collect_adt_constraints(db, def).instantiate_identity(); Self { @@ -221,7 +221,7 @@ impl<'db> DefAnalyzer<'db> { } } - fn for_trait(db: &'db dyn HirAnalysisDb, trait_: Trait) -> Self { + fn for_trait(db: &'db dyn HirAnalysisDb, trait_: Trait<'db>) -> Self { let def = lower_trait(db, trait_); let assumptions = collect_trait_constraints(db, def).instantiate_identity(); Self { @@ -234,7 +234,7 @@ impl<'db> DefAnalyzer<'db> { } } - fn for_impl(db: &'db dyn HirAnalysisDb, impl_: HirImpl, ty: TyId) -> Self { + fn for_impl(db: &'db dyn HirAnalysisDb, impl_: HirImpl<'db>, ty: TyId<'db>) -> Self { let assumptions = collect_impl_block_constraints(db, impl_).instantiate_identity(); let def = DefKind::Impl(impl_); Self { @@ -247,7 +247,7 @@ impl<'db> DefAnalyzer<'db> { } } - fn for_trait_impl(db: &'db dyn HirAnalysisDb, implementor: Implementor) -> Self { + fn for_trait_impl(db: &'db dyn HirAnalysisDb, implementor: Implementor<'db>) -> Self { let assumptions = implementor.constraints(db); Self { db, @@ -259,7 +259,7 @@ impl<'db> DefAnalyzer<'db> { } } - fn for_func(db: &'db dyn HirAnalysisDb, func: FuncDef) -> Self { + fn for_func(db: &'db dyn HirAnalysisDb, func: FuncDef<'db>) -> Self { let hir_db = db.as_hir_db(); let assumptions = collect_func_def_constraints(db, func, true).instantiate_identity(); let self_ty = match func @@ -298,7 +298,7 @@ impl<'db> DefAnalyzer<'db> { /// 2. the given `ty` is not const type /// TODO: This method is a stop-gap implementation until we design a true /// const type system. - fn verify_term_type_kind(&mut self, ty: HirTyId, span: DynLazySpan) -> bool { + fn verify_term_type_kind(&mut self, ty: HirTyId<'db>, span: DynLazySpan<'db>) -> bool { let ty = lower_hir_ty(self.db, ty, self.scope()); if !ty.has_star_kind(self.db) { self.diags @@ -356,7 +356,7 @@ impl<'db> DefAnalyzer<'db> { !is_conflict } - fn verify_self_type(&mut self, self_ty: HirTyId, span: DynLazySpan) -> bool { + fn verify_self_type(&mut self, self_ty: HirTyId<'db>, span: DynLazySpan<'db>) -> bool { let Some(expected_ty) = self.self_ty else { return false; }; @@ -387,7 +387,7 @@ impl<'db> DefAnalyzer<'db> { true } - fn check_method_conflict(&mut self, func: FuncDef) -> bool { + fn check_method_conflict(&mut self, func: FuncDef<'db>) -> bool { let self_ty = func .receiver_ty(self.db) .map_or_else(|| self.self_ty.unwrap(), |ty| ty.instantiate_identity()); @@ -417,11 +417,11 @@ impl<'db> DefAnalyzer<'db> { true } - fn scope(&self) -> ScopeId { + fn scope(&self) -> ScopeId<'db> { self.def.scope(self.db) } - fn analyze(mut self) -> Vec { + fn analyze(mut self) -> Vec> { match self.def { DefKind::Adt(def) => match def.adt_ref(self.db).data(self.db) { AdtRef::Struct(struct_) => { @@ -468,12 +468,12 @@ impl<'db> DefAnalyzer<'db> { } } -impl<'db> Visitor for DefAnalyzer<'db> { +impl<'db> Visitor<'db> for DefAnalyzer<'db> { // We don't need to traverse the nested item, each item kinds are explicitly // handled(e.g, `visit_trait` or `visit_enum`). - fn visit_item(&mut self, _ctxt: &mut VisitorCtxt<'_, LazyItemSpan>, _item: ItemKind) {} + fn visit_item(&mut self, _ctxt: &mut VisitorCtxt<'db, LazyItemSpan>, _item: ItemKind<'db>) {} - fn visit_ty(&mut self, ctxt: &mut VisitorCtxt<'_, LazyTySpan>, hir_ty: HirTyId) { + fn visit_ty(&mut self, ctxt: &mut VisitorCtxt<'db, LazyTySpan<'db>>, hir_ty: HirTyId<'db>) { let ty = lower_hir_ty(self.db, hir_ty, self.scope()); let span = ctxt.span().unwrap(); if let Some(diag) = ty.emit_diag(self.db, span.clone().into()) { @@ -485,8 +485,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_where_predicate( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyWherePredicateSpan>, - pred: &hir::hir_def::WherePredicate, + ctxt: &mut VisitorCtxt<'db, LazyWherePredicateSpan<'db>>, + pred: &hir::hir_def::WherePredicate<'db>, ) { let Some(hir_ty) = pred.ty.to_opt() else { return; @@ -517,7 +517,11 @@ impl<'db> Visitor for DefAnalyzer<'db> { walk_where_predicate(self, ctxt, pred); } - fn visit_field_def(&mut self, ctxt: &mut VisitorCtxt<'_, LazyFieldDefSpan>, field: &FieldDef) { + fn visit_field_def( + &mut self, + ctxt: &mut VisitorCtxt<'db, LazyFieldDefSpan<'db>>, + field: &FieldDef<'db>, + ) { let Some(ty) = field.ty.to_opt() else { return; }; @@ -556,8 +560,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_variant_def( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyVariantDefSpan>, - variant: &hir::hir_def::VariantDef, + ctxt: &mut VisitorCtxt<'db, LazyVariantDefSpan<'db>>, + variant: &hir::hir_def::VariantDef<'db>, ) { if let VariantKind::Tuple(tuple_id) = variant.kind { let span = ctxt.span().unwrap().tuple_type_moved(); @@ -574,8 +578,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_generic_param( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyGenericParamSpan>, - param: &hir::hir_def::GenericParam, + ctxt: &mut VisitorCtxt<'db, LazyGenericParamSpan<'db>>, + param: &hir::hir_def::GenericParam<'db>, ) { let ScopeId::GenericParam(_, idx) = ctxt.scope() else { unreachable!() @@ -709,8 +713,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_super_trait_list( &mut self, - ctxt: &mut VisitorCtxt<'_, hir::span::item::LazySuperTraitListSpan>, - super_traits: &[TraitRefId], + ctxt: &mut VisitorCtxt<'db, hir::span::item::LazySuperTraitListSpan<'db>>, + super_traits: &[TraitRefId<'db>], ) { let DefKind::Trait(def) = self.def else { unreachable!() @@ -720,7 +724,7 @@ impl<'db> Visitor for DefAnalyzer<'db> { walk_super_trait_list(self, ctxt, super_traits); } - fn visit_impl(&mut self, ctxt: &mut VisitorCtxt<'_, LazyImplSpan>, impl_: HirImpl) { + fn visit_impl(&mut self, ctxt: &mut VisitorCtxt<'db, LazyImplSpan<'db>>, impl_: HirImpl<'db>) { let Some(impl_ty) = impl_.ty(self.db.as_hir_db()).to_opt() else { return; }; @@ -746,8 +750,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_func( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyFuncSpan>, - hir_func: hir::hir_def::Func, + ctxt: &mut VisitorCtxt<'db, LazyFuncSpan<'db>>, + hir_func: hir::hir_def::Func<'db>, ) { let Some(func) = lower_func(self.db, hir_func) else { return; @@ -792,8 +796,8 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_func_param_list( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyFuncParamListSpan>, - params: FuncParamListId, + ctxt: &mut VisitorCtxt<'db, LazyFuncParamListSpan<'db>>, + params: FuncParamListId<'db>, ) { // Checks if the argument names are not duplicated. let mut already_seen: FxHashMap = FxHashMap::default(); @@ -825,20 +829,20 @@ impl<'db> Visitor for DefAnalyzer<'db> { fn visit_func_param( &mut self, - ctxt: &mut VisitorCtxt<'_, LazyFuncParamSpan>, - param: &hir::hir_def::FuncParam, + ctxt: &mut VisitorCtxt<'db, LazyFuncParamSpan<'db>>, + param: &hir::hir_def::FuncParam<'db>, ) { let Some(hir_ty) = param.ty.to_opt() else { return; }; - let ty_span: DynLazySpan = if param.is_self_param() && param.self_ty_fallback { + let ty_span: DynLazySpan = if param.is_self_param(ctxt.db()) && param.self_ty_fallback { ctxt.span().unwrap().name().into() } else { ctxt.span().unwrap().ty().into() }; - if param.is_self_param() { + if param.is_self_param(ctxt.db()) { self.verify_self_type(hir_ty, ty_span.clone()); } @@ -851,10 +855,10 @@ impl<'db> Visitor for DefAnalyzer<'db> { } #[salsa::tracked(recovery_fn = check_recursive_adt_impl)] -pub(crate) fn check_recursive_adt( - db: &dyn HirAnalysisDb, - adt: AdtRefId, -) -> Option { +pub(crate) fn check_recursive_adt<'db>( + db: &'db dyn HirAnalysisDb, + adt: AdtRefId<'db>, +) -> Option> { let adt_def = lower_adt(db, adt); for field in adt_def.fields(db) { for ty in field.iter_types(db) { @@ -867,11 +871,11 @@ pub(crate) fn check_recursive_adt( None } -fn check_recursive_adt_impl( - db: &dyn HirAnalysisDb, +fn check_recursive_adt_impl<'db>( + db: &'db dyn HirAnalysisDb, cycle: &salsa::Cycle, - adt: AdtRefId, -) -> Option { + adt: AdtRefId<'db>, +) -> Option> { let participants: FxHashSet<_> = cycle .participant_keys() .map(|key| check_recursive_adt::key_from_id(key.key_index())) @@ -895,13 +899,13 @@ fn check_recursive_adt_impl( None } -impl TyId { +impl<'db> TyId<'db> { /// Collect all adts inside types which are not wrapped by indirect type /// wrapper like pointer or reference. - fn collect_direct_adts(self, db: &dyn HirAnalysisDb) -> FxHashSet { + fn collect_direct_adts(self, db: &'db dyn HirAnalysisDb) -> FxHashSet> { struct AdtCollector<'db> { db: &'db dyn HirAnalysisDb, - adts: FxHashSet, + adts: FxHashSet>, } impl<'db> TyVisitor<'db> for AdtCollector<'db> { @@ -909,13 +913,13 @@ impl TyId { self.db } - fn visit_app(&mut self, abs: TyId, arg: TyId) { + fn visit_app(&mut self, abs: TyId<'db>, arg: TyId<'db>) { if !abs.is_indirect(self.db) { walk_ty(self, arg) } } - fn visit_adt(&mut self, adt: AdtDef) { + fn visit_adt(&mut self, adt: AdtDef<'db>) { self.adts.insert(adt.adt_ref(self.db)); } } @@ -930,14 +934,14 @@ impl TyId { } } -fn analyze_trait_ref( - db: &dyn HirAnalysisDb, - self_ty: TyId, - trait_ref: TraitRefId, - scope: ScopeId, - assumptions: Option, - span: DynLazySpan, -) -> Option { +fn analyze_trait_ref<'db>( + db: &'db dyn HirAnalysisDb, + self_ty: TyId<'db>, + trait_ref: TraitRefId<'db>, + scope: ScopeId<'db>, + assumptions: Option>, + span: DynLazySpan<'db>, +) -> Option> { let trait_inst = match lower_trait_ref(db, self_ty, trait_ref, scope) { Ok(trait_ref) => trait_ref, @@ -982,16 +986,16 @@ fn analyze_trait_ref( } #[derive(Clone, Copy, Debug, derive_more::From)] -enum DefKind { - Adt(AdtDef), - Trait(TraitDef), - ImplTrait(Implementor), - Impl(HirImpl), - Func(FuncDef), +enum DefKind<'db> { + Adt(AdtDef<'db>), + Trait(TraitDef<'db>), + ImplTrait(Implementor<'db>), + Impl(HirImpl<'db>), + Func(FuncDef<'db>), } -impl DefKind { - fn original_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { +impl<'db> DefKind<'db> { + fn original_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { match self { Self::Adt(def) => def.original_params(db), Self::Trait(def) => def.original_params(db), @@ -1003,7 +1007,7 @@ impl DefKind { } } - fn trait_self_param(self, db: &dyn HirAnalysisDb) -> TyId { + fn trait_self_param(self, db: &'db dyn HirAnalysisDb) -> TyId<'db> { if let Self::Trait(def) = self { def.self_param(db) } else { @@ -1011,7 +1015,7 @@ impl DefKind { } } - fn collect_super_trait_cycle(self, db: &dyn HirAnalysisDb) -> Option<&SuperTraitCycle> { + fn collect_super_trait_cycle(self, db: &'db dyn HirAnalysisDb) -> Option<&SuperTraitCycle> { if let Self::Trait(def) = self { collect_super_traits(db, def).as_ref().err() } else { @@ -1019,7 +1023,7 @@ impl DefKind { } } - fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId { + fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> { match self { Self::Adt(def) => def.adt_ref(db).scope(db), Self::Trait(def) => def.trait_(db).scope(), @@ -1038,10 +1042,10 @@ impl DefKind { /// 4. If conflict occurs. /// 5. If implementor type satisfies the required kind bound. /// 6. If implementor type satisfies the required trait bound. -fn analyze_impl_trait_specific_error( - db: &dyn HirAnalysisDb, - impl_trait: ImplTrait, -) -> Result, Vec> { +fn analyze_impl_trait_specific_error<'db>( + db: &'db dyn HirAnalysisDb, + impl_trait: ImplTrait<'db>, +) -> Result>, Vec>> { let mut diags = vec![]; let hir_db = db.as_hir_db(); // We don't need to report error because it should be reported from the parser. @@ -1103,10 +1107,10 @@ fn analyze_impl_trait_specific_error( return Err(diags); }; - fn analyze_conflict_impl( - db: &dyn HirAnalysisDb, - implementor: Binder, - diags: &mut Vec, + fn analyze_conflict_impl<'db>( + db: &'db dyn HirAnalysisDb, + implementor: Binder>, + diags: &mut Vec>, ) { let trait_ = implementor.skip_binder().trait_(db); let env = ingot_trait_env(db, trait_.ingot(db)); @@ -1194,12 +1198,12 @@ fn analyze_impl_trait_specific_error( struct ImplTraitMethodAnalyzer<'db> { db: &'db dyn HirAnalysisDb, - diags: Vec, - implementor: Implementor, + diags: Vec>, + implementor: Implementor<'db>, } impl<'db> ImplTraitMethodAnalyzer<'db> { - fn new(db: &'db dyn HirAnalysisDb, implementor: Implementor) -> Self { + fn new(db: &'db dyn HirAnalysisDb, implementor: Implementor<'db>) -> Self { Self { db, diags: vec![], @@ -1207,7 +1211,7 @@ impl<'db> ImplTraitMethodAnalyzer<'db> { } } - fn analyze(mut self) -> Vec { + fn analyze(mut self) -> Vec> { let impl_methods = self.implementor.methods(self.db); let hir_trait = self.implementor.trait_def(self.db).trait_(self.db); let trait_methods = self.implementor.trait_def(self.db).methods(self.db); @@ -1268,11 +1272,11 @@ impl<'db> ImplTraitMethodAnalyzer<'db> { } } -fn find_const_ty_param( - db: &dyn HirAnalysisDb, - ident: IdentId, - scope: ScopeId, -) -> Option { +fn find_const_ty_param<'db>( + db: &'db dyn HirAnalysisDb, + ident: IdentId<'db>, + scope: ScopeId<'db>, +) -> Option> { let path = PathId::from_ident(db.as_hir_db(), ident); let EarlyResolvedPath::Full(bucket) = resolve_path_early(db, path, scope) else { return None; diff --git a/crates/hir-analysis/src/ty/diagnostics.rs b/crates/hir-analysis/src/ty/diagnostics.rs index 7c848d694..f5407c691 100644 --- a/crates/hir-analysis/src/ty/diagnostics.rs +++ b/crates/hir-analysis/src/ty/diagnostics.rs @@ -23,29 +23,29 @@ use super::{ use crate::{name_resolution::diagnostics::NameResDiag, HirAnalysisDb}; #[salsa::accumulator] -pub struct AdtDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct AdtDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct TraitDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct TraitDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct ImplTraitDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct ImplTraitDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct ImplDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct ImplDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct FuncDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct FuncDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct TypeAliasDefDiagAccumulator(pub(super) TyDiagCollection); +pub struct TypeAliasDefDiagAccumulator<'db>(pub(super) TyDiagCollection<'db>); #[salsa::accumulator] -pub struct FuncBodyDiagAccumulator(pub(super) FuncBodyDiag); +pub struct FuncBodyDiagAccumulator<'db>(pub(super) FuncBodyDiag<'db>); #[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::From)] -pub enum FuncBodyDiag { - Ty(TyDiagCollection), - Body(BodyDiag), - NameRes(NameResDiag), +pub enum FuncBodyDiag<'db> { + Ty(TyDiagCollection<'db>), + Body(BodyDiag<'db>), + NameRes(NameResDiag<'db>), } -impl FuncBodyDiag { - pub(super) fn to_voucher(&self) -> Box { +impl<'db> FuncBodyDiag<'db> { + pub(super) fn to_voucher(&self) -> Box { match self { Self::Ty(diag) => diag.to_voucher(), Self::Body(diag) => Box::new(diag.clone()) as _, @@ -55,15 +55,15 @@ impl FuncBodyDiag { } #[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::From)] -pub enum TyDiagCollection { - Ty(TyLowerDiag), - Satisfiability(TraitConstraintDiag), - TraitLower(TraitLowerDiag), - Impl(ImplDiag), +pub enum TyDiagCollection<'db> { + Ty(TyLowerDiag<'db>), + Satisfiability(TraitConstraintDiag<'db>), + TraitLower(TraitLowerDiag<'db>), + Impl(ImplDiag<'db>), } -impl TyDiagCollection { - pub(super) fn to_voucher(&self) -> Box { +impl<'db> TyDiagCollection<'db> { + pub(super) fn to_voucher(&self) -> Box { match self.clone() { TyDiagCollection::Ty(diag) => Box::new(diag) as _, TyDiagCollection::Satisfiability(diag) => Box::new(diag) as _, @@ -74,78 +74,78 @@ impl TyDiagCollection { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TyLowerDiag { - ExpectedStarKind(DynLazySpan), - InvalidTypeArgKind(DynLazySpan, String), +pub enum TyLowerDiag<'db> { + ExpectedStarKind(DynLazySpan<'db>), + InvalidTypeArgKind(DynLazySpan<'db>, String), RecursiveType { - primary_span: DynLazySpan, - field_span: DynLazySpan, + primary_span: DynLazySpan<'db>, + field_span: DynLazySpan<'db>, }, UnboundTypeAliasParam { - span: DynLazySpan, - type_alias: HirTypeAlias, + span: DynLazySpan<'db>, + type_alias: HirTypeAlias<'db>, n_given_arg: usize, }, TypeAliasCycle { - primary: DynLazySpan, - cycle: Vec, + primary: DynLazySpan<'db>, + cycle: Vec>, }, - InconsistentKindBound(DynLazySpan, String), + InconsistentKindBound(DynLazySpan<'db>, String), - KindBoundNotAllowed(DynLazySpan), + KindBoundNotAllowed(DynLazySpan<'db>), GenericParamAlreadyDefinedInParent { - primary: DynLazySpan, - conflict_with: DynLazySpan, - name: IdentId, + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, + name: IdentId<'db>, }, DuplicatedArgName { - primary: DynLazySpan, - conflict_with: DynLazySpan, - name: IdentId, + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, + name: IdentId<'db>, }, InvalidConstParamTy { - primary: DynLazySpan, + primary: DynLazySpan<'db>, pretty_ty: String, }, - RecursiveConstParamTy(DynLazySpan), + RecursiveConstParamTy(DynLazySpan<'db>), ConstTyMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: String, actual: String, }, ConstTyExpected { - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: String, }, NormalTypeExpected { - primary: DynLazySpan, + primary: DynLazySpan<'db>, given: String, }, - AssocTy(DynLazySpan), + AssocTy(DynLazySpan<'db>), - InvalidConstTyExpr(DynLazySpan), + InvalidConstTyExpr(DynLazySpan<'db>), } -impl TyLowerDiag { - pub fn expected_star_kind_ty(span: DynLazySpan) -> Self { +impl<'db> TyLowerDiag<'db> { + pub fn expected_star_kind_ty(span: DynLazySpan<'db>) -> Self { Self::ExpectedStarKind(span) } pub fn invalid_type_arg_kind( db: &dyn HirAnalysisDb, - span: DynLazySpan, + span: DynLazySpan<'db>, expected: Option, - arg: TyId, + arg: TyId<'db>, ) -> Self { let msg = if let Some(expected) = expected { let arg_kind = arg.kind(db); @@ -164,7 +164,10 @@ impl TyLowerDiag { Self::InvalidTypeArgKind(span, msg) } - pub(super) fn recursive_type(primary_span: DynLazySpan, field_span: DynLazySpan) -> Self { + pub(super) fn recursive_type( + primary_span: DynLazySpan<'db>, + field_span: DynLazySpan<'db>, + ) -> Self { Self::RecursiveType { primary_span, field_span, @@ -172,8 +175,8 @@ impl TyLowerDiag { } pub(super) fn unbound_type_alias_param( - span: DynLazySpan, - type_alias: HirTypeAlias, + span: DynLazySpan<'db>, + type_alias: HirTypeAlias<'db>, n_given_arg: usize, ) -> Self { Self::UnboundTypeAliasParam { @@ -184,18 +187,18 @@ impl TyLowerDiag { } pub(super) fn invalid_const_param_ty( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - ty: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + ty: TyId<'db>, ) -> Self { let pretty_ty = ty.pretty_print(db).to_string(); Self::InvalidConstParamTy { primary, pretty_ty } } pub(super) fn inconsistent_kind_bound( - db: &dyn HirAnalysisDb, - span: DynLazySpan, - ty: TyId, + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + ty: TyId<'db>, former_bound: &Kind, new_kind: &Kind, ) -> Self { @@ -209,9 +212,9 @@ impl TyLowerDiag { } pub(super) fn generic_param_conflict( - primary: DynLazySpan, - conflict_with: DynLazySpan, - name: IdentId, + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, + name: IdentId<'db>, ) -> Self { Self::GenericParamAlreadyDefinedInParent { primary, @@ -221,10 +224,10 @@ impl TyLowerDiag { } pub(super) fn const_ty_mismatch( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - expected: TyId, - actual: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + expected: TyId<'db>, + actual: TyId<'db>, ) -> Self { let expected = expected.pretty_print(db).to_string(); let actual = actual.pretty_print(db).to_string(); @@ -237,26 +240,26 @@ impl TyLowerDiag { pub(super) fn const_ty_expected( db: &dyn HirAnalysisDb, - primary: DynLazySpan, - expected: TyId, + primary: DynLazySpan<'db>, + expected: TyId<'db>, ) -> Self { let expected = expected.pretty_print(db).to_string(); Self::ConstTyExpected { primary, expected } } pub(super) fn normal_type_expected( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - given: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + given: TyId<'db>, ) -> Self { let given = given.pretty_print(db).to_string(); Self::NormalTypeExpected { primary, given } } pub(super) fn duplicated_arg_name( - primary: DynLazySpan, - conflict_with: DynLazySpan, - name: IdentId, + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, + name: IdentId<'db>, ) -> Self { Self::DuplicatedArgName { primary, @@ -265,7 +268,7 @@ impl TyLowerDiag { } } - pub(super) fn assoc_ty(span: DynLazySpan) -> Self { + pub(super) fn assoc_ty(span: DynLazySpan<'db>) -> Self { Self::AssocTy(span) } @@ -527,7 +530,7 @@ impl TyLowerDiag { } } -impl DiagnosticVoucher for TyLowerDiag { +impl<'db> DiagnosticVoucher for TyLowerDiag<'db> { fn error_code(&self) -> GlobalErrorCode { GlobalErrorCode::new(DiagnosticPass::TypeDefinition, self.local_code()) } @@ -543,174 +546,174 @@ impl DiagnosticVoucher for TyLowerDiag { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum BodyDiag { - TypeMismatch(DynLazySpan, String, String), - InfiniteOccurrence(DynLazySpan), +pub enum BodyDiag<'db> { + TypeMismatch(DynLazySpan<'db>, String, String), + InfiniteOccurrence(DynLazySpan<'db>), - DuplicatedRestPat(DynLazySpan), + DuplicatedRestPat(DynLazySpan<'db>), InvalidPathDomainInPat { - primary: DynLazySpan, - resolved: Option, + primary: DynLazySpan<'db>, + resolved: Option>, }, UnitVariantExpected { - primary: DynLazySpan, + primary: DynLazySpan<'db>, kind_name: String, hint: Option, }, TupleVariantExpected { - primary: DynLazySpan, + primary: DynLazySpan<'db>, kind_name: Option, hint: Option, }, RecordExpected { - primary: DynLazySpan, + primary: DynLazySpan<'db>, kind_name: Option, hint: Option, }, MismatchedFieldCount { - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: usize, given: usize, }, DuplicatedRecordFieldBind { - primary: DynLazySpan, - first_use: DynLazySpan, - name: IdentId, + primary: DynLazySpan<'db>, + first_use: DynLazySpan<'db>, + name: IdentId<'db>, }, RecordFieldNotFound { - primary: DynLazySpan, - label: IdentId, + primary: DynLazySpan<'db>, + label: IdentId<'db>, }, ExplicitLabelExpectedInRecord { - primary: DynLazySpan, + primary: DynLazySpan<'db>, hint: Option, }, MissingRecordFields { - primary: DynLazySpan, - missing_fields: BTreeSet, + primary: DynLazySpan<'db>, + missing_fields: BTreeSet>, hint: Option, }, - UndefinedVariable(DynLazySpan, IdentId), + UndefinedVariable(DynLazySpan<'db>, IdentId<'db>), ReturnedTypeMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, actual: String, expected: String, - func: Option, + func: Option>, }, - TypeMustBeKnown(DynLazySpan), + TypeMustBeKnown(DynLazySpan<'db>), AccessedFieldNotFound { - primary: DynLazySpan, + primary: DynLazySpan<'db>, given_ty: String, - index: FieldIndex, + index: FieldIndex<'db>, }, OpsTraitNotImplemented { - span: DynLazySpan, + span: DynLazySpan<'db>, ty: String, - op: IdentId, - trait_path: PathId, + op: IdentId<'db>, + trait_path: PathId<'db>, }, - NonAssignableExpr(DynLazySpan), + NonAssignableExpr(DynLazySpan<'db>), ImmutableAssignment { - primary: DynLazySpan, - binding: Option<(IdentId, DynLazySpan)>, + primary: DynLazySpan<'db>, + binding: Option<(IdentId<'db>, DynLazySpan<'db>)>, }, LoopControlOutsideOfLoop { - primary: DynLazySpan, + primary: DynLazySpan<'db>, is_break: bool, }, TraitNotImplemented { - primary: DynLazySpan, + primary: DynLazySpan<'db>, ty: String, - trait_name: IdentId, + trait_name: IdentId<'db>, }, - NotCallable(DynLazySpan, String), + NotCallable(DynLazySpan<'db>, String), CallGenericArgNumMismatch { - primary: DynLazySpan, - def_span: DynLazySpan, + primary: DynLazySpan<'db>, + def_span: DynLazySpan<'db>, given: usize, expected: usize, }, CallArgNumMismatch { - primary: DynLazySpan, - def_span: DynLazySpan, + primary: DynLazySpan<'db>, + def_span: DynLazySpan<'db>, given: usize, expected: usize, }, CallArgLabelMismatch { - primary: DynLazySpan, - def_span: DynLazySpan, - given: Option, - expected: IdentId, + primary: DynLazySpan<'db>, + def_span: DynLazySpan<'db>, + given: Option>, + expected: IdentId<'db>, }, AmbiguousInherentMethodCall { - primary: DynLazySpan, - method_name: IdentId, - cand_spans: Vec, + primary: DynLazySpan<'db>, + method_name: IdentId<'db>, + cand_spans: Vec>, }, AmbiguousTrait { - primary: DynLazySpan, - method_name: IdentId, - traits: Vec, + primary: DynLazySpan<'db>, + method_name: IdentId<'db>, + traits: Vec>, }, AmbiguousTraitInst { - primary: DynLazySpan, + primary: DynLazySpan<'db>, cands: Vec, }, InvisibleAmbiguousTrait { - primary: DynLazySpan, - traits: Vec, + primary: DynLazySpan<'db>, + traits: Vec>, }, MethodNotFound { - primary: DynLazySpan, - method_name: IdentId, + primary: DynLazySpan<'db>, + method_name: IdentId<'db>, receiver: String, }, NotValue { - primary: DynLazySpan, - given: Either, + primary: DynLazySpan<'db>, + given: Either, TyId<'db>>, }, TypeAnnotationNeeded { - primary: DynLazySpan, + primary: DynLazySpan<'db>, ty: Option, is_integral: bool, }, } -impl BodyDiag { +impl<'db> BodyDiag<'db> { pub(super) fn type_mismatch( - db: &dyn HirAnalysisDb, - span: DynLazySpan, - expected: TyId, - actual: TyId, + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + expected: TyId<'db>, + actual: TyId<'db>, ) -> Self { let expected = expected.pretty_print(db).to_string(); let actual = actual.pretty_print(db).to_string(); @@ -718,8 +721,8 @@ impl BodyDiag { } pub(super) fn unit_variant_expected( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, record_like: T, ) -> Self where @@ -735,8 +738,8 @@ impl BodyDiag { } pub(super) fn tuple_variant_expected( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, record_like: Option, ) -> Self where @@ -782,16 +785,16 @@ impl BodyDiag { } } - pub(super) fn record_field_not_found(primary: DynLazySpan, label: IdentId) -> Self { + pub(super) fn record_field_not_found(primary: DynLazySpan<'db>, label: IdentId<'db>) -> Self { Self::RecordFieldNotFound { primary, label } } pub(super) fn returned_type_mismatch( db: &dyn HirAnalysisDb, - primary: DynLazySpan, - actual: TyId, - expected: TyId, - func: Option, + primary: DynLazySpan<'db>, + actual: TyId<'db>, + expected: TyId<'db>, + func: Option>, ) -> Self { let actual = actual.pretty_print(db).to_string(); let expected = expected.pretty_print(db).to_string(); @@ -805,9 +808,9 @@ impl BodyDiag { pub(super) fn accessed_field_not_found( db: &dyn HirAnalysisDb, - primary: DynLazySpan, - given_ty: TyId, - index: FieldIndex, + primary: DynLazySpan<'db>, + given_ty: TyId<'db>, + index: FieldIndex<'db>, ) -> Self { let given_ty = given_ty.pretty_print(db).to_string(); Self::AccessedFieldNotFound { @@ -818,9 +821,9 @@ impl BodyDiag { } pub(super) fn ops_trait_not_implemented( - db: &dyn HirAnalysisDb, - span: DynLazySpan, - ty: TyId, + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + ty: TyId<'db>, ops: T, ) -> Self where @@ -836,16 +839,20 @@ impl BodyDiag { trait_path, } } - pub(super) fn not_callable(db: &dyn HirAnalysisDb, span: DynLazySpan, ty: TyId) -> Self { + pub(super) fn not_callable( + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + ty: TyId<'db>, + ) -> Self { let ty = ty.pretty_print(db).to_string(); Self::NotCallable(span, ty) } pub(super) fn method_not_found( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - method_name: IdentId, - receiver: Either, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + method_name: IdentId<'db>, + receiver: Either, TraitDef<'db>>, ) -> Self { let receiver = match receiver { Either::Left(ty) => ty.pretty_print(db), @@ -864,9 +871,9 @@ impl BodyDiag { } pub(super) fn type_annotation_needed( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - ty: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + ty: TyId<'db>, ) -> Self { let (ty, is_integral) = match ty.base_ty(db).data(db) { TyData::TyVar(var) => (None, matches!(var.sort, TyVarSort::Integral)), @@ -881,9 +888,9 @@ impl BodyDiag { } pub(super) fn ambiguous_trait_inst( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - cands: Vec, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + cands: Vec>, ) -> Self { let cands = cands .into_iter() @@ -1579,7 +1586,7 @@ impl BodyDiag { } } -impl DiagnosticVoucher for BodyDiag { +impl<'db> DiagnosticVoucher for BodyDiag<'db> { fn error_code(&self) -> GlobalErrorCode { GlobalErrorCode::new(DiagnosticPass::TyCheck, self.local_code()) } @@ -1595,23 +1602,23 @@ impl DiagnosticVoucher for BodyDiag { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TraitLowerDiag { - ExternalTraitForExternalType(DynLazySpan), +pub enum TraitLowerDiag<'db> { + ExternalTraitForExternalType(DynLazySpan<'db>), ConflictTraitImpl { - primary: ImplTrait, - conflict_with: ImplTrait, + primary: ImplTrait<'db>, + conflict_with: ImplTrait<'db>, }, - CyclicSuperTraits(DynLazySpan), + CyclicSuperTraits(DynLazySpan<'db>), } -impl TraitLowerDiag { - pub(super) fn external_trait_for_external_type(impl_trait: ImplTrait) -> Self { +impl<'db> TraitLowerDiag<'db> { + pub(super) fn external_trait_for_external_type(impl_trait: ImplTrait<'db>) -> Self { Self::ExternalTraitForExternalType(impl_trait.lazy_span().trait_ref().into()) } - pub(super) fn conflict_impl(primary: ImplTrait, conflict_with: ImplTrait) -> Self { + pub(super) fn conflict_impl(primary: ImplTrait<'db>, conflict_with: ImplTrait<'db>) -> Self { Self::ConflictTraitImpl { primary, conflict_with, @@ -1677,7 +1684,7 @@ impl TraitLowerDiag { } } -impl DiagnosticVoucher for TraitLowerDiag { +impl<'db> DiagnosticVoucher for TraitLowerDiag<'db> { fn error_code(&self) -> GlobalErrorCode { GlobalErrorCode::new(DiagnosticPass::ImplTraitDefinition, self.local_code()) } @@ -1693,35 +1700,35 @@ impl DiagnosticVoucher for TraitLowerDiag { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TraitConstraintDiag { +pub enum TraitConstraintDiag<'db> { KindMismatch { - primary: DynLazySpan, - trait_def: Trait, + primary: DynLazySpan<'db>, + trait_def: Trait<'db>, }, TraitArgNumMismatch { - span: DynLazySpan, + span: DynLazySpan<'db>, expected: usize, given: usize, }, - TraitArgKindMismatch(DynLazySpan, String), + TraitArgKindMismatch(DynLazySpan<'db>, String), - TraitBoundNotSat(DynLazySpan, String, Option), + TraitBoundNotSat(DynLazySpan<'db>, String, Option), - InfiniteBoundRecursion(DynLazySpan, String), + InfiniteBoundRecursion(DynLazySpan<'db>, String), - ConcreteTypeBound(DynLazySpan, String), + ConcreteTypeBound(DynLazySpan<'db>, String), - ConstTyBound(DynLazySpan, String), + ConstTyBound(DynLazySpan<'db>, String), } -impl TraitConstraintDiag { +impl<'db> TraitConstraintDiag<'db> { pub(super) fn kind_mismatch( - db: &dyn HirAnalysisDb, - span: DynLazySpan, + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, expected: &Kind, - actual: TyId, + actual: TyId<'db>, ) -> Self { let actual_kind = actual.kind(db); let ty_display = actual.pretty_print(db); @@ -1732,7 +1739,11 @@ impl TraitConstraintDiag { Self::TraitArgKindMismatch(span, msg) } - pub(super) fn trait_arg_num_mismatch(span: DynLazySpan, expected: usize, given: usize) -> Self { + pub(super) fn trait_arg_num_mismatch( + span: DynLazySpan<'db>, + expected: usize, + given: usize, + ) -> Self { Self::TraitArgNumMismatch { span, expected, @@ -1741,10 +1752,10 @@ impl TraitConstraintDiag { } pub(super) fn trait_bound_not_satisfied( - db: &dyn HirAnalysisDb, - span: DynLazySpan, - primary_goal: TraitInstId, - unsat_subgoal: Option, + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + primary_goal: TraitInstId<'db>, + unsat_subgoal: Option>, ) -> Self { let msg = format!( "`{}` doesn't implement `{}`", @@ -1761,12 +1772,20 @@ impl TraitConstraintDiag { Self::TraitBoundNotSat(span, msg, unsat_subgoal) } - pub(super) fn const_ty_bound(db: &dyn HirAnalysisDb, ty: TyId, span: DynLazySpan) -> Self { + pub(super) fn const_ty_bound( + db: &'db dyn HirAnalysisDb, + ty: TyId<'db>, + span: DynLazySpan<'db>, + ) -> Self { let msg = format!("`{}` is a const type", ty.pretty_print(db)); Self::ConstTyBound(span, msg) } - pub(super) fn concrete_type_bound(db: &dyn HirAnalysisDb, span: DynLazySpan, ty: TyId) -> Self { + pub(super) fn concrete_type_bound( + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + ty: TyId<'db>, + ) -> Self { let msg = format!("`{}` is a concrete type", ty.pretty_print(db)); Self::ConcreteTypeBound(span, msg) } @@ -1879,7 +1898,7 @@ impl TraitConstraintDiag { } } -impl DiagnosticVoucher for TraitConstraintDiag { +impl<'db> DiagnosticVoucher for TraitConstraintDiag<'db> { fn error_code(&self) -> GlobalErrorCode { GlobalErrorCode::new(DiagnosticPass::TraitSatisfaction, self.local_code()) } @@ -1895,75 +1914,78 @@ impl DiagnosticVoucher for TraitConstraintDiag { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ImplDiag { +pub enum ImplDiag<'db> { ConflictMethodImpl { - primary: DynLazySpan, - conflict_with: DynLazySpan, + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, }, MethodNotDefinedInTrait { - primary: DynLazySpan, - trait_: Trait, - method_name: IdentId, + primary: DynLazySpan<'db>, + trait_: Trait<'db>, + method_name: IdentId<'db>, }, NotAllTraitItemsImplemented { - primary: DynLazySpan, - not_implemented: BTreeSet, + primary: DynLazySpan<'db>, + not_implemented: BTreeSet>, }, MethodTypeParamNumMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: usize, given: usize, }, MethodTypeParamKindMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, message: String, }, MethodArgNumMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: usize, given: usize, }, MethodArgLabelMismatch { - primary: DynLazySpan, - definition: DynLazySpan, + primary: DynLazySpan<'db>, + definition: DynLazySpan<'db>, message: String, }, MethodArgTyMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, message: String, }, MethodRetTyMismatch { - primary: DynLazySpan, + primary: DynLazySpan<'db>, message: String, }, MethodStricterBound { - primary: DynLazySpan, + primary: DynLazySpan<'db>, message: String, }, InvalidSelfType { - primary: DynLazySpan, + primary: DynLazySpan<'db>, message: String, }, InherentImplIsNotAllowed { - primary: DynLazySpan, + primary: DynLazySpan<'db>, ty: String, is_nominal: bool, }, } -impl ImplDiag { - pub(super) fn conflict_method_impl(primary: DynLazySpan, conflict_with: DynLazySpan) -> Self { +impl<'db> ImplDiag<'db> { + pub(super) fn conflict_method_impl( + primary: DynLazySpan<'db>, + conflict_with: DynLazySpan<'db>, + ) -> Self { Self::ConflictMethodImpl { primary, conflict_with, @@ -1971,9 +1993,9 @@ impl ImplDiag { } pub(super) fn method_not_defined_in_trait( - primary: DynLazySpan, - trait_: Trait, - method_name: IdentId, + primary: DynLazySpan<'db>, + trait_: Trait<'db>, + method_name: IdentId<'db>, ) -> Self { Self::MethodNotDefinedInTrait { primary, @@ -1983,8 +2005,8 @@ impl ImplDiag { } pub(super) fn not_all_trait_items_implemented( - primary: DynLazySpan, - not_implemented: BTreeSet, + primary: DynLazySpan<'db>, + not_implemented: BTreeSet>, ) -> Self { Self::NotAllTraitItemsImplemented { primary, @@ -1993,7 +2015,7 @@ impl ImplDiag { } pub(super) fn method_param_num_mismatch( - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: usize, given: usize, ) -> Self { @@ -2005,7 +2027,7 @@ impl ImplDiag { } pub(super) fn method_arg_num_mismatch( - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: usize, given: usize, ) -> Self { @@ -2017,10 +2039,10 @@ impl ImplDiag { } pub fn method_arg_ty_mismatch( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - expected: TyId, - given: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + expected: TyId<'db>, + given: TyId<'db>, ) -> Self { let message = format!( "expected `{}` type, but the given type is `{}`", @@ -2032,11 +2054,11 @@ impl ImplDiag { } pub fn method_arg_label_mismatch( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - definition: DynLazySpan, - expected: FuncParamName, - given: FuncParamName, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + definition: DynLazySpan<'db>, + expected: FuncParamName<'db>, + given: FuncParamName<'db>, ) -> Self { let message = format!( "expected `{}` label, but the given label is `{}`", @@ -2052,10 +2074,10 @@ impl ImplDiag { } pub fn method_ret_type_mismatch( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - expected: TyId, - given: TyId, + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + expected: TyId<'db>, + given: TyId<'db>, ) -> Self { let message = format!( "expected `{}` type, but the given type is `{}`", @@ -2067,7 +2089,7 @@ impl ImplDiag { } pub(super) fn method_param_kind_mismatch( - primary: DynLazySpan, + primary: DynLazySpan<'db>, expected: &Kind, given: &Kind, ) -> Self { @@ -2080,9 +2102,9 @@ impl ImplDiag { } pub(super) fn method_stricter_bound( - db: &dyn HirAnalysisDb, - primary: DynLazySpan, - stricter_bounds: &[TraitInstId], + db: &'db dyn HirAnalysisDb, + primary: DynLazySpan<'db>, + stricter_bounds: &[TraitInstId<'db>], ) -> Self { let message = format!( "method has stricter bounds than the declared method in the trait: {}", @@ -2096,9 +2118,9 @@ impl ImplDiag { pub(super) fn invalid_self_ty( db: &dyn HirAnalysisDb, - primary: DynLazySpan, - expected: TyId, - actual: TyId, + primary: DynLazySpan<'db>, + expected: TyId<'db>, + actual: TyId<'db>, ) -> Self { let message = if !expected.is_trait_self(db) { format!( @@ -2352,7 +2374,7 @@ impl ImplDiag { } } -impl DiagnosticVoucher for ImplDiag { +impl<'db> DiagnosticVoucher for ImplDiag<'db> { fn error_code(&self) -> GlobalErrorCode { GlobalErrorCode::new(DiagnosticPass::TraitSatisfaction, self.local_code()) } diff --git a/crates/hir-analysis/src/ty/fold.rs b/crates/hir-analysis/src/ty/fold.rs index 823f5c992..768ede709 100644 --- a/crates/hir-analysis/src/ty/fold.rs +++ b/crates/hir-analysis/src/ty/fold.rs @@ -30,10 +30,10 @@ where pub trait TyFolder<'db> { fn db(&self) -> &'db dyn HirAnalysisDb; - fn fold_ty(&mut self, ty: TyId) -> TyId; + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db>; } -impl<'db> TyFoldable<'db> for TyId { +impl<'db> TyFoldable<'db> for TyId<'db> { fn super_fold_with(self, folder: &mut F) -> Self where F: TyFolder<'db>, @@ -109,7 +109,7 @@ where } } -impl<'db> TyFoldable<'db> for TraitInstId { +impl<'db> TyFoldable<'db> for TraitInstId<'db> { fn super_fold_with(self, folder: &mut F) -> Self where F: TyFolder<'db>, @@ -126,7 +126,7 @@ impl<'db> TyFoldable<'db> for TraitInstId { } } -impl<'db> TyFoldable<'db> for Implementor { +impl<'db> TyFoldable<'db> for Implementor<'db> { fn super_fold_with(self, folder: &mut F) -> Self where F: TyFolder<'db>, @@ -144,7 +144,7 @@ impl<'db> TyFoldable<'db> for Implementor { } } -impl<'db> TyFoldable<'db> for PredicateListId { +impl<'db> TyFoldable<'db> for PredicateListId<'db> { fn super_fold_with(self, folder: &mut F) -> Self where F: TyFolder<'db>, @@ -159,7 +159,7 @@ impl<'db> TyFoldable<'db> for PredicateListId { } } -impl<'db> TyFoldable<'db> for ExprProp { +impl<'db> TyFoldable<'db> for ExprProp<'db> { fn super_fold_with(self, folder: &mut F) -> Self where F: TyFolder<'db>, diff --git a/crates/hir-analysis/src/ty/func_def.rs b/crates/hir-analysis/src/ty/func_def.rs index a9ffa5cc9..b507381ac 100644 --- a/crates/hir-analysis/src/ty/func_def.rs +++ b/crates/hir-analysis/src/ty/func_def.rs @@ -15,7 +15,7 @@ use crate::{ /// Lower func to [`FuncDef`]. This function returns `None` iff the function /// name is `Partial::Absent`. #[salsa::tracked] -pub fn lower_func(db: &dyn HirAnalysisDb, func: Func) -> Option { +pub fn lower_func<'db>(db: &'db dyn HirAnalysisDb, func: Func<'db>) -> Option> { let name = func.name(db.as_hir_db()).to_opt()?; let params_set = collect_generic_params(db, GenericParamOwnerId::new(db, func.into())); @@ -51,47 +51,47 @@ pub fn lower_func(db: &dyn HirAnalysisDb, func: Func) -> Option { } #[salsa::tracked] -pub struct FuncDef { - pub hir_def: HirFuncDefKind, +pub struct FuncDef<'db> { + pub hir_def: HirFuncDefKind<'db>, - pub name: IdentId, + pub name: IdentId<'db>, - pub params_set: GenericParamTypeSet, + pub params_set: GenericParamTypeSet<'db>, /// Argument types of the function. #[return_ref] - pub arg_tys: Vec>, + pub arg_tys: Vec>>, /// Return types of the function. - pub ret_ty: Binder, + pub ret_ty: Binder>, } -impl FuncDef { - pub fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { +impl<'db> FuncDef<'db> { + pub fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> { self.hir_def(db).ingot(db) } - pub fn name_span(self, db: &dyn HirAnalysisDb) -> DynLazySpan { + pub fn name_span(self, db: &'db dyn HirAnalysisDb) -> DynLazySpan<'db> { self.hir_def(db).name_span() } - pub fn param_list_span(self, db: &dyn HirAnalysisDb) -> DynLazySpan { + pub fn param_list_span(self, db: &'db dyn HirAnalysisDb) -> DynLazySpan<'db> { self.hir_def(db).param_list_span() } - pub fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId { + pub fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> { self.hir_def(db).scope() } - pub fn params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub fn params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.params_set(db).params(db) } - pub fn explicit_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub fn explicit_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.params_set(db).explicit_params(db) } - pub fn receiver_ty(self, db: &dyn HirAnalysisDb) -> Option> { + pub fn receiver_ty(self, db: &'db dyn HirAnalysisDb) -> Option>> { self.is_method(db) .then(|| self.arg_tys(db).first().copied().unwrap()) } @@ -104,7 +104,7 @@ impl FuncDef { self.params_set(db).offset_to_explicit_params_position(db) } - pub fn hir_func_def(self, db: &dyn HirAnalysisDb) -> Option { + pub fn hir_func_def(self, db: &'db dyn HirAnalysisDb) -> Option> { if let HirFuncDefKind::Func(func) = self.hir_def(db) { Some(func) } else { @@ -112,23 +112,23 @@ impl FuncDef { } } - pub fn param_span(self, db: &dyn HirAnalysisDb, idx: usize) -> DynLazySpan { + pub fn param_span(self, db: &'db dyn HirAnalysisDb, idx: usize) -> DynLazySpan<'db> { self.hir_def(db).param_span(idx) } - pub fn param_label(self, db: &dyn HirAnalysisDb, idx: usize) -> Option { + pub fn param_label(self, db: &'db dyn HirAnalysisDb, idx: usize) -> Option> { self.hir_def(db).param_label(db, idx) } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, derive_more::From)] -pub enum HirFuncDefKind { - Func(Func), - VariantCtor(Enum, usize), +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, derive_more::From, salsa::Update)] +pub enum HirFuncDefKind<'db> { + Func(Func<'db>), + VariantCtor(Enum<'db>, usize), } -impl HirFuncDefKind { - pub fn name_span(self) -> DynLazySpan { +impl<'db> HirFuncDefKind<'db> { + pub fn name_span(self) -> DynLazySpan<'db> { match self { Self::Func(func) => func.lazy_span().name_moved().into(), Self::VariantCtor(enum_, idx) => enum_ @@ -147,7 +147,7 @@ impl HirFuncDefKind { } } - pub fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { + pub fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> { let top_mod = match self { Self::Func(func) => func.top_mod(db.as_hir_db()), Self::VariantCtor(enum_, ..) => enum_.top_mod(db.as_hir_db()), @@ -156,14 +156,14 @@ impl HirFuncDefKind { top_mod.ingot(db.as_hir_db()) } - pub fn scope(self) -> ScopeId { + pub fn scope(self) -> ScopeId<'db> { match self { Self::Func(func) => func.scope(), Self::VariantCtor(enum_, idx) => ScopeId::Variant(enum_.into(), idx), } } - pub fn param_list_span(self) -> DynLazySpan { + pub fn param_list_span(self) -> DynLazySpan<'db> { match self { Self::Func(func) => func.lazy_span().params_moved().into(), Self::VariantCtor(enum_, idx) => enum_ @@ -175,7 +175,7 @@ impl HirFuncDefKind { } } - pub fn param_label(self, db: &dyn HirAnalysisDb, idx: usize) -> Option { + pub fn param_label(self, db: &'db dyn HirAnalysisDb, idx: usize) -> Option> { let Self::Func(func) = self else { return None; }; @@ -187,7 +187,7 @@ impl HirFuncDefKind { .label_eagerly() } - pub fn param_span(self, idx: usize) -> DynLazySpan { + pub fn param_span(self, idx: usize) -> DynLazySpan<'db> { match self { Self::Func(func) => func.lazy_span().params_moved().param(idx).into(), Self::VariantCtor(enum_, variant_idx) => enum_ diff --git a/crates/hir-analysis/src/ty/method_cmp.rs b/crates/hir-analysis/src/ty/method_cmp.rs index c36eaecdb..5822350b5 100644 --- a/crates/hir-analysis/src/ty/method_cmp.rs +++ b/crates/hir-analysis/src/ty/method_cmp.rs @@ -33,12 +33,12 @@ use crate::HirAnalysisDb; /// * `trait_inst` - The instance of the trait being checked. /// * `sink` - A mutable reference to a vector where diagnostic messages will be /// collected. -pub(super) fn compare_impl_method( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: TraitMethod, - trait_inst: TraitInstId, - sink: &mut Vec, +pub(super) fn compare_impl_method<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: TraitMethod<'db>, + trait_inst: TraitInstId<'db>, + sink: &mut Vec>, ) { if !compare_generic_param_num(db, impl_m, trait_m.0, sink) { return; @@ -73,11 +73,11 @@ pub(super) fn compare_impl_method( /// Checks if the number of generic parameters of the implemented method is the /// same as the number of generic parameters of the trait method. /// Returns `false` if the comparison fails. -fn compare_generic_param_num( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: FuncDef, - sink: &mut Vec, +fn compare_generic_param_num<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: FuncDef<'db>, + sink: &mut Vec>, ) -> bool { let impl_params = impl_m.explicit_params(db); let trait_params = trait_m.explicit_params(db); @@ -99,11 +99,11 @@ fn compare_generic_param_num( /// Checks if the generic parameter kinds are the same. /// Returns `false` if the comparison fails. -fn compare_generic_param_kind( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: FuncDef, - sink: &mut Vec, +fn compare_generic_param_kind<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: FuncDef<'db>, + sink: &mut Vec>, ) -> bool { let mut err = false; for (idx, (&trait_m_param, &impl_m_param)) in trait_m @@ -134,11 +134,11 @@ fn compare_generic_param_kind( /// Checks if the arity of the implemented method is the same as the arity of /// the trait method. /// Returns `false` if the comparison fails. -fn compare_arity( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: FuncDef, - sink: &mut Vec, +fn compare_arity<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: FuncDef<'db>, + sink: &mut Vec>, ) -> bool { let impl_m_arity = impl_m.arg_tys(db).len(); let trait_m_arity = trait_m.arg_tys(db).len(); @@ -162,11 +162,11 @@ fn compare_arity( /// Checks if the argument labels of the implemented method are the same as the /// argument labels of the trait method. /// Returns `false` if the comparison fails. -fn compare_arg_label( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: FuncDef, - sink: &mut Vec, +fn compare_arg_label<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: FuncDef<'db>, + sink: &mut Vec>, ) -> bool { let hir_db = db.as_hir_db(); @@ -216,12 +216,12 @@ fn compare_arg_label( /// Checks if the argument types and return type of the implemented method are /// the same as the argument types and return type of the trait method. /// Returns `false` if the comparison fails. -fn compare_ty( - db: &dyn HirAnalysisDb, - impl_m: FuncDef, - trait_m: FuncDef, - map_to_impl: &[TyId], - sink: &mut Vec, +fn compare_ty<'db>( + db: &'db dyn HirAnalysisDb, + impl_m: FuncDef<'db>, + trait_m: FuncDef<'db>, + map_to_impl: &[TyId<'db>], + sink: &mut Vec>, ) -> bool { let mut err = false; let impl_m_arg_tys = impl_m.arg_tys(db); diff --git a/crates/hir-analysis/src/ty/method_table.rs b/crates/hir-analysis/src/ty/method_table.rs index 1e4559025..26b0b8970 100644 --- a/crates/hir-analysis/src/ty/method_table.rs +++ b/crates/hir-analysis/src/ty/method_table.rs @@ -16,7 +16,10 @@ use crate::{ }; #[salsa::tracked(return_ref)] -pub(crate) fn collect_methods(db: &dyn HirAnalysisDb, ingot: IngotId) -> MethodTable { +pub(crate) fn collect_methods<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, +) -> MethodTable<'db> { let mut collector = MethodCollector::new(db, ingot); let enums = ingot.all_enums(db.as_hir_db()); @@ -29,23 +32,28 @@ pub(crate) fn collect_methods(db: &dyn HirAnalysisDb, ingot: IngotId) -> MethodT } #[salsa::tracked(return_ref)] -pub(crate) fn probe_method( - db: &dyn HirAnalysisDb, - ingot: IngotId, - ty: Canonical, - name: IdentId, -) -> Vec { +pub(crate) fn probe_method<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, + ty: Canonical>, + name: IdentId<'db>, +) -> Vec> { let table = collect_methods(db, ingot); table.probe(db, ty, name) } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct MethodTable { - buckets: FxHashMap, +pub struct MethodTable<'db> { + buckets: FxHashMap, MethodBucket<'db>>, } -impl MethodTable { - fn probe(&self, db: &dyn HirAnalysisDb, ty: Canonical, name: IdentId) -> Vec { +impl<'db> MethodTable<'db> { + fn probe( + &self, + db: &'db dyn HirAnalysisDb, + ty: Canonical>, + name: IdentId<'db>, + ) -> Vec> { let mut table = UnificationTable::new(db); let ty = ty.extract_identity(&mut table); let Some(base) = Self::extract_ty_base(ty, db) else { @@ -69,7 +77,7 @@ impl MethodTable { self } - fn insert(&mut self, db: &dyn HirAnalysisDb, ty: TyId, func: FuncDef) { + fn insert(&mut self, db: &'db dyn HirAnalysisDb, ty: TyId<'db>, func: FuncDef<'db>) { let Some(base) = Self::extract_ty_base(ty, db) else { return; }; @@ -80,7 +88,7 @@ impl MethodTable { methods.insert(name, func); } - fn extract_ty_base(ty: TyId, db: &dyn HirAnalysisDb) -> Option<&TyBase> { + fn extract_ty_base(ty: TyId<'db>, db: &'db dyn HirAnalysisDb) -> Option<&'db TyBase<'db>> { let base = ty.base_ty(db); match base.data(db) { TyData::TyBase(base) => Some(base), @@ -90,18 +98,23 @@ impl MethodTable { } #[derive(Debug, Clone, PartialEq, Eq)] -struct MethodBucket { - methods: FxHashMap, FxHashMap>, +struct MethodBucket<'db> { + methods: FxHashMap>, FxHashMap, FuncDef<'db>>>, } -impl MethodBucket { +impl<'db> MethodBucket<'db> { fn new() -> Self { Self { methods: FxHashMap::default(), } } - fn probe(&self, table: &mut UnificationTable, ty: TyId, name: IdentId) -> Vec { + fn probe( + &self, + table: &mut UnificationTable<'db>, + ty: TyId<'db>, + name: IdentId<'db>, + ) -> Vec> { let mut methods = vec![]; for (&cand_ty, funcs) in self.methods.iter() { let snapshot = table.snapshot(); @@ -124,12 +137,12 @@ impl MethodBucket { struct MethodCollector<'db> { db: &'db dyn HirAnalysisDb, - ingot: IngotId, - method_table: MethodTable, + ingot: IngotId<'db>, + method_table: MethodTable<'db>, } impl<'db> MethodCollector<'db> { - fn new(db: &'db dyn HirAnalysisDb, ingot: IngotId) -> Self { + fn new(db: &'db dyn HirAnalysisDb, ingot: IngotId<'db>) -> Self { Self { db, ingot, @@ -137,7 +150,7 @@ impl<'db> MethodCollector<'db> { } } - fn collect_variant_ctors(&mut self, enums: &[Enum]) { + fn collect_variant_ctors(&mut self, enums: &[Enum<'db>]) { let hir_db = self.db.as_hir_db(); for &enum_ in enums { let adt_ref = AdtRefId::new(self.db, enum_.into()); @@ -181,7 +194,7 @@ impl<'db> MethodCollector<'db> { } } - fn collect_impls(&mut self, impls: &[Impl]) { + fn collect_impls(&mut self, impls: &[Impl<'db>]) { for impl_ in impls { let ty = match impl_.ty(self.db.as_hir_db()).to_opt() { Some(ty) => lower_hir_ty(self.db, ty, impl_.scope()), @@ -202,11 +215,11 @@ impl<'db> MethodCollector<'db> { } } - fn finalize(self) -> MethodTable { + fn finalize(self) -> MethodTable<'db> { self.method_table.finalize() } - fn insert(&mut self, ty: TyId, func: FuncDef) { + fn insert(&mut self, ty: TyId<'db>, func: FuncDef<'db>) { let ty = match func.receiver_ty(self.db) { Some(ty) => ty.instantiate_identity(), None => ty, diff --git a/crates/hir-analysis/src/ty/trait_def.rs b/crates/hir-analysis/src/ty/trait_def.rs index fcf08ee40..dff4c71f9 100644 --- a/crates/hir-analysis/src/ty/trait_def.rs +++ b/crates/hir-analysis/src/ty/trait_def.rs @@ -27,17 +27,20 @@ use crate::{ty::trait_lower::collect_trait_impls, HirAnalysisDb}; /// Returns [`TraitEnv`] for the given ingot. #[salsa::tracked(return_ref)] -pub(crate) fn ingot_trait_env(db: &dyn HirAnalysisDb, ingot: IngotId) -> TraitEnv { +pub(crate) fn ingot_trait_env<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, +) -> TraitEnv<'db> { TraitEnv::collect(db, ingot) } /// Returns all [`Implementor`] for the given trait inst. #[salsa::tracked(return_ref)] -pub(crate) fn impls_for_trait( - db: &dyn HirAnalysisDb, - ingot: IngotId, - trait_: Canonical, -) -> Vec> { +pub(crate) fn impls_for_trait<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, + trait_: Canonical>, +) -> Vec>> { let mut table = UnificationTable::new(db); let trait_ = trait_.extract_identity(&mut table); @@ -61,11 +64,11 @@ pub(crate) fn impls_for_trait( /// Returns all [`Implementor`] for the given `ty`. #[salsa::tracked(return_ref)] -pub(crate) fn impls_for_ty( - db: &dyn HirAnalysisDb, - ingot: IngotId, - ty: Canonical, -) -> Vec> { +pub(crate) fn impls_for_ty<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, + ty: Canonical>, +) -> Vec>> { let mut table = UnificationTable::new(db); let ty = ty.extract_identity(&mut table); @@ -107,18 +110,18 @@ pub(crate) fn impls_for_ty( /// Represents the trait environment of an ingot, which maintain all trait /// implementors which can be used in the ingot. #[derive(Debug, PartialEq, Eq, Clone)] -pub(crate) struct TraitEnv { - pub(super) impls: FxHashMap>>, - hir_to_implementor: FxHashMap>, +pub(crate) struct TraitEnv<'db> { + pub(super) impls: FxHashMap, Vec>>>, + hir_to_implementor: FxHashMap, Binder>>, /// This maintains a mapping from the base type to the implementors. - ty_to_implementors: FxHashMap, Vec>>, + ty_to_implementors: FxHashMap>, Vec>>>, - ingot: IngotId, + ingot: IngotId<'db>, } -impl TraitEnv { - fn collect(db: &dyn HirAnalysisDb, ingot: IngotId) -> Self { +impl<'db> TraitEnv<'db> { + fn collect(db: &dyn HirAnalysisDb, ingot: IngotId<'db>) -> Self { let mut impls: FxHashMap<_, Vec>> = FxHashMap::default(); let mut hir_to_implementor: FxHashMap> = FxHashMap::default(); @@ -171,36 +174,36 @@ impl TraitEnv { /// Represents an implementor of a trait, which can be thought of as a lowered /// `impl Trait`. #[salsa::interned] -pub(crate) struct Implementor { +pub(crate) struct Implementor<'db> { /// The trait that this implementor implements. - pub(crate) trait_: TraitInstId, + pub(crate) trait_: TraitInstId<'db>, /// The type parameters of this implementor. #[return_ref] - pub(crate) params: Vec, + pub(crate) params: Vec>, /// The original hir. - pub(crate) hir_impl_trait: ImplTrait, + pub(crate) hir_impl_trait: ImplTrait<'db>, } -impl Implementor { +impl<'db> Implementor<'db> { /// Returns the trait definition that this implementor implements. - pub(crate) fn trait_def(self, db: &dyn HirAnalysisDb) -> TraitDef { + pub(crate) fn trait_def(self, db: &'db dyn HirAnalysisDb) -> TraitDef<'db> { self.trait_(db).def(db) } - pub(crate) fn original_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub(crate) fn original_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.params(db) } /// The self type of the impl trait. - pub(crate) fn self_ty(self, db: &dyn HirAnalysisDb) -> TyId { + pub(crate) fn self_ty(self, db: &'db dyn HirAnalysisDb) -> TyId<'db> { self.trait_(db).self_ty(db) } /// Returns the constraints that the implementor requires when the /// implementation is selected. - pub(super) fn constraints(self, db: &dyn HirAnalysisDb) -> PredicateListId { + pub(super) fn constraints(self, db: &'db dyn HirAnalysisDb) -> PredicateListId<'db> { collect_implementor_constraints(db, self).instantiate(db, self.params(db)) } @@ -225,13 +228,13 @@ pub(super) fn does_impl_trait_conflict( /// Represents an instantiated trait, which can be thought of as a trait /// reference from a HIR perspective. #[salsa::interned] -pub struct TraitInstId { - pub def: TraitDef, +pub struct TraitInstId<'db> { + pub def: TraitDef<'db>, #[return_ref] - pub args: Vec, + pub args: Vec>, } -impl TraitInstId { +impl<'db> TraitInstId<'db> { pub fn pretty_print(self, db: &dyn HirAnalysisDb, as_pred: bool) -> String { if as_pred { let inst = self.pretty_print(db, false); @@ -258,20 +261,20 @@ impl TraitInstId { } } - pub fn self_ty(self, db: &dyn HirAnalysisDb) -> TyId { + pub fn self_ty(self, db: &'db dyn HirAnalysisDb) -> TyId<'db> { self.args(db)[0] } - pub(super) fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { + pub(super) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> { self.def(db).ingot(db) } pub(super) fn emit_sat_diag( self, - db: &dyn HirAnalysisDb, - assumptions: PredicateListId, - span: DynLazySpan, - ) -> Option { + db: &'db dyn HirAnalysisDb, + assumptions: PredicateListId<'db>, + span: DynLazySpan<'db>, + ) -> Option> { if let WellFormedness::IllFormed { goal, subgoal } = check_trait_inst_wf(db, self, assumptions) { @@ -284,32 +287,32 @@ impl TraitInstId { /// Represents a trait definition. #[salsa::tracked] -pub struct TraitDef { - pub trait_: Trait, +pub struct TraitDef<'db> { + pub trait_: Trait<'db>, #[return_ref] - pub(crate) param_set: GenericParamTypeSet, + pub(crate) param_set: GenericParamTypeSet<'db>, #[return_ref] - pub methods: BTreeMap, + pub methods: BTreeMap, TraitMethod<'db>>, } -impl TraitDef { - pub fn params(self, db: &dyn HirAnalysisDb) -> &[TyId] { +impl<'db> TraitDef<'db> { + pub fn params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.param_set(db).params(db) } - pub fn self_param(self, db: &dyn HirAnalysisDb) -> TyId { + pub fn self_param(self, db: &dyn HirAnalysisDb) -> TyId<'db> { self.param_set(db).trait_self(db).unwrap() } - pub fn original_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub fn original_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { self.param_set(db).explicit_params(db) } } #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] -pub struct TraitMethod(pub FuncDef); +pub struct TraitMethod<'db>(pub FuncDef<'db>); -impl TraitMethod { +impl<'db> TraitMethod<'db> { pub fn has_default_impl(self, db: &dyn HirAnalysisDb) -> bool { self.0 .hir_func_def(db) @@ -319,24 +322,24 @@ impl TraitMethod { } } -impl TraitDef { +impl<'db> TraitDef<'db> { /// Returns the type kind that implementor type must have. - pub(crate) fn expected_implementor_kind(self, db: &dyn HirAnalysisDb) -> &Kind { + pub(crate) fn expected_implementor_kind(self, db: &'db dyn HirAnalysisDb) -> &Kind { self.self_param(db).kind(db) } /// Returns `ingot` in which this trait is defined. - pub(crate) fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { + pub(crate) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId { let hir_db = db.as_hir_db(); self.trait_(db).top_mod(hir_db).ingot(hir_db) } - pub(super) fn super_traits(self, db: &dyn HirAnalysisDb) -> &BTreeSet> { + pub(super) fn super_traits(self, db: &'db dyn HirAnalysisDb) -> &BTreeSet> { const _EMPTY: &BTreeSet> = &BTreeSet::new(); collect_super_traits(db, self).as_ref().unwrap_or(_EMPTY) } - fn name(self, db: &dyn HirAnalysisDb) -> Option<&str> { + fn name(self, db: &'db dyn HirAnalysisDb) -> Option<&'db str> { self.trait_(db) .name(db.as_hir_db()) .to_opt() diff --git a/crates/hir-analysis/src/ty/trait_lower.rs b/crates/hir-analysis/src/ty/trait_lower.rs index 5445e472c..3f78fb68a 100644 --- a/crates/hir-analysis/src/ty/trait_lower.rs +++ b/crates/hir-analysis/src/ty/trait_lower.rs @@ -22,10 +22,10 @@ use crate::{ HirAnalysisDb, }; -type TraitImplTable = FxHashMap>>; +type TraitImplTable<'db> = FxHashMap, Vec>>>; #[salsa::tracked] -pub(crate) fn lower_trait(db: &dyn HirAnalysisDb, trait_: Trait) -> TraitDef { +pub(crate) fn lower_trait<'db>(db: &'db dyn HirAnalysisDb, trait_: Trait<'db>) -> TraitDef<'db> { TraitBuilder::new(db, trait_).build() } @@ -35,7 +35,10 @@ pub(crate) fn lower_trait(db: &dyn HirAnalysisDb, trait_: Trait) -> TraitDef { /// available implementors in the ingot, please use /// [`TraitEnv`](super::trait_def::TraitEnv). #[salsa::tracked(return_ref)] -pub(crate) fn collect_trait_impls(db: &dyn HirAnalysisDb, ingot: IngotId) -> TraitImplTable { +pub(crate) fn collect_trait_impls<'db>( + db: &'db dyn HirAnalysisDb, + ingot: IngotId<'db>, +) -> TraitImplTable<'db> { let const_impls = ingot .external_ingots(db.as_hir_db()) .iter() @@ -50,10 +53,10 @@ pub(crate) fn collect_trait_impls(db: &dyn HirAnalysisDb, ingot: IngotId) -> Tra /// If the implementor type or the trait reference is ill-formed, returns /// `None`. #[salsa::tracked] -pub(crate) fn lower_impl_trait( - db: &dyn HirAnalysisDb, - impl_trait: ImplTrait, -) -> Option> { +pub(crate) fn lower_impl_trait<'db>( + db: &'db dyn HirAnalysisDb, + impl_trait: ImplTrait<'db>, +) -> Option>> { let hir_db = db.as_hir_db(); let scope = impl_trait.scope(); @@ -87,12 +90,12 @@ pub(crate) fn lower_impl_trait( /// Lower a trait reference to a trait instance. #[salsa::tracked] -pub(crate) fn lower_trait_ref( - db: &dyn HirAnalysisDb, - self_ty: TyId, - trait_ref: TraitRefId, - scope: ScopeId, -) -> Result { +pub(crate) fn lower_trait_ref<'db>( + db: &'db dyn HirAnalysisDb, + self_ty: TyId<'db>, + trait_ref: TraitRefId<'db>, + scope: ScopeId<'db>, +) -> Result, TraitRefLowerError<'db>> { let hir_db = db.as_hir_db(); let mut args = vec![self_ty]; @@ -179,10 +182,10 @@ pub(crate) fn lower_trait_ref( } #[salsa::tracked(return_ref)] -pub(crate) fn collect_implementor_methods( - db: &dyn HirAnalysisDb, - implementor: Implementor, -) -> BTreeMap { +pub(crate) fn collect_implementor_methods<'db>( + db: &'db dyn HirAnalysisDb, + implementor: Implementor<'db>, +) -> BTreeMap, FuncDef<'db>> { let mut methods = BTreeMap::default(); for method in implementor.hir_impl_trait(db).methods(db.as_hir_db()) { @@ -195,22 +198,22 @@ pub(crate) fn collect_implementor_methods( } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(crate) enum TraitRefLowerError { +pub(crate) enum TraitRefLowerError<'db> { /// The trait reference contains an associated type, which is not supported /// yet. - AssocTy(PathId), + AssocTy(PathId<'db>), /// The number of arguments doesn't match the number of parameters. ArgNumMismatch { expected: usize, given: usize }, /// The kind of the argument doesn't match the kind of the parameter of the /// trait. - ArgKindMisMatch { expected: Kind, given: TyId }, + ArgKindMisMatch { expected: Kind, given: TyId<'db> }, /// The argument type doesn't match the const parameter type. ArgTypeMismatch { - expected: Option, - given: Option, + expected: Option>, + given: Option>, }, /// Other errors, which is reported by another pass. So we don't need to @@ -220,13 +223,13 @@ pub(crate) enum TraitRefLowerError { struct TraitBuilder<'db> { db: &'db dyn HirAnalysisDb, - trait_: Trait, - param_set: GenericParamTypeSet, - methods: BTreeMap, + trait_: Trait<'db>, + param_set: GenericParamTypeSet<'db>, + methods: BTreeMap, TraitMethod<'db>>, } impl<'db> TraitBuilder<'db> { - fn new(db: &'db dyn HirAnalysisDb, trait_: Trait) -> Self { + fn new(db: &'db dyn HirAnalysisDb, trait_: Trait<'db>) -> Self { let params_owner_id = GenericParamOwnerId::new(db, trait_.into()); let param_set = collect_generic_params(db, params_owner_id); @@ -238,7 +241,7 @@ impl<'db> TraitBuilder<'db> { } } - fn build(mut self) -> TraitDef { + fn build(mut self) -> TraitDef<'db> { self.collect_params(); self.collect_methods(); @@ -269,8 +272,8 @@ impl<'db> TraitBuilder<'db> { /// Collect all implementors in an ingot. struct ImplementorCollector<'db> { db: &'db dyn HirAnalysisDb, - impl_table: TraitImplTable, - const_impl_maps: Vec<&'db TraitImplTable>, + impl_table: TraitImplTable<'db>, + const_impl_maps: Vec<&'db TraitImplTable<'db>>, } impl<'db> ImplementorCollector<'db> { @@ -282,7 +285,7 @@ impl<'db> ImplementorCollector<'db> { } } - fn collect(mut self, impl_traits: &[ImplTrait]) -> TraitImplTable { + fn collect(mut self, impl_traits: &[ImplTrait<'db>]) -> TraitImplTable<'db> { for &impl_ in impl_traits { let Some(implementor) = lower_impl_trait(self.db, impl_) else { continue; diff --git a/crates/hir-analysis/src/ty/trait_resolution/mod.rs b/crates/hir-analysis/src/ty/trait_resolution/mod.rs index b1da8344e..b3df79118 100644 --- a/crates/hir-analysis/src/ty/trait_resolution/mod.rs +++ b/crates/hir-analysis/src/ty/trait_resolution/mod.rs @@ -24,11 +24,11 @@ pub(crate) mod constraint; mod proof_forest; #[salsa::tracked(return_ref)] -pub fn is_goal_satisfiable( - db: &dyn HirAnalysisDb, - assumptions: PredicateListId, - goal: Canonical, -) -> GoalSatisfiability { +pub fn is_goal_satisfiable<'db>( + db: &'db dyn HirAnalysisDb, + assumptions: PredicateListId<'db>, + goal: Canonical>, +) -> GoalSatisfiability<'db> { let flags = collect_flags(db, goal.value); if flags.contains(TyFlags::HAS_INVALID) { return GoalSatisfiability::ContainsInvalid; @@ -40,11 +40,11 @@ pub fn is_goal_satisfiable( /// Checks if the given type is well-formed, i.e., the arguments of the given /// type applications satisfies the constraints under the given assumptions. #[salsa::tracked] -pub(crate) fn check_ty_wf( - db: &dyn HirAnalysisDb, - ty: TyId, - assumptions: PredicateListId, -) -> WellFormedness { +pub(crate) fn check_ty_wf<'db>( + db: &'db dyn HirAnalysisDb, + ty: TyId<'db>, + assumptions: PredicateListId<'db>, +) -> WellFormedness<'db> { let (_, args) = ty.decompose_ty_app(db); for &arg in args { @@ -73,15 +73,15 @@ pub(crate) fn check_ty_wf( } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum WellFormedness { +pub(crate) enum WellFormedness<'db> { WellFormed, IllFormed { - goal: TraitInstId, - subgoal: Option, + goal: TraitInstId<'db>, + subgoal: Option>, }, } -impl WellFormedness { +impl<'db> WellFormedness<'db> { fn is_wf(self) -> bool { matches!(self, WellFormedness::WellFormed) } @@ -90,11 +90,11 @@ impl WellFormedness { /// Checks if the given trait instance are well-formed, i.e., the arguments of /// the trait satisfies all constraints under the given assumptions. #[salsa::tracked] -pub(crate) fn check_trait_inst_wf( - db: &dyn HirAnalysisDb, - trait_inst: TraitInstId, - assumptions: PredicateListId, -) -> WellFormedness { +pub(crate) fn check_trait_inst_wf<'db>( + db: &'db dyn HirAnalysisDb, + trait_inst: TraitInstId<'db>, + assumptions: PredicateListId<'db>, +) -> WellFormedness<'db> { let constraints = collect_trait_constraints(db, trait_inst.def(db)).instantiate(db, trait_inst.args(db)); @@ -114,12 +114,12 @@ pub(crate) fn check_trait_inst_wf( } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum GoalSatisfiability { +pub enum GoalSatisfiability<'db> { /// Goal is satisfied with the unique solution. - Satisfied(Solution), + Satisfied(Solution>), /// Goal might be satisfied, but needs more type information to determine /// satisfiability and uniqueness. - NeedsConfirmation(BTreeSet>), + NeedsConfirmation(BTreeSet>>), /// Goal contains invalid. ContainsInvalid, @@ -139,14 +139,14 @@ impl GoalSatisfiability { } #[salsa::interned] -pub struct PredicateListId { +pub struct PredicateListId<'db> { #[return_ref] - pub list: BTreeSet, - pub ingot: IngotId, + pub list: BTreeSet>, + pub ingot: IngotId<'db>, } -impl PredicateListId { - pub(super) fn merge(self, db: &dyn HirAnalysisDb, other: Self) -> Self { +impl<'db> PredicateListId<'db> { + pub(super) fn merge(self, db: &'db dyn HirAnalysisDb, other: Self) -> Self { let mut predicates = self.list(db).clone(); predicates.extend(other.list(db)); PredicateListId::new(db, predicates, self.ingot(db)) @@ -156,7 +156,7 @@ impl PredicateListId { Self::new(db, BTreeSet::new(), IngotId::dummy()) } - fn extend_by_super(self, db: &dyn HirAnalysisDb) -> Self { + fn extend_by_super(self, db: &'db dyn HirAnalysisDb) -> Self { let mut list = self.list(db).clone(); for &pred in self.list(db) { for &super_trait in pred.def(db).super_traits(db).iter() { diff --git a/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs b/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs index d37c58fcc..27e6193aa 100644 --- a/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs +++ b/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs @@ -33,8 +33,8 @@ const MAXIMUM_TYPE_DEPTH: usize = 256; /// Since `TraitInstId` contains `Self` type as its first argument, /// the query for `Implements>` is represented as /// `Trait`. -type Goal = Canonical; -type Solution = crate::ty::canonical::Solution; +type Goal<'db> = Canonical>; +type Solution<'db> = crate::ty::canonical::Solution>; /// A structure representing a proof forest used for solving trait goals. /// @@ -57,13 +57,13 @@ pub(super) struct ProofForest<'db> { /// This heap stores tuples of [`OrderedConsumerNode`] and [`Solution`], /// allowing the solver to efficiently retrieve and prioritize /// consumer nodes that are closer to the original goal. - c_heap: BinaryHeap<(OrderedConsumerNode, Solution)>, + c_heap: BinaryHeap<(OrderedConsumerNode, Solution<'db>)>, /// A mapping from goals to generator nodes. - goal_to_node: FxHashMap, + goal_to_node: FxHashMap, GeneratorNode>, /// The list of assumptions. - assumptions: PredicateListId, + assumptions: PredicateListId<'db>, /// The maximum number of solutions. maximum_solution_num: usize, @@ -113,7 +113,7 @@ impl<'db> ProofForest<'db> { pub(super) fn new( db: &'db dyn HirAnalysisDb, goal: Goal, - assumptions: PredicateListId, + assumptions: PredicateListId<'db>, ) -> Self { let assumptions = assumptions.extend_by_super(db); @@ -150,7 +150,7 @@ impl<'db> ProofForest<'db> { /// - `UnSat` if no solutions are found and an unresolved subgoal is /// identified. /// - `NeedsConfirmation` if multiple solutions are found. - pub(super) fn solve(mut self) -> GoalSatisfiability { + pub(super) fn solve(mut self) -> GoalSatisfiability<'db> { loop { if self.g_nodes[self.root].solutions.len() >= self.maximum_solution_num { break; @@ -253,17 +253,17 @@ impl<'db> ProofForest<'db> { struct GeneratorNodeData<'db> { table: PersistentUnificationTable<'db>, /// The canonical goal associated with the generator node. - goal: Goal, + goal: Goal<'db>, /// The trait instance extracted from the goal. - extracted_goal: TraitInstId, + extracted_goal: TraitInstId<'db>, /// A set of solutions found for the goal. - solutions: BTreeSet, + solutions: BTreeSet>, /// A list of consumer nodes that depend on this generator node. dependents: Vec, /// A list of candidate implementors for the trait. - cands: &'db [Binder], + cands: &'db [Binder>], /// The list of assumptions for the goal. - assumptions: PredicateListId, + assumptions: PredicateListId<'db>, /// The index of the next candidate to be tried. next_cand: usize, /// A list of child consumer nodes created for sub-goals. diff --git a/crates/hir-analysis/src/ty/ty_check/env.rs b/crates/hir-analysis/src/ty/ty_check/env.rs index 08a4fe731..c7daa2e77 100644 --- a/crates/hir-analysis/src/ty/ty_check/env.rs +++ b/crates/hir-analysis/src/ty/ty_check/env.rs @@ -324,8 +324,8 @@ impl BlockEnv { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct ExprProp { - pub ty: TyId, +pub struct ExprProp<'db> { + pub ty: TyId<'db>, pub is_mut: bool, pub(crate) binding: Option, } @@ -365,9 +365,16 @@ impl ExprProp { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) enum LocalBinding { - Local { pat: PatId, is_mut: bool }, - Param { idx: usize, ty: TyId, is_mut: bool }, +pub(crate) enum LocalBinding<'db> { + Local { + pat: PatId, + is_mut: bool, + }, + Param { + idx: usize, + ty: TyId<'db>, + is_mut: bool, + }, } impl LocalBinding { diff --git a/crates/hir-analysis/src/ty/ty_check/expr.rs b/crates/hir-analysis/src/ty/ty_check/expr.rs index 8f0477842..0585d698c 100644 --- a/crates/hir-analysis/src/ty/ty_check/expr.rs +++ b/crates/hir-analysis/src/ty/ty_check/expr.rs @@ -913,25 +913,25 @@ impl<'db> TyChecker<'db> { /// TODO: We need to refine this trait definition to connect std library traits /// smoothly. pub(crate) trait TraitOps { - fn trait_path(&self, db: &dyn HirAnalysisDb) -> PathId { + fn trait_path<'db>(&self, db: &'db dyn HirAnalysisDb) -> PathId<'db> { let hir_db = db.as_hir_db(); let path = std_ops_path(db); path.push(hir_db, self.trait_name(db)) } - fn trait_name(&self, db: &dyn HirAnalysisDb) -> IdentId { + fn trait_name<'db>(&self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> { self.triple(db)[0] } - fn op_symbol(&self, db: &dyn HirAnalysisDb) -> IdentId { + fn op_symbol<'db>(&self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> { self.triple(db)[2] } - fn triple(&self, db: &dyn HirAnalysisDb) -> [IdentId; 3]; + fn triple<'db>(&self, db: &'db dyn HirAnalysisDb) -> [IdentId<'db>; 3]; } impl TraitOps for UnOp { - fn triple(&self, db: &dyn HirAnalysisDb) -> [IdentId; 3] { + fn triple<'db>(&self, db: &'db dyn HirAnalysisDb) -> [IdentId<'db>; 3] { let triple = match self { UnOp::Plus => ["UnaryPlus", "add", "+"], UnOp::Minus => ["Neg", "neg", "-"], @@ -944,7 +944,7 @@ impl TraitOps for UnOp { } impl TraitOps for BinOp { - fn triple(&self, db: &dyn HirAnalysisDb) -> [IdentId; 3] { + fn triple<'db>(&self, db: &'db dyn HirAnalysisDb) -> [IdentId<'db>; 3] { let triple = match self { BinOp::Arith(arith_op) => { use ArithBinOp::*; @@ -995,7 +995,7 @@ impl TraitOps for BinOp { struct IndexingOp {} impl TraitOps for IndexingOp { - fn triple(&self, db: &dyn HirAnalysisDb) -> [IdentId; 3] { + fn triple<'db>(&self, db: &'db dyn HirAnalysisDb) -> [IdentId<'db>; 3] { let name = "Index"; let method_name = "index"; let symbol = "[]"; @@ -1011,7 +1011,7 @@ impl TraitOps for IndexingOp { struct AugAssignOp(ArithBinOp); impl TraitOps for AugAssignOp { - fn triple(&self, db: &dyn HirAnalysisDb) -> [IdentId; 3] { + fn triple<'db>(&self, db: &'db dyn HirAnalysisDb) -> [IdentId<'db>; 3] { use ArithBinOp::*; let triple = match self.0 { Add => ["AddAssign", "add_assign", "+="], diff --git a/crates/hir-analysis/src/ty/ty_def.rs b/crates/hir-analysis/src/ty/ty_def.rs index e3bab756a..e771156d7 100644 --- a/crates/hir-analysis/src/ty/ty_def.rs +++ b/crates/hir-analysis/src/ty/ty_def.rs @@ -6,7 +6,6 @@ use bitflags::bitflags; use common::input::IngotKind; use hir::{ hir_def::{ - kw, prim_ty::{IntTy as HirIntTy, PrimTy as HirPrimTy, UintTy as HirUintTy}, Body, IdentId, IngotId, IntegerId, TypeAlias as HirTypeAlias, }, @@ -26,21 +25,21 @@ use super::{ use crate::{ty::trait_resolution::check_ty_wf, HirAnalysisDb}; #[salsa::interned] -pub struct TyId { +pub struct TyId<'db> { #[return_ref] - pub data: TyData, + pub data: TyData<'db>, } -impl TyId { +impl<'db> TyId<'db> { /// Returns the kind of the type. - pub fn kind(self, db: &dyn HirAnalysisDb) -> &Kind { + pub fn kind(self, db: &'db dyn HirAnalysisDb) -> &'db Kind { ty_kind(db, self) } /// Returns the current arguments of the type. /// ## Example /// Calling this method for `TyApp, U>` returns `[T, U]`. - pub fn generic_args(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub fn generic_args(self, db: &'db dyn HirAnalysisDb) -> &[Self] { let (_, args) = self.decompose_ty_app(db); args } @@ -49,12 +48,12 @@ impl TyId { /// ## Example /// `TyApp` returns `Adt`. /// `TyApp, i32>` returns `TyParam`. - pub fn base_ty(self, db: &dyn HirAnalysisDb) -> TyId { + pub fn base_ty(self, db: &'db dyn HirAnalysisDb) -> Self { self.decompose_ty_app(db).0 } /// Returns the type of const type if the type is a const type. - pub fn const_ty_ty(self, db: &dyn HirAnalysisDb) -> Option { + pub fn const_ty_ty(self, db: &'db dyn HirAnalysisDb) -> Option { match self.data(db) { TyData::ConstTy(const_ty) => Some(const_ty.ty(db)), _ => None, @@ -91,7 +90,7 @@ impl TyId { } /// Returns `IngotId` that declares the type. - pub fn ingot(self, db: &dyn HirAnalysisDb) -> Option { + pub fn ingot(self, db: &'db dyn HirAnalysisDb) -> Option> { match self.data(db) { TyData::TyBase(TyBase::Adt(adt)) => adt.ingot(db).into(), TyData::TyBase(TyBase::Func(def)) => def.ingot(db).into(), @@ -100,7 +99,7 @@ impl TyId { } } - pub fn invalid_cause(self, db: &dyn HirAnalysisDb) -> Option { + pub fn invalid_cause(self, db: &'db dyn HirAnalysisDb) -> Option> { match self.data(db) { TyData::Invalid(cause) => Some(cause.clone()), _ => None, @@ -128,7 +127,7 @@ impl TyId { !matches!(self.kind(db), Kind::Abs(_, _)) } - pub fn pretty_print(self, db: &dyn HirAnalysisDb) -> &str { + pub fn pretty_print(self, db: &'db dyn HirAnalysisDb) -> &str { pretty_print_ty(db, self) } @@ -147,20 +146,20 @@ impl TyId { /// Decompose type application into the base type and type arguments, this /// doesn't perform deconstruction recursively. e.g., /// `App(App(T, U), App(V, W))` -> `(T, [U, App(V, W)])` - pub(super) fn decompose_ty_app(self, db: &dyn HirAnalysisDb) -> (TyId, &[TyId]) { + pub(super) fn decompose_ty_app(self, db: &'db dyn HirAnalysisDb) -> (TyId<'db>, &[TyId<'db>]) { let (base, args) = decompose_ty_app(db, self); (*base, args) } - pub(super) fn ptr(db: &dyn HirAnalysisDb) -> TyId { + pub(super) fn ptr(db: &'db dyn HirAnalysisDb) -> TyId<'db> { Self::new(db, TyData::TyBase(TyBase::Prim(PrimTy::Ptr))) } - pub(super) fn tuple(db: &dyn HirAnalysisDb, n: usize) -> Self { + pub(super) fn tuple(db: &'db dyn HirAnalysisDb, n: usize) -> Self { Self::new(db, TyData::TyBase(TyBase::tuple(n))) } - pub(super) fn tuple_with_elems(db: &dyn HirAnalysisDb, elems: &[TyId]) -> Self { + pub(super) fn tuple_with_elems(db: &'db dyn HirAnalysisDb, elems: &[TyId<'db>]) -> Self { let base = TyBase::tuple(elems.len()); let mut ty = Self::new(db, TyData::TyBase(base)); for &elem in elems { @@ -169,16 +168,16 @@ impl TyId { ty } - pub(super) fn bool(db: &dyn HirAnalysisDb) -> Self { + pub(super) fn bool(db: &'db dyn HirAnalysisDb) -> Self { Self::new(db, TyData::TyBase(TyBase::Prim(PrimTy::Bool))) } - pub(super) fn array(db: &dyn HirAnalysisDb) -> Self { + pub(super) fn array(db: &'db dyn HirAnalysisDb) -> Self { let base = TyBase::Prim(PrimTy::Array); Self::new(db, TyData::TyBase(base)) } - pub(super) fn array_with_elem(db: &dyn HirAnalysisDb, elem: TyId, len: usize) -> Self { + pub(super) fn array_with_elem(db: &'db dyn HirAnalysisDb, elem: TyId<'db>, len: usize) -> Self { let base = TyBase::Prim(PrimTy::Array); let base = Self::new(db, TyData::TyBase(base)); let array = TyId::app(db, base, elem); @@ -190,23 +189,23 @@ impl TyId { TyId::app(db, array, len) } - pub(super) fn unit(db: &dyn HirAnalysisDb) -> Self { + pub(super) fn unit(db: &'db dyn HirAnalysisDb) -> Self { Self::tuple(db, 0) } - pub(super) fn never(db: &dyn HirAnalysisDb) -> Self { + pub(super) fn never(db: &'db dyn HirAnalysisDb) -> Self { Self::new(db, TyData::Never) } - pub(super) fn const_ty(db: &dyn HirAnalysisDb, const_ty: ConstTyId) -> Self { + pub(super) fn const_ty(db: &'db dyn HirAnalysisDb, const_ty: ConstTyId<'db>) -> Self { Self::new(db, TyData::ConstTy(const_ty)) } - pub(super) fn adt(db: &dyn HirAnalysisDb, adt: AdtDef) -> Self { + pub(super) fn adt(db: &'db dyn HirAnalysisDb, adt: AdtDef<'db>) -> Self { Self::new(db, TyData::TyBase(TyBase::Adt(adt))) } - pub(super) fn func(db: &dyn HirAnalysisDb, func: FuncDef) -> Self { + pub(super) fn func(db: &'db dyn HirAnalysisDb, func: FuncDef<'db>) -> Self { Self::new(db, TyData::TyBase(TyBase::Func(func))) } @@ -263,13 +262,13 @@ impl TyId { /// Emit diagnostics for the type if the type contains invalid types. pub(super) fn emit_diag( self, - db: &dyn HirAnalysisDb, - span: DynLazySpan, - ) -> Option { + db: &'db dyn HirAnalysisDb, + span: DynLazySpan<'db>, + ) -> Option> { struct EmitDiagVisitor<'db> { db: &'db dyn HirAnalysisDb, - diag: Option, - span: DynLazySpan, + diag: Option>, + span: DynLazySpan<'db>, } impl<'db> TyVisitor<'db> for EmitDiagVisitor<'db> { @@ -345,10 +344,10 @@ impl TyId { pub(super) fn emit_wf_diag( self, - db: &dyn HirAnalysisDb, - assumptions: PredicateListId, - span: DynLazySpan, - ) -> Option { + db: &'db dyn HirAnalysisDb, + assumptions: PredicateListId<'db>, + span: DynLazySpan<'db>, + ) -> Option> { if let WellFormedness::IllFormed { goal, subgoal } = check_ty_wf(db, self, assumptions) { Some(TraitConstraintDiag::trait_bound_not_satisfied(db, span, goal, subgoal).into()) } else { @@ -357,7 +356,7 @@ impl TyId { } pub(super) fn ty_var( - db: &dyn HirAnalysisDb, + db: &'db dyn HirAnalysisDb, sort: TyVarSort, kind: Kind, key: InferenceKey, @@ -365,7 +364,11 @@ impl TyId { Self::new(db, TyData::TyVar(TyVar { sort, kind, key })) } - pub(super) fn const_ty_var(db: &dyn HirAnalysisDb, ty: TyId, key: InferenceKey) -> Self { + pub(super) fn const_ty_var( + db: &'db dyn HirAnalysisDb, + ty: TyId<'db>, + key: InferenceKey, + ) -> Self { let ty_var = TyVar { sort: TyVarSort::General, kind: ty.kind(db).clone(), @@ -377,7 +380,7 @@ impl TyId { } /// Perform type level application. - pub(super) fn app(db: &dyn HirAnalysisDb, lhs: Self, rhs: Self) -> TyId { + pub(super) fn app(db: &'db dyn HirAnalysisDb, lhs: Self, rhs: Self) -> TyId<'db> { let Some(applicable_ty) = lhs.applicable_ty(db) else { return Self::invalid(db, InvalidCause::kind_mismatch(None, rhs)); }; @@ -410,15 +413,15 @@ impl TyId { self.is_ptr(db) } - pub(super) fn invalid(db: &dyn HirAnalysisDb, cause: InvalidCause) -> Self { + pub(super) fn invalid(db: &'db dyn HirAnalysisDb, cause: InvalidCause<'db>) -> Self { Self::new(db, TyData::Invalid(cause)) } - pub(super) fn from_hir_prim_ty(db: &dyn HirAnalysisDb, hir_prim: HirPrimTy) -> Self { + pub(super) fn from_hir_prim_ty(db: &'db dyn HirAnalysisDb, hir_prim: HirPrimTy) -> Self { Self::new(db, TyData::TyBase(hir_prim.into())) } - pub(super) fn const_ty_param(self, db: &dyn HirAnalysisDb) -> Option { + pub(super) fn const_ty_param(self, db: &'db dyn HirAnalysisDb) -> Option> { if let TyData::ConstTy(const_ty) = self.data(db) { Some(const_ty.ty(db)) } else { @@ -428,9 +431,9 @@ impl TyId { pub(super) fn evaluate_const_ty( self, - db: &dyn HirAnalysisDb, - expected_ty: Option, - ) -> Result { + db: &'db dyn HirAnalysisDb, + expected_ty: Option>, + ) -> Result, InvalidCause<'db>> { match (expected_ty, self.data(db)) { (Some(expected_const_ty), TyData::ConstTy(const_ty)) => { if expected_const_ty.has_invalid(db) { @@ -468,7 +471,7 @@ impl TyId { } /// Returns the property of the type that can be applied to the `self`. - pub fn applicable_ty(self, db: &dyn HirAnalysisDb) -> Option { + pub fn applicable_ty(self, db: &'db dyn HirAnalysisDb) -> Option { let applicable_kind = match self.kind(db) { Kind::Star => return None, Kind::Abs(arg, _) => *arg.clone(), @@ -523,34 +526,34 @@ impl TyId { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ApplicableTyProp { +pub struct ApplicableTyProp<'db> { /// A kind of the applicable type. pub kind: Kind, /// An expected type of const type if the applicable type is a const type. - pub const_ty: Option, + pub const_ty: Option>, } #[salsa::tracked(return_ref)] -pub fn ty_kind(db: &dyn HirAnalysisDb, ty: TyId) -> Kind { +pub fn ty_kind<'db>(db: &'db dyn HirAnalysisDb, ty: TyId<'db>) -> Kind { ty.data(db).kind(db) } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TyData { +pub enum TyData<'db> { /// Type variable. - TyVar(TyVar), + TyVar(TyVar<'db>), /// Type Parameter. - TyParam(TyParam), + TyParam(TyParam<'db>), // Type application, // e.g., `Option` is represented as `TApp(TyConst(Option), TyConst(i32))`. - TyApp(TyId, TyId), + TyApp(TyId<'db>, TyId<'db>), /// A concrete type, e.g., `i32`, `u32`, `bool`, `String`, `Result` etc. - TyBase(TyBase), + TyBase(TyBase<'db>), - ConstTy(ConstTyId), + ConstTy(ConstTyId<'db>), /// A never(bottom) type. Never, @@ -558,47 +561,47 @@ pub enum TyData { // Invalid type which means the type is ill-formed. // This type can be unified with any other types. // NOTE: For type soundness check in this level, we don't consider trait satisfiability. - Invalid(InvalidCause), + Invalid(InvalidCause<'db>), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum InvalidCause { +pub enum InvalidCause<'db> { /// Type is not fully applied where it is required. NotFullyApplied, /// Kind mismatch between two types. KindMismatch { expected: Option, - given: TyId, + given: TyId<'db>, }, InvalidConstParamTy { - ty: TyId, + ty: TyId<'db>, }, RecursiveConstParamTy, /// The given type doesn't match the expected const type. ConstTyMismatch { - expected: TyId, - given: TyId, + expected: TyId<'db>, + given: TyId<'db>, }, /// The given type is not a const type where it is required. ConstTyExpected { - expected: TyId, + expected: TyId<'db>, }, /// The given type is const type where it is *NOT* required. NormalTypeExpected { - given: TyId, + given: TyId<'db>, }, /// Type alias parameter is not bound. /// NOTE: In our type system, type alias is a macro, so we can't perform /// partial application to type alias. UnboundTypeAliasParam { - alias: HirTypeAlias, + alias: HirTypeAlias<'db>, n_given_args: usize, }, @@ -609,7 +612,7 @@ pub enum InvalidCause { // TODO: Remove this error kind and introduce a new error kind for more specific cause when // type inference is implemented. InvalidConstTyExpr { - body: Body, + body: Body<'db>, }, // TraitConstraintNotSat(PredicateId), @@ -618,8 +621,8 @@ pub enum InvalidCause { Other, } -impl InvalidCause { - pub(super) fn kind_mismatch(expected: Option<&Kind>, ty: TyId) -> Self { +impl<'db> InvalidCause<'db> { + pub(super) fn kind_mismatch(expected: Option<&Kind>, ty: TyId<'db>) -> Self { Self::KindMismatch { expected: expected.cloned(), given: ty, @@ -670,18 +673,18 @@ impl fmt::Display for Kind { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TyVar { +pub struct TyVar<'db> { pub sort: TyVarSort, pub kind: Kind, - pub(super) key: InferenceKey, + pub(super) key: InferenceKey<'db>, } -impl std::cmp::PartialOrd for TyVar { +impl<'db> std::cmp::PartialOrd for TyVar<'db> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl std::cmp::Ord for TyVar { +impl<'db> std::cmp::Ord for TyVar<'db> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { if self == other { return std::cmp::Ordering::Equal; @@ -718,7 +721,7 @@ impl PartialOrd for TyVarSort { } } -impl TyVar { +impl<'db> TyVar<'db> { pub(super) fn pretty_print(&self) -> String { match self.sort { TyVarSort::General => ("_").to_string(), @@ -731,8 +734,8 @@ impl TyVar { /// Type generics parameter. We also treat `Self` type in a trait definition as /// a special type parameter. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TyParam { - pub name: IdentId, +pub struct TyParam<'db> { + pub name: IdentId<'db>, // The index points to the lowered type parameter list, which means that the idx doesn't // correspond to the index of the type parameter in the original source code. // E.g., @@ -746,12 +749,12 @@ pub struct TyParam { pub is_trait_self: bool, } -impl TyParam { +impl<'db> TyParam<'db> { pub(super) fn pretty_print(&self, db: &dyn HirAnalysisDb) -> String { self.name.data(db.as_hir_db()).to_string() } - pub(super) fn normal_param(name: IdentId, idx: usize, kind: Kind) -> Self { + pub(super) fn normal_param(name: IdentId<'db>, idx: usize, kind: Kind) -> Self { Self { name, idx, @@ -760,9 +763,9 @@ impl TyParam { } } - pub(super) fn trait_self(kind: Kind) -> Self { + pub(super) fn trait_self(db: &'db dyn HirAnalysisDb, kind: Kind) -> Self { Self { - name: kw::SELF_TY, + name: IdentId::make_self_ty(db.as_hir_db()), idx: 0, kind, is_trait_self: true, @@ -771,13 +774,13 @@ impl TyParam { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, derive_more::From)] -pub enum TyBase { +pub enum TyBase<'db> { Prim(PrimTy), - Adt(AdtDef), - Func(FuncDef), + Adt(AdtDef<'db>), + Func(FuncDef<'db>), } -impl TyBase { +impl<'db> TyBase<'db> { pub fn is_integral(self) -> bool { match self { Self::Prim(prim) => prim.is_integral(), @@ -831,7 +834,7 @@ impl TyBase { } } - pub(super) fn adt(self) -> Option { + pub(super) fn adt(self) -> Option> { match self { Self::Adt(adt) => Some(adt), _ => None, @@ -839,7 +842,7 @@ impl TyBase { } } -impl From for TyBase { +impl<'db> From for TyBase<'db> { fn from(hir_prim: HirPrimTy) -> Self { match hir_prim { HirPrimTy::Bool => Self::Prim(PrimTy::Bool), @@ -922,7 +925,7 @@ pub(super) trait HasKind { fn kind(&self, db: &dyn HirAnalysisDb) -> Kind; } -impl HasKind for TyData { +impl<'db> HasKind for TyData<'db> { fn kind(&self, db: &dyn HirAnalysisDb) -> Kind { match self { TyData::TyVar(ty_var) => ty_var.kind(db), @@ -944,13 +947,13 @@ impl HasKind for TyData { } } -impl HasKind for TyVar { +impl<'db> HasKind for TyVar<'db> { fn kind(&self, _db: &dyn HirAnalysisDb) -> Kind { self.kind.clone() } } -impl HasKind for TyBase { +impl<'db> HasKind for TyBase<'db> { fn kind(&self, db: &dyn HirAnalysisDb) -> Kind { match self { TyBase::Prim(prim) => prim.kind(db), @@ -972,7 +975,7 @@ impl HasKind for PrimTy { } } -impl HasKind for AdtDef { +impl<'db> HasKind for AdtDef<'db> { fn kind(&self, db: &dyn HirAnalysisDb) -> Kind { let mut kind = Kind::Star; for param in self.params(db).iter().rev() { @@ -983,7 +986,7 @@ impl HasKind for AdtDef { } } -impl HasKind for FuncDef { +impl<'db> HasKind for FuncDef<'db> { fn kind(&self, db: &dyn HirAnalysisDb) -> Kind { let mut kind = Kind::Star; for param in self.params(db).iter().rev() { @@ -997,13 +1000,13 @@ impl HasKind for FuncDef { pub(crate) fn collect_variables<'db, V>( db: &'db dyn HirAnalysisDb, visitable: &V, -) -> BTreeSet +) -> BTreeSet> where V: TyVisitable<'db>, { struct TyVarCollector<'db> { db: &'db dyn HirAnalysisDb, - vars: BTreeSet, + vars: BTreeSet>, } impl<'db> TyVisitor<'db> for TyVarCollector<'db> { @@ -1011,7 +1014,7 @@ where self.db } - fn visit_var(&mut self, var: &TyVar) { + fn visit_var(&mut self, var: &TyVar<'db>) { self.vars.insert(var.clone()); } } @@ -1028,13 +1031,13 @@ where pub(crate) fn inference_keys<'db, V>( db: &'db dyn HirAnalysisDb, visitable: &V, -) -> FxHashSet +) -> FxHashSet> where V: TyVisitable<'db>, { struct FreeInferenceKeyCollector<'db> { db: &'db dyn HirAnalysisDb, - keys: FxHashSet, + keys: FxHashSet>, } impl<'db> TyVisitor<'db> for FreeInferenceKeyCollector<'db> { @@ -1042,7 +1045,7 @@ where self.db } - fn visit_var(&mut self, var: &TyVar) { + fn visit_var(&mut self, var: &TyVar<'db>) { self.keys.insert(var.key); } } @@ -1057,7 +1060,7 @@ where } #[salsa::tracked(return_ref)] -pub(crate) fn pretty_print_ty(db: &dyn HirAnalysisDb, ty: TyId) -> String { +pub(crate) fn pretty_print_ty<'db>(db: &'db dyn HirAnalysisDb, ty: TyId<'db>) -> String { match ty.data(db) { TyData::TyVar(var) => var.pretty_print(), TyData::TyParam(param) => param.pretty_print(db), @@ -1069,7 +1072,7 @@ pub(crate) fn pretty_print_ty(db: &dyn HirAnalysisDb, ty: TyId) -> String { } } -fn pretty_print_ty_app(db: &dyn HirAnalysisDb, ty: TyId) -> String { +fn pretty_print_ty_app<'db>(db: &'db dyn HirAnalysisDb, ty: TyId<'db>) -> String { use PrimTy::*; use TyBase::*; @@ -1115,11 +1118,14 @@ fn pretty_print_ty_app(db: &dyn HirAnalysisDb, ty: TyId) -> String { /// Decompose type application into the base type and type arguments. /// e.g., `App(App(T, U), App(V, W))` -> `(T, [U, App(V, W)])` #[salsa::tracked(return_ref)] -pub(crate) fn decompose_ty_app(db: &dyn HirAnalysisDb, ty: TyId) -> (TyId, Vec) { +pub(crate) fn decompose_ty_app<'db>( + db: &'db dyn HirAnalysisDb, + ty: TyId<'db>, +) -> (TyId<'db>, Vec>) { struct TyAppDecomposer<'db> { db: &'db dyn HirAnalysisDb, - base: Option, - args: Vec, + base: Option>, + args: Vec>, } impl<'db> TyVisitor<'db> for TyAppDecomposer<'db> { @@ -1127,7 +1133,7 @@ pub(crate) fn decompose_ty_app(db: &dyn HirAnalysisDb, ty: TyId) -> (TyId, Vec) { let db = self.db; match ty.data(db) { @@ -1160,7 +1166,7 @@ bitflags! { } #[salsa::tracked] -pub(crate) fn ty_flags(db: &dyn HirAnalysisDb, ty: TyId) -> TyFlags { +pub(crate) fn ty_flags<'db>(db: &'db dyn HirAnalysisDb, ty: TyId<'db>) -> TyFlags { struct Collector<'db> { db: &'db dyn HirAnalysisDb, flags: TyFlags, diff --git a/crates/hir-analysis/src/ty/ty_lower.rs b/crates/hir-analysis/src/ty/ty_lower.rs index 54aa9d953..90cd75ccd 100644 --- a/crates/hir-analysis/src/ty/ty_lower.rs +++ b/crates/hir-analysis/src/ty/ty_lower.rs @@ -2,12 +2,11 @@ use std::collections::BTreeSet; use either::Either; use hir::hir_def::{ - kw, scope_graph::ScopeId, GenericArg, GenericArgListId, GenericParam, GenericParamListId, + scope_graph::ScopeId, GenericArg, GenericArgListId, GenericParam, GenericParamListId, GenericParamOwner, IdentId, IngotId, ItemKind, KindBound as HirKindBound, Partial, PathId, TupleTypeId, TypeAlias as HirTypeAlias, TypeBound, TypeId as HirTyId, TypeKind as HirTyKind, WhereClauseId, }; -use salsa::function::Configuration; use super::{ adt_def::{lower_adt, AdtRefId}, @@ -23,34 +22,38 @@ use crate::{ /// Lowers the given HirTy to `TyId`. #[salsa::tracked(recovery_fn=recover_lower_hir_ty_cycle)] -pub fn lower_hir_ty(db: &dyn HirAnalysisDb, ty: HirTyId, scope: ScopeId) -> TyId { +pub fn lower_hir_ty<'db>( + db: &'db dyn HirAnalysisDb, + ty: HirTyId<'db>, + scope: ScopeId<'db>, +) -> TyId<'db> { TyBuilder::new(db, scope).lower_ty(ty) } -fn recover_lower_hir_ty_cycle( - db: &dyn HirAnalysisDb, +fn recover_lower_hir_ty_cycle<'db>( + db: &'db dyn HirAnalysisDb, _cycle: &salsa::Cycle, - _ty: HirTyId, - _scope: ScopeId, -) -> TyId { + _ty: HirTyId<'db>, + _scope: ScopeId<'db>, +) -> TyId<'db> { TyId::invalid(db, InvalidCause::RecursiveConstParamTy) } /// Collects the generic parameters of the given generic parameter owner. #[salsa::tracked] -pub(crate) fn collect_generic_params( - db: &dyn HirAnalysisDb, - owner: GenericParamOwnerId, -) -> GenericParamTypeSet { +pub(crate) fn collect_generic_params<'db>( + db: &'db dyn HirAnalysisDb, + owner: GenericParamOwnerId<'db>, +) -> GenericParamTypeSet<'db> { GenericParamCollector::new(db, owner.data(db)).finalize() } /// Lowers the given type alias to [`TyAlias`]. #[salsa::tracked(return_ref, recovery_fn = recover_lower_type_alias_cycle)] -pub(crate) fn lower_type_alias( - db: &dyn HirAnalysisDb, - alias: HirTypeAlias, -) -> Result { +pub(crate) fn lower_type_alias<'db>( + db: &'db dyn HirAnalysisDb, + alias: HirTypeAlias<'db>, +) -> Result, AliasCycle<'db>> { let param_set = collect_generic_params(db, GenericParamOwnerId::new(db, alias.into())); let Some(hir_ty) = alias.ty(db.as_hir_db()).to_opt() else { @@ -76,10 +79,10 @@ pub(crate) fn lower_type_alias( #[doc(hidden)] #[salsa::tracked(return_ref)] -pub(crate) fn evaluate_params_precursor( - db: &dyn HirAnalysisDb, - set: GenericParamTypeSet, -) -> Vec { +pub(crate) fn evaluate_params_precursor<'db>( + db: &'db dyn HirAnalysisDb, + set: GenericParamTypeSet<'db>, +) -> Vec> { set.params_precursor(db) .iter() .enumerate() @@ -87,11 +90,11 @@ pub(crate) fn evaluate_params_precursor( .collect() } -fn recover_lower_type_alias_cycle( - db: &dyn HirAnalysisDb, +fn recover_lower_type_alias_cycle<'db>( + db: &'db dyn HirAnalysisDb, cycle: &salsa::Cycle, - _alias: HirTypeAlias, -) -> Result { + _alias: HirTypeAlias<'db>, +) -> Result, AliasCycle<'db>> { use once_cell::sync::Lazy; use regex::Regex; @@ -114,14 +117,14 @@ fn recover_lower_type_alias_cycle( } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(crate) struct AliasCycle(BTreeSet); +pub(crate) struct AliasCycle<'db>(BTreeSet>); -impl AliasCycle { - pub(super) fn representative(&self) -> HirTypeAlias { +impl<'db> AliasCycle<'db> { + pub(super) fn representative(&self) -> HirTypeAlias<'db> { *self.0.iter().next().unwrap() } - pub(super) fn participants(&self) -> impl Iterator + '_ { + pub(super) fn participants(&self) -> impl Iterator> + '_ { self.0.iter().skip(1).copied() } } @@ -133,29 +136,29 @@ impl AliasCycle { /// NOTE: `TyAlias` can't become an alias to partial applied types, i.e., the /// right hand side of the alias declaration must be a fully applied type. #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct TyAlias { - alias: HirTypeAlias, - alias_to: Binder, - param_set: GenericParamTypeSet, +pub(crate) struct TyAlias<'db> { + alias: HirTypeAlias<'db>, + alias_to: Binder>, + param_set: GenericParamTypeSet<'db>, } -impl TyAlias { - fn params<'db>(&self, db: &'db dyn HirAnalysisDb) -> &'db [TyId] { +impl<'db> TyAlias<'db> { + fn params(&self, db: &'db dyn HirAnalysisDb) -> &'db [TyId<'db>] { self.param_set.params(db) } } struct TyBuilder<'db> { db: &'db dyn HirAnalysisDb, - scope: ScopeId, + scope: ScopeId<'db>, } impl<'db> TyBuilder<'db> { - pub(super) fn new(db: &'db dyn HirAnalysisDb, scope: ScopeId) -> Self { + pub(super) fn new(db: &'db dyn HirAnalysisDb, scope: ScopeId<'db>) -> Self { Self { db, scope } } - pub(super) fn lower_ty(&mut self, ty: HirTyId) -> TyId { + pub(super) fn lower_ty(&mut self, ty: HirTyId<'db>) -> TyId<'db> { match ty.data(self.db.as_hir_db()) { HirTyKind::Ptr(pointee) => self.lower_ptr(*pointee), @@ -178,7 +181,11 @@ impl<'db> TyBuilder<'db> { } } - pub(super) fn lower_path(&mut self, path: Partial, args: GenericArgListId) -> TyId { + pub(super) fn lower_path( + &mut self, + path: Partial>, + args: GenericArgListId<'db>, + ) -> TyId<'db> { let path_ty = path .to_opt() .map(|path| match self.resolve_path(path) { @@ -209,7 +216,7 @@ impl<'db> TyBuilder<'db> { } } - pub(super) fn lower_self_ty(&mut self, args: GenericArgListId) -> TyId { + pub(super) fn lower_self_ty(&mut self, args: GenericArgListId<'db>) -> TyId<'db> { let res = self.resolve_path(PathId::self_ty(self.db.as_hir_db())); let (scope, res) = match res { Either::Left(res @ NameResKind::Scope(scope)) => (scope, res), @@ -267,14 +274,14 @@ impl<'db> TyBuilder<'db> { .fold(ty, |acc, arg| TyId::app(self.db, acc, arg)) } - fn lower_ptr(&mut self, pointee: Partial) -> TyId { + fn lower_ptr(&mut self, pointee: Partial>) -> TyId<'db> { let pointee = self.lower_opt_hir_ty(pointee); let ptr = TyId::ptr(self.db); TyId::app(self.db, ptr, pointee) } - fn lower_tuple(&mut self, tuple_id: TupleTypeId) -> TyId { + fn lower_tuple(&mut self, tuple_id: TupleTypeId<'db>) -> TyId<'db> { let elems = tuple_id.data(self.db.as_hir_db()); let len = elems.len(); let tuple = TyId::tuple(self.db, len); @@ -288,7 +295,10 @@ impl<'db> TyBuilder<'db> { }) } - fn lower_resolved_path(&mut self, kind: NameResKind) -> Either { + fn lower_resolved_path( + &mut self, + kind: NameResKind<'db>, + ) -> Either, &'db TyAlias<'db>> { let scope = match kind { NameResKind::Scope(scope) => scope, NameResKind::Prim(prim_ty) => { @@ -340,7 +350,7 @@ impl<'db> TyBuilder<'db> { /// If the path is resolved to a type, return the resolution. Otherwise, /// returns the `TyId::Invalid` with proper `InvalidCause`. - fn resolve_path(&mut self, path: PathId) -> Either { + fn resolve_path(&mut self, path: PathId<'db>) -> Either, TyId<'db>> { match resolve_path_early(self.db, path, self.scope) { EarlyResolvedPath::Full(bucket) => match bucket.pick(NameDomain::TYPE) { Ok(res) => Either::Left(res.kind), @@ -355,7 +365,7 @@ impl<'db> TyBuilder<'db> { } } - fn lower_opt_hir_ty(&self, hir_ty: Partial) -> TyId { + fn lower_opt_hir_ty(&self, hir_ty: Partial>) -> TyId<'db> { hir_ty .to_opt() .map(|hir_ty| lower_hir_ty(self.db, hir_ty, self.scope)) @@ -363,7 +373,11 @@ impl<'db> TyBuilder<'db> { } } -pub(super) fn lower_generic_arg(db: &dyn HirAnalysisDb, arg: &GenericArg, scope: ScopeId) -> TyId { +pub(super) fn lower_generic_arg<'db>( + db: &'db dyn HirAnalysisDb, + arg: &GenericArg<'db>, + scope: ScopeId<'db>, +) -> TyId<'db> { match arg { GenericArg::Type(ty_arg) => ty_arg .ty @@ -378,11 +392,11 @@ pub(super) fn lower_generic_arg(db: &dyn HirAnalysisDb, arg: &GenericArg, scope: } } -pub(crate) fn lower_generic_arg_list( - db: &dyn HirAnalysisDb, - args: GenericArgListId, - scope: ScopeId, -) -> Vec { +pub(crate) fn lower_generic_arg_list<'db>( + db: &'db dyn HirAnalysisDb, + args: GenericArgListId<'db>, + scope: ScopeId<'db>, +) -> Vec> { args.data(db.as_hir_db()) .iter() .map(|arg| lower_generic_arg(db, arg, scope)) @@ -390,24 +404,24 @@ pub(crate) fn lower_generic_arg_list( } #[salsa::interned] -pub struct GenericParamTypeSet { +pub struct GenericParamTypeSet<'db> { #[return_ref] - pub(crate) params_precursor: Vec, - pub(crate) scope: ScopeId, + pub(crate) params_precursor: Vec>, + pub(crate) scope: ScopeId<'db>, offset_to_explicit: usize, } -impl GenericParamTypeSet { - pub(crate) fn params(self, db: &dyn HirAnalysisDb) -> &[TyId] { +impl<'db> GenericParamTypeSet<'db> { + pub(crate) fn params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { evaluate_params_precursor(db, self) } - pub(crate) fn explicit_params(self, db: &dyn HirAnalysisDb) -> &[TyId] { + pub(crate) fn explicit_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] { let offset = self.offset_to_explicit(db); &self.params(db)[offset..] } - pub(crate) fn empty(db: &dyn HirAnalysisDb, scope: ScopeId) -> Self { + pub(crate) fn empty(db: &'db dyn HirAnalysisDb, scope: ScopeId<'db>) -> Self { Self::new(db, Vec::new(), scope, 0) } @@ -415,7 +429,7 @@ impl GenericParamTypeSet { self.params_precursor(db).len() } - pub(super) fn trait_self(&self, db: &dyn HirAnalysisDb) -> Option { + pub(super) fn trait_self(&self, db: &'db dyn HirAnalysisDb) -> Option> { let params = self.params_precursor(db); let cand = params.first()?; @@ -432,9 +446,9 @@ impl GenericParamTypeSet { pub(super) fn param_by_original_idx( &self, - db: &dyn HirAnalysisDb, + db: &'db dyn HirAnalysisDb, original_idx: usize, - ) -> Option { + ) -> Option> { let idx = self.offset_to_explicit(db) + original_idx; self.params_precursor(db) .get(idx) @@ -444,16 +458,16 @@ impl GenericParamTypeSet { struct GenericParamCollector<'db> { db: &'db dyn HirAnalysisDb, - owner: GenericParamOwner, - params: Vec, + owner: GenericParamOwner<'db>, + params: Vec>, offset_to_original: usize, } impl<'db> GenericParamCollector<'db> { - fn new(db: &'db dyn HirAnalysisDb, owner: GenericParamOwner) -> Self { + fn new(db: &'db dyn HirAnalysisDb, owner: GenericParamOwner<'db>) -> Self { let params = match owner { GenericParamOwner::Trait(_) => { - vec![TyParamPrecursor::trait_self(None)] + vec![TyParamPrecursor::trait_self(db, None)] } GenericParamOwner::Func(func) if func.is_associated_func(db.as_hir_db()) => { @@ -530,7 +544,7 @@ impl<'db> GenericParamCollector<'db> { } } - fn finalize(mut self) -> GenericParamTypeSet { + fn finalize(mut self) -> GenericParamTypeSet<'db> { self.collect_generic_params(); self.collect_kind_in_where_clause(); @@ -596,7 +610,7 @@ impl<'db> GenericParamCollector<'db> { } } - fn trait_self_ty_mut(&mut self) -> Option<&mut TyParamPrecursor> { + fn trait_self_ty_mut(&mut self) -> Option<&mut TyParamPrecursor<'db>> { let cand = self.params.get_mut(0)?; cand.is_trait_self().then_some(cand) } @@ -610,16 +624,21 @@ enum ParamLoc { #[doc(hidden)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TyParamPrecursor { - name: Partial, +pub struct TyParamPrecursor<'db> { + name: Partial>, original_idx: Option, kind: Option, - const_ty_ty: Option, + const_ty_ty: Option>, is_const_ty: bool, } -impl TyParamPrecursor { - fn evaluate(&self, db: &dyn HirAnalysisDb, scope: ScopeId, lowered_idx: usize) -> TyId { +impl<'db> TyParamPrecursor<'db> { + fn evaluate( + &self, + db: &'db dyn HirAnalysisDb, + scope: ScopeId<'db>, + lowered_idx: usize, + ) -> TyId<'db> { let Partial::Present(name) = self.name else { return TyId::invalid(db, InvalidCause::Other); }; @@ -627,7 +646,7 @@ impl TyParamPrecursor { let kind = self.kind.clone().unwrap_or(Kind::Star); if self.original_idx.is_none() { - let param = TyParam::trait_self(kind); + let param = TyParam::trait_self(db, kind); return TyId::new(db, TyData::TyParam(param)); } @@ -655,7 +674,7 @@ impl TyParamPrecursor { TyId::new(db, TyData::ConstTy(const_ty)) } - fn ty_param(name: Partial, idx: usize, kind: Option) -> Self { + fn ty_param(name: Partial>, idx: usize, kind: Option) -> Self { Self { name, original_idx: idx.into(), @@ -665,7 +684,7 @@ impl TyParamPrecursor { } } - fn const_ty_param(name: Partial, idx: usize, ty: Option) -> Self { + fn const_ty_param(name: Partial>, idx: usize, ty: Option>) -> Self { Self { name, original_idx: idx.into(), @@ -675,8 +694,8 @@ impl TyParamPrecursor { } } - fn trait_self(kind: Option) -> Self { - let name = Partial::Present(kw::SELF_TY); + fn trait_self(db: &'db dyn HirAnalysisDb, kind: Option) -> Self { + let name = Partial::Present(IdentId::make_self_ty(db.as_hir_db())); Self { name, original_idx: None, @@ -712,30 +731,30 @@ pub(super) fn lower_kind(kind: &HirKindBound) -> Kind { } #[salsa::interned] -pub(crate) struct GenericParamOwnerId { - pub(super) data: GenericParamOwner, +pub(crate) struct GenericParamOwnerId<'db> { + pub(super) data: GenericParamOwner<'db>, } -impl GenericParamOwnerId { - pub(super) fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId { +impl<'db> GenericParamOwnerId<'db> { + pub(super) fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> { self.data(db).scope() } - pub(super) fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId { + pub(super) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> { self.data(db).top_mod(db.as_hir_db()).ingot(db.as_hir_db()) } - pub(super) fn where_clause(self, db: &dyn HirAnalysisDb) -> Option { + pub(super) fn where_clause(self, db: &'db dyn HirAnalysisDb) -> Option> { self.data(db) .where_clause_owner() .map(|owner| owner.where_clause(db.as_hir_db())) } - pub(super) fn params(self, db: &dyn HirAnalysisDb) -> GenericParamListId { + pub(super) fn params(self, db: &'db dyn HirAnalysisDb) -> GenericParamListId<'db> { self.data(db).params(db.as_hir_db()) } - pub(super) fn from_item_opt(db: &dyn HirAnalysisDb, item: ItemKind) -> Option { + pub(super) fn from_item_opt(db: &'db dyn HirAnalysisDb, item: ItemKind<'db>) -> Option { let owner = GenericParamOwner::from_item_opt(item)?; Self::new(db, owner).into() } diff --git a/crates/hir-analysis/src/ty/unify.rs b/crates/hir-analysis/src/ty/unify.rs index 3bdb12f69..e356fd3ba 100644 --- a/crates/hir-analysis/src/ty/unify.rs +++ b/crates/hir-analysis/src/ty/unify.rs @@ -1,6 +1,8 @@ //! This module contains the unification table for type inference and trait //! satisfiability checking. +use std::marker::PhantomData; + use either::Either; use ena::unify::{InPlace, UnifyKey, UnifyValue}; use num_bigint::BigUint; @@ -16,7 +18,7 @@ use crate::{ HirAnalysisDb, }; -pub(crate) type UnificationTable<'db> = UnificationTableBase<'db, InPlace>; +pub(crate) type UnificationTable<'db> = UnificationTableBase<'db, InPlace>>; /// This table should only be used in the trait resolution where the performance /// of `clone` is the critical. This table provides the very cheap clone @@ -25,7 +27,7 @@ pub(crate) type UnificationTable<'db> = UnificationTableBase<'db, InPlace = - UnificationTableBase<'db, ena::unify::Persistent>; + UnificationTableBase<'db, ena::unify::Persistent>>; pub type Snapshot = ena::unify::Snapshot; pub type UnificationResult = Result<(), UnificationError>; @@ -36,17 +38,17 @@ pub enum UnificationError { TypeMismatch, } -pub(crate) trait UnificationStore: +pub(crate) trait UnificationStore<'db>: Default - + ena::unify::UnificationStoreBase + + ena::unify::UnificationStoreBase, Value = InferenceValue<'db>> + ena::unify::UnificationStore + ena::unify::UnificationStoreMut { } -impl UnificationStore for U where +impl<'db, U> UnificationStore<'db> for U where U: Default - + ena::unify::UnificationStoreBase + + ena::unify::UnificationStoreBase, Value = InferenceValue<'db>> + ena::unify::UnificationStoreBase + ena::unify::UnificationStore + ena::unify::UnificationStoreMut @@ -64,7 +66,7 @@ where impl<'db, U> UnificationTableBase<'db, U> where - U: UnificationStore, + U: UnificationStore<'db>, { pub fn new(db: &'db dyn HirAnalysisDb) -> Self { Self { @@ -92,7 +94,7 @@ where pub fn unify(&mut self, lhs: T, rhs: T) -> UnificationResult where - T: Unifiable, + T: Unifiable<'db>, { let snapshot = self.snapshot(); match lhs.unify(self, rhs) { @@ -111,7 +113,7 @@ where /// error. This method doesn't roll back the unification table. Please /// refer to `unify`[Self::unify] if you need to roll back the table /// automatically when unification fails. - fn unify_ty(&mut self, ty1: TyId, ty2: TyId) -> UnificationResult { + fn unify_ty(&mut self, ty1: TyId<'db>, ty2: TyId<'db>) -> UnificationResult { if !ty1.kind(self.db).does_match(ty2.kind(self.db)) { return Err(UnificationError::TypeMismatch); } @@ -173,12 +175,12 @@ where } } - pub fn new_var(&mut self, sort: TyVarSort, kind: &Kind) -> TyId { + pub fn new_var(&mut self, sort: TyVarSort, kind: &Kind) -> TyId<'db> { let key = self.new_key(kind, sort); TyId::ty_var(self.db, sort, kind.clone(), key) } - pub(super) fn new_var_from_param(&mut self, ty: TyId) -> TyId { + pub(super) fn new_var_from_param(&mut self, ty: TyId<'db>) -> TyId<'db> { match ty.data(self.db) { TyData::TyParam(param) => { let sort = TyVarSort::General; @@ -198,7 +200,7 @@ where } } - pub(super) fn new_var_for(&mut self, ty_prop: ApplicableTyProp) -> TyId { + pub(super) fn new_var_for(&mut self, ty_prop: ApplicableTyProp<'db>) -> TyId<'db> { let kind = ty_prop.kind; let sort = TyVarSort::General; let key = self.new_key(&kind, sort); @@ -216,7 +218,7 @@ where value.instantiate_with(self.db, |ty| self.new_var_from_param(ty)) } - pub fn instantiate_to_term(&mut self, mut ty: TyId) -> TyId { + pub fn instantiate_to_term(&mut self, mut ty: TyId<'db>) -> TyId<'db> { if ty.has_invalid(self.db) { return ty; }; @@ -229,12 +231,12 @@ where ty } - pub fn new_key(&mut self, kind: &Kind, sort: TyVarSort) -> InferenceKey { + pub fn new_key(&mut self, kind: &Kind, sort: TyVarSort) -> InferenceKey<'db> { self.table .new_key(InferenceValue::Unbound(kind.clone(), sort)) } - fn probe_impl(&mut self, key: InferenceKey) -> Either { + fn probe_impl(&mut self, key: InferenceKey<'db>) -> Either, TyVar> { let root_key = self.table.find(key); match self.table.probe_value(key) { InferenceValue::Bound(ty) => Either::Left(ty), @@ -254,7 +256,7 @@ where /// that has a broader sort are narrowed down to the narrower one. /// /// NOTE: This method assumes that we have only two sorts: General and Int. - fn unify_var_var(&mut self, ty_var1: TyId, ty_var2: TyId) -> UnificationResult { + fn unify_var_var(&mut self, ty_var1: TyId<'db>, ty_var2: TyId<'db>) -> UnificationResult { let (var1, var2) = match (ty_var1.data(self.db), ty_var2.data(self.db)) { (TyData::TyVar(var1), TyData::TyVar(var2)) => (var1, var2), (TyData::ConstTy(const_ty1), TyData::ConstTy(const_ty2)) => { @@ -364,23 +366,23 @@ where } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct InferenceKey(pub(super) u32); +pub struct InferenceKey<'db>(pub(super) u32, PhantomData<&'db ()>); #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum InferenceValue { - Bound(TyId), +pub enum InferenceValue<'db> { + Bound(TyId<'db>), Unbound(Kind, TyVarSort), } -impl UnifyKey for InferenceKey { - type Value = InferenceValue; +impl<'db> UnifyKey for InferenceKey<'db> { + type Value = InferenceValue<'db>; fn index(&self) -> u32 { self.0 } fn from_index(idx: u32) -> Self { - Self(idx) + Self(idx, Default::default()) } fn tag() -> &'static str { @@ -388,7 +390,7 @@ impl UnifyKey for InferenceKey { } } -impl UnifyValue for InferenceValue { +impl<'db> UnifyValue for InferenceValue<'db> { type Error = UnificationError; fn unify_values(v1: &Self, v2: &Self) -> Result { @@ -418,28 +420,28 @@ impl UnifyValue for InferenceValue { } } -pub(crate) trait Unifiable { - fn unify( +pub(crate) trait Unifiable<'db> { + fn unify>( self, - table: &mut UnificationTableBase, + table: &mut UnificationTableBase<'db, U>, other: Self, ) -> UnificationResult; } -impl Unifiable for TyId { - fn unify( +impl<'db> Unifiable<'db> for TyId<'db> { + fn unify>( self, - table: &mut UnificationTableBase, + table: &mut UnificationTableBase<'db, U>, other: Self, ) -> UnificationResult { table.unify_ty(self, other) } } -impl Unifiable for TraitInstId { - fn unify( +impl<'db> Unifiable<'db> for TraitInstId<'db> { + fn unify>( self, - table: &mut UnificationTableBase, + table: &mut UnificationTableBase<'db, U>, other: Self, ) -> UnificationResult { let db = table.db; @@ -455,10 +457,10 @@ impl Unifiable for TraitInstId { } } -impl Unifiable for Implementor { - fn unify( +impl<'db> Unifiable<'db> for Implementor<'db> { + fn unify>( self, - table: &mut UnificationTableBase, + table: &mut UnificationTableBase<'db, U>, other: Self, ) -> UnificationResult { let db = table.db; @@ -468,13 +470,13 @@ impl Unifiable for Implementor { impl<'db, U> TyFolder<'db> for UnificationTableBase<'db, U> where - U: UnificationStore, + U: UnificationStore<'db>, { fn db(&self) -> &'db dyn HirAnalysisDb { self.db } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { let mut resolver = TyVarResolver { table: self, var_stack: vec![], @@ -486,21 +488,21 @@ where struct TyVarResolver<'a, 'db, U> where - U: UnificationStore, + U: UnificationStore<'db>, { table: &'a mut UnificationTableBase<'db, U>, - var_stack: Vec, + var_stack: Vec>, } impl<'a, 'db, U> TyFolder<'db> for TyVarResolver<'a, 'db, U> where - U: UnificationStore, + U: UnificationStore<'db>, { fn db(&self) -> &'db dyn HirAnalysisDb { self.table.db } - fn fold_ty(&mut self, ty: TyId) -> TyId { + fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> { let db = self.table.db; let (shallow_resolved, key) = match ty.data(db) { TyData::TyVar(var) if !self.var_stack.contains(&var.key) => { diff --git a/crates/hir-analysis/src/ty/visitor.rs b/crates/hir-analysis/src/ty/visitor.rs index 5a681bed3..5020b1425 100644 --- a/crates/hir-analysis/src/ty/visitor.rs +++ b/crates/hir-analysis/src/ty/visitor.rs @@ -20,48 +20,48 @@ pub trait TyVisitable<'db> { pub trait TyVisitor<'db> { fn db(&self) -> &'db dyn HirAnalysisDb; - fn visit_ty(&mut self, ty: TyId) { + fn visit_ty(&mut self, ty: TyId<'db>) { walk_ty(self, ty) } #[allow(unused_variables)] - fn visit_var(&mut self, var: &TyVar) {} + fn visit_var(&mut self, var: &TyVar<'db>) {} #[allow(unused_variables)] - fn visit_param(&mut self, ty_param: &TyParam) {} + fn visit_param(&mut self, ty_param: &TyParam<'db>) {} #[allow(unused_variables)] - fn visit_const_param(&mut self, ty_param: &TyParam, const_ty_ty: TyId) {} + fn visit_const_param(&mut self, ty_param: &TyParam<'db>, const_ty_ty: TyId<'db>) {} - fn visit_app(&mut self, abs: TyId, arg: TyId) { + fn visit_app(&mut self, abs: TyId<'db>, arg: TyId<'db>) { self.visit_ty(abs); self.visit_ty(arg); } #[allow(unused_variables)] - fn visit_ty_base(&mut self, ty_base: &TyBase) { + fn visit_ty_base(&mut self, ty_base: &TyBase<'db>) { walk_ty_base(self, ty_base); } #[allow(unused_variables)] - fn visit_invalid(&mut self, cause: &InvalidCause) {} + fn visit_invalid(&mut self, cause: &InvalidCause<'db>) {} #[allow(unused_variables)] fn visit_prim(&mut self, prim: &PrimTy) {} #[allow(unused_variables)] - fn visit_adt(&mut self, adt: AdtDef) {} + fn visit_adt(&mut self, adt: AdtDef<'db>) {} #[allow(unused_variables)] - fn visit_func(&mut self, func: FuncDef) {} + fn visit_func(&mut self, func: FuncDef<'db>) {} #[allow(unused_variables)] - fn visit_const_ty(&mut self, const_ty: &ConstTyId) { + fn visit_const_ty(&mut self, const_ty: &ConstTyId<'db>) { walk_const_ty(self, const_ty) } } -pub fn walk_ty<'db, V>(visitor: &mut V, ty: TyId) +pub fn walk_ty<'db, V>(visitor: &mut V, ty: TyId<'db>) where V: TyVisitor<'db> + ?Sized, { @@ -82,7 +82,7 @@ where } } -pub fn walk_ty_base<'db, V>(visitor: &mut V, ty_con: &TyBase) +pub fn walk_ty_base<'db, V>(visitor: &mut V, ty_con: &TyBase<'db>) where V: TyVisitor<'db> + ?Sized, { @@ -93,7 +93,7 @@ where } } -pub fn walk_const_ty<'db, V>(visitor: &mut V, const_ty: &ConstTyId) +pub fn walk_const_ty<'db, V>(visitor: &mut V, const_ty: &ConstTyId<'db>) where V: TyVisitor<'db> + ?Sized, { @@ -106,7 +106,7 @@ where } } -impl<'db> TyVisitable<'db> for TyId { +impl<'db> TyVisitable<'db> for TyId<'db> { fn visit_with(&self, visitor: &mut V) where V: TyVisitor<'db>, @@ -151,7 +151,7 @@ where } } -impl<'db> TyVisitable<'db> for TraitInstId { +impl<'db> TyVisitable<'db> for TraitInstId<'db> { fn visit_with(&self, visitor: &mut V) where V: TyVisitor<'db>, @@ -161,7 +161,7 @@ impl<'db> TyVisitable<'db> for TraitInstId { } } -impl<'db> TyVisitable<'db> for Implementor { +impl<'db> TyVisitable<'db> for Implementor<'db> { fn visit_with(&self, visitor: &mut V) where V: TyVisitor<'db>, @@ -171,7 +171,7 @@ impl<'db> TyVisitable<'db> for Implementor { } } -impl<'db> TyVisitable<'db> for PredicateListId { +impl<'db> TyVisitable<'db> for PredicateListId<'db> { fn visit_with(&self, visitor: &mut V) where V: TyVisitor<'db>, @@ -180,7 +180,7 @@ impl<'db> TyVisitable<'db> for PredicateListId { } } -impl<'db> TyVisitable<'db> for ExprProp { +impl<'db> TyVisitable<'db> for ExprProp<'db> { fn visit_with(&self, visitor: &mut V) where V: TyVisitor<'db>, diff --git a/crates/hir/src/hir_def/item.rs b/crates/hir/src/hir_def/item.rs index a3b9542e7..aeabd6267 100644 --- a/crates/hir/src/hir_def/item.rs +++ b/crates/hir/src/hir_def/item.rs @@ -37,6 +37,7 @@ use crate::{ Ord, derive_more::From, derive_more::TryInto, + salsa::Update, )] pub enum ItemKind<'db> { TopMod(TopLevelMod<'db>), diff --git a/crates/hir/src/hir_def/scope_graph.rs b/crates/hir/src/hir_def/scope_graph.rs index 12173f8c7..0cc6a1447 100644 --- a/crates/hir/src/hir_def/scope_graph.rs +++ b/crates/hir/src/hir_def/scope_graph.rs @@ -69,7 +69,7 @@ impl<'db> ScopeGraph<'db> { } /// An reference to a `[ScopeData]` in a `ScopeGraph`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update)] pub enum ScopeId<'db> { /// An item scope. Item(ItemKind<'db>), @@ -385,7 +385,7 @@ impl<'db> ScopeId<'db> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update)] pub enum FieldParent<'db> { Item(ItemKind<'db>), Variant(ItemKind<'db>, usize),