Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 401 |
1 files changed, 234 insertions, 167 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 34372a4a95..4d4482b1af 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -49,13 +49,13 @@ use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ AdtId, AssocItemId, AssocItemLoc, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, - DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, - HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, - MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UnionId, + DefWithBodyId, EnumId, EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, + FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, + Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UnionId, attrs::AttrFlags, builtin_derive::BuiltinDeriveImplMethod, - expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, + expr_store::{ExpressionStore, ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, @@ -69,7 +69,11 @@ use hir_def::{ }, per_ns::PerNs, resolver::{HasResolver, Resolver}, - signatures::{EnumSignature, ImplFlags, StaticFlags, StructFlags, TraitFlags, VariantFields}, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplFlags, ImplSignature, StaticFlags, + StaticSignature, StructFlags, StructSignature, TraitFlags, TraitSignature, + TypeAliasSignature, UnionSignature, VariantFields, + }, src::HasSource as _, visibility::visibility_from_ast, }; @@ -141,6 +145,7 @@ pub use { Complete, FindPathConfig, attrs::{Docs, IsInnerDoc}, + expr_store::Body, find_path::PrefixKind, import_map, lang_item::{LangItemEnum as LangItem, crate_lang_items}, @@ -729,8 +734,8 @@ impl Module { ModuleDef::Adt(adt) => { match adt { Adt::Struct(s) => { - let source_map = db.struct_signature_with_source_map(s.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &StructSignature::with_source_map(db, s.id).1; + expr_store_diagnostics(db, acc, source_map); let source_map = &s.id.fields_with_source_map(db).1; expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( @@ -741,8 +746,8 @@ impl Module { ); } Adt::Union(u) => { - let source_map = db.union_signature_with_source_map(u.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &UnionSignature::with_source_map(db, u.id).1; + expr_store_diagnostics(db, acc, source_map); let source_map = &u.id.fields_with_source_map(db).1; expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( @@ -753,8 +758,8 @@ impl Module { ); } Adt::Enum(e) => { - let source_map = db.enum_signature_with_source_map(e.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &EnumSignature::with_source_map(db, e.id).1; + expr_store_diagnostics(db, acc, source_map); let (variants, diagnostics) = e.id.enum_variants_with_diagnostics(db); let file = e.id.lookup(db).id.file_id; let ast_id_map = db.ast_id_map(file); @@ -789,13 +794,13 @@ impl Module { } ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m), ModuleDef::TypeAlias(type_alias) => { - let source_map = db.type_alias_signature_with_source_map(type_alias.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &TypeAliasSignature::with_source_map(db, type_alias.id).1; + expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( db, acc, db.type_for_type_alias_with_diagnostics(type_alias.id).1, - &source_map, + source_map, ); acc.extend(def.diagnostics(db, style_lints)); } @@ -815,8 +820,8 @@ impl Module { continue; }; let loc = impl_id.lookup(db); - let (impl_signature, source_map) = db.impl_signature_with_source_map(impl_id); - expr_store_diagnostics(db, acc, &source_map); + let (impl_signature, source_map) = ImplSignature::with_source_map(db, impl_id); + expr_store_diagnostics(db, acc, source_map); let file_id = loc.id.file_id; if file_id.macro_file().is_some_and(|it| it.kind(db) == MacroKind::DeriveBuiltIn) { @@ -888,9 +893,9 @@ impl Module { if let (false, Some(trait_)) = (impl_is_negative, trait_) { let items = &trait_.id.trait_items(db).items; let required_items = items.iter().filter(|&(_, assoc)| match *assoc { - AssocItemId::FunctionId(it) => !db.function_signature(it).has_body(), - AssocItemId::ConstId(id) => !db.const_signature(id).has_body(), - AssocItemId::TypeAliasId(it) => db.type_alias_signature(it).ty.is_none(), + AssocItemId::FunctionId(it) => !FunctionSignature::of(db, it).has_body(), + AssocItemId::ConstId(id) => !ConstSignature::of(db, id).has_body(), + AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it).ty.is_none(), }); impl_assoc_items_scratch.extend(impl_id.impl_items(db).items.iter().cloned()); @@ -928,7 +933,7 @@ impl Module { let self_ty = structurally_normalize_ty( &infcx, self_ty, - db.trait_environment(impl_id.into()), + db.trait_environment(GenericDefId::from(impl_id).into()), ); let self_ty_is_guaranteed_unsized = matches!( self_ty.kind(), @@ -983,7 +988,7 @@ impl Module { continue; } - if db.function_signature(*fn_).is_default() { + if FunctionSignature::of(db, *fn_).is_default() { return false; } } @@ -1007,12 +1012,12 @@ impl Module { impl_assoc_items_scratch.clear(); } - push_ty_diagnostics(db, acc, db.impl_self_ty_with_diagnostics(impl_id).1, &source_map); + push_ty_diagnostics(db, acc, db.impl_self_ty_with_diagnostics(impl_id).1, source_map); push_ty_diagnostics( db, acc, db.impl_trait_with_diagnostics(impl_id).and_then(|it| it.1), - &source_map, + source_map, ); for &(_, item) in impl_id.impl_items(db).items.iter() { @@ -1331,7 +1336,7 @@ impl TupleField { pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let interner = DbInterner::new_no_crate(db); - let ty = InferenceResult::for_body(db, self.owner) + let ty = InferenceResult::of(db, self.owner) .tuple_field_access_type(self.tuple) .as_slice() .get(self.index as usize) @@ -1455,7 +1460,7 @@ impl Struct { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.struct_signature(self.id).name.clone() + StructSignature::of(db, self.id).name.clone() } pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { @@ -1548,7 +1553,7 @@ pub struct Union { impl Union { pub fn name(self, db: &dyn HirDatabase) -> Name { - db.union_signature(self.id).name.clone() + UnionSignature::of(db, self.id).name.clone() } pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -1607,7 +1612,7 @@ impl Enum { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.enum_signature(self.id).name.clone() + EnumSignature::of(db, self.id).name.clone() } pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> { @@ -1962,6 +1967,44 @@ impl VariantDef { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ExpressionStoreOwner { + Body(DefWithBody), + Signature(GenericDef), +} + +impl From<GenericDef> for ExpressionStoreOwner { + fn from(v: GenericDef) -> Self { + Self::Signature(v) + } +} + +impl From<DefWithBody> for ExpressionStoreOwner { + fn from(v: DefWithBody) -> Self { + Self::Body(v) + } +} + +impl From<ExpressionStoreOwnerId> for ExpressionStoreOwner { + fn from(v: ExpressionStoreOwnerId) -> Self { + match v { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + Self::Signature(generic_def_id.into()) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Self::Body(def_with_body_id.into()), + } + } +} + +impl ExpressionStoreOwner { + pub fn module(self, db: &dyn HirDatabase) -> Module { + match self { + Self::Body(body) => body.module(db), + Self::Signature(generic_def) => generic_def.module(db), + } + } +} + /// The defs which have a body. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum DefWithBody { @@ -2018,7 +2061,7 @@ impl DefWithBody { let Some(id) = self.id() else { return String::new(); }; - let body = db.body(id); + let body = Body::of(db, id); body.pretty_print(db, id, Edition::CURRENT) } @@ -2045,17 +2088,17 @@ impl DefWithBody { }; let krate = self.module(db).id.krate(db); - let (body, source_map) = db.body_with_source_map(id); + let (body, source_map) = Body::with_source_map(db, id); let sig_source_map = match self { DefWithBody::Function(id) => match id.id { - AnyFunctionId::FunctionId(id) => db.function_signature_with_source_map(id).1, + AnyFunctionId::FunctionId(id) => &FunctionSignature::with_source_map(db, id).1, AnyFunctionId::BuiltinDeriveImplMethod { .. } => return, }, - DefWithBody::Static(id) => db.static_signature_with_source_map(id.into()).1, - DefWithBody::Const(id) => db.const_signature_with_source_map(id.into()).1, + DefWithBody::Static(id) => &StaticSignature::with_source_map(db, id.into()).1, + DefWithBody::Const(id) => &ConstSignature::with_source_map(db, id.into()).1, DefWithBody::Variant(variant) => { let enum_id = variant.parent_enum(db).id; - db.enum_signature_with_source_map(enum_id).1 + &EnumSignature::with_source_map(db, enum_id).1 } }; @@ -2063,17 +2106,11 @@ impl DefWithBody { Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints); } - expr_store_diagnostics(db, acc, &source_map); + expr_store_diagnostics(db, acc, source_map); - let infer = InferenceResult::for_body(db, id); + let infer = InferenceResult::of(db, id); for d in infer.diagnostics() { - acc.extend(AnyDiagnostic::inference_diagnostic( - db, - id, - d, - &source_map, - &sig_source_map, - )); + acc.extend(AnyDiagnostic::inference_diagnostic(db, id, d, source_map, sig_source_map)); } for (pat_or_expr, mismatch) in infer.type_mismatches() { @@ -2195,7 +2232,7 @@ impl DefWithBody { { need_mut = &mir::MutabilityReason::Not; } - let local = Local { parent: id, binding_id }; + let local = Local { parent: id.into(), binding_id }; let is_mut = body[binding_id].mode == BindingAnnotation::Mutable; match (need_mut, is_mut) { @@ -2252,7 +2289,7 @@ impl DefWithBody { } for diagnostic in BodyValidationDiagnostic::collect(db, id, style_lints) { - acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, &source_map)); + acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, source_map)); } for diag in hir_ty::diagnostics::incorrect_case(db, id.into()) { @@ -2266,7 +2303,7 @@ impl DefWithBody { db: &'db dyn HirDatabase, ) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.expression_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2276,7 +2313,7 @@ impl DefWithBody { /// Returns an iterator over the inferred types of all patterns in this body. pub fn pattern_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.pattern_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2286,7 +2323,7 @@ impl DefWithBody { /// Returns an iterator over the inferred types of all bindings in this body. pub fn binding_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.binding_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2354,7 +2391,7 @@ impl Function { pub fn name(self, db: &dyn HirDatabase) -> Name { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).name.clone(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).name.clone(), AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => { Name::new_symbol_root(method.name()) } @@ -2556,7 +2593,7 @@ impl Function { pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).has_self_param(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_self_param(), AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method { BuiltinDeriveImplMethod::clone | BuiltinDeriveImplMethod::fmt @@ -2591,7 +2628,7 @@ impl Function { pub fn num_params(self, db: &dyn HirDatabase) -> usize { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).params.len(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).params.len(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => { self.fn_sig(db).1.skip_binder().inputs().len() } @@ -2635,21 +2672,21 @@ impl Function { pub fn is_const(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_const(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_const(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } pub fn is_async(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_async(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_async(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } pub fn is_varargs(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_varargs(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_varargs(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } @@ -2702,7 +2739,7 @@ impl Function { AnyFunctionId::FunctionId(id) => { self.exported_main(db) || self.module(db).is_crate_root(db) - && db.function_signature(id).name == sym::main + && FunctionSignature::of(db, id).name == sym::main } AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } @@ -2779,7 +2816,7 @@ impl Function { /// This is false in the case of required (not provided) trait methods. pub fn has_body(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).has_body(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_body(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => true, } } @@ -2807,7 +2844,7 @@ impl Function { id.into(), GenericArgs::empty(interner).store(), ParamEnvAndCrate { - param_env: db.trait_environment(id.into()), + param_env: db.trait_environment(GenericDefId::from(id).into()), krate: id.module(db).krate(db), } .store(), @@ -2893,23 +2930,24 @@ impl<'db> Param<'db> { match self.func { Callee::Def(CallableDefId::FunctionId(it)) => { let parent = DefWithBodyId::FunctionId(it); - let body = db.body(parent); + let body = Body::of(db, parent); if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { - Some(Local { parent, binding_id: self_param }) + Some(Local { parent: parent.into(), binding_id: self_param }) } else if let Pat::Bind { id, .. } = &body[body.params[self.idx - body.self_param.is_some() as usize]] { - Some(Local { parent, binding_id: *id }) + Some(Local { parent: parent.into(), binding_id: *id }) } else { None } } Callee::Closure(closure, _) => { let c = db.lookup_intern_closure(closure); - let body_owner = c.0.as_def_with_body()?; - let body = db.body(body_owner); - if let Expr::Closure { args, .. } = &body[c.1] - && let Pat::Bind { id, .. } = &body[args[self.idx]] + let body_owner = c.0; + let store = ExpressionStore::of(db, c.0); + + if let Expr::Closure { args, .. } = &store[c.1] + && let Pat::Bind { id, .. } = &store[args[self.idx]] { return Some(Local { parent: body_owner, binding_id: *id }); } @@ -2933,7 +2971,7 @@ impl SelfParam { pub fn access(self, db: &dyn HirDatabase) -> Access { match self.func.id { AnyFunctionId::FunctionId(id) => { - let func_data = db.function_signature(id); + let func_data = FunctionSignature::of(db, id); func_data .params .first() @@ -3062,7 +3100,7 @@ impl Const { } pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { - db.const_signature(self.id).name.clone() + ConstSignature::of(db, self.id).name.clone() } pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> { @@ -3135,11 +3173,11 @@ impl Static { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.static_signature(self.id).name.clone() + StaticSignature::of(db, self.id).name.clone() } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { - db.static_signature(self.id).flags.contains(StaticFlags::MUTABLE) + StaticSignature::of(db, self.id).flags.contains(StaticFlags::MUTABLE) } pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> { @@ -3195,7 +3233,7 @@ impl Trait { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.trait_signature(self.id).name.clone() + TraitSignature::of(db, self.id).name.clone() } pub fn direct_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> { @@ -3225,11 +3263,11 @@ impl Trait { } pub fn is_auto(self, db: &dyn HirDatabase) -> bool { - db.trait_signature(self.id).flags.contains(TraitFlags::AUTO) + TraitSignature::of(db, self.id).flags.contains(TraitFlags::AUTO) } pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool { - db.trait_signature(self.id).flags.contains(TraitFlags::UNSAFE) + TraitSignature::of(db, self.id).flags.contains(TraitFlags::UNSAFE) } pub fn type_or_const_param_count( @@ -3305,7 +3343,7 @@ impl TypeAlias { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.type_alias_signature(self.id).name.clone() + TypeAliasSignature::of(db, self.id).name.clone() } } @@ -3752,6 +3790,17 @@ impl AsAssocItem for DefWithBody { } } +impl AsAssocItem for GenericDef { + fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> { + match self { + GenericDef::Function(it) => it.as_assoc_item(db), + GenericDef::Const(it) => it.as_assoc_item(db), + GenericDef::TypeAlias(it) => it.as_assoc_item(db), + _ => None, + } + } +} + fn as_assoc_item<'db, ID, DEF, LOC>( db: &(dyn HirDatabase + 'db), ctor: impl FnOnce(DEF) -> AssocItem, @@ -3934,7 +3983,7 @@ impl AssocItem { db, acc, db.type_for_type_alias_with_diagnostics(type_alias.id).1, - &db.type_alias_signature_with_source_map(type_alias.id).1, + &TypeAliasSignature::with_source_map(db, type_alias.id).1, ); for diag in hir_ty::diagnostics::incorrect_case(db, type_alias.id.into()) { acc.push(diag.into()); @@ -4085,24 +4134,24 @@ impl GenericDef { } let source_map = match def { - GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature_with_source_map(it).1, - GenericDefId::AdtId(AdtId::StructId(it)) => db.struct_signature_with_source_map(it).1, - GenericDefId::AdtId(AdtId::UnionId(it)) => db.union_signature_with_source_map(it).1, + GenericDefId::AdtId(AdtId::EnumId(it)) => &EnumSignature::with_source_map(db, it).1, + GenericDefId::AdtId(AdtId::StructId(it)) => &StructSignature::with_source_map(db, it).1, + GenericDefId::AdtId(AdtId::UnionId(it)) => &UnionSignature::with_source_map(db, it).1, GenericDefId::ConstId(_) => return, - GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1, - GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1, + GenericDefId::FunctionId(it) => &FunctionSignature::with_source_map(db, it).1, + GenericDefId::ImplId(it) => &ImplSignature::with_source_map(db, it).1, GenericDefId::StaticId(_) => return, - GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1, - GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1, + GenericDefId::TraitId(it) => &TraitSignature::with_source_map(db, it).1, + GenericDefId::TypeAliasId(it) => &TypeAliasSignature::with_source_map(db, it).1, }; - expr_store_diagnostics(db, acc, &source_map); - push_ty_diagnostics(db, acc, db.generic_defaults_with_diagnostics(def).1, &source_map); + expr_store_diagnostics(db, acc, source_map); + push_ty_diagnostics(db, acc, db.generic_defaults_with_diagnostics(def).1, source_map); push_ty_diagnostics( db, acc, GenericPredicates::query_with_diagnostics(db, def).1.clone(), - &source_map, + source_map, ); for (param_id, param) in generics.iter_type_or_consts() { if let TypeOrConstParamData::ConstParamData(_) = param { @@ -4113,7 +4162,7 @@ impl GenericDef { TypeOrConstParamId { parent: def, local_id: param_id }, )) .1, - &source_map, + source_map, ); } } @@ -4210,7 +4259,7 @@ impl<'db> GenericSubstitution<'db> { /// A single local definition. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Local { - pub(crate) parent: DefWithBodyId, + pub(crate) parent: ExpressionStoreOwnerId, pub(crate) binding_id: BindingId, } @@ -4272,7 +4321,7 @@ impl Local { pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { match self.parent { - DefWithBodyId::FunctionId(func) if self.is_self(db) => { + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) if self.is_self(db) => { Some(SelfParam { func: func.into() }) } _ => None, @@ -4280,8 +4329,7 @@ impl Local { } pub fn name(self, db: &dyn HirDatabase) -> Name { - let body = db.body(self.parent); - body[self.binding_id].name.clone() + ExpressionStore::of(db, self.parent)[self.binding_id].name.clone() } pub fn is_self(self, db: &dyn HirDatabase) -> bool { @@ -4289,16 +4337,17 @@ impl Local { } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { - let body = db.body(self.parent); - body[self.binding_id].mode == BindingAnnotation::Mutable + ExpressionStore::of(db, self.parent)[self.binding_id].mode == BindingAnnotation::Mutable } pub fn is_ref(self, db: &dyn HirDatabase) -> bool { - let body = db.body(self.parent); - matches!(body[self.binding_id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) + matches!( + ExpressionStore::of(db, self.parent)[self.binding_id].mode, + BindingAnnotation::Ref | BindingAnnotation::RefMut + ) } - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.parent.into() } @@ -4312,67 +4361,89 @@ impl Local { pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; - let infer = InferenceResult::for_body(db, def); + let infer = InferenceResult::of(db, def); let ty = infer.binding_ty(self.binding_id); Type::new(db, def, ty) } /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;` pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> { - let (body, source_map) = db.body_with_source_map(self.parent); - match body.self_param.zip(source_map.self_param_syntax()) { - Some((param, source)) if param == self.binding_id => { - let root = source.file_syntax(db); - vec![LocalSource { - local: self, - source: source.map(|ast| Either::Right(ast.to_node(&root))), - }] + let b; + let s; + let (_, source_map) = match self.parent { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + s = ExpressionStore::with_source_map(db, generic_def_id.into()); + (s.0, s.1) } - _ => source_map - .patterns_for_binding(self.binding_id) - .iter() - .map(|&definition| { - let src = source_map.pat_syntax(definition).unwrap(); // Hmm... - let root = src.file_syntax(db); - LocalSource { + ExpressionStoreOwnerId::Body(def_with_body_id) => { + b = Body::with_source_map(db, def_with_body_id); + if let Some((param, source)) = b.0.self_param.zip(b.1.self_param_syntax()) + && param == self.binding_id + { + let root = source.file_syntax(db); + return vec![LocalSource { local: self, - source: src.map(|ast| match ast.to_node(&root) { - Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), - _ => unreachable!("local with non ident-pattern"), - }), - } - }) - .collect(), - } + source: source.map(|ast| Either::Right(ast.to_node(&root))), + }]; + } + (&b.0.store, &b.1.store) + } + }; + source_map + .patterns_for_binding(self.binding_id) + .iter() + .map(|&definition| { + let src = source_map.pat_syntax(definition).unwrap(); // Hmm... + let root = src.file_syntax(db); + LocalSource { + local: self, + source: src.map(|ast| match ast.to_node(&root) { + Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), + _ => unreachable!("local with non ident-pattern"), + }), + } + }) + .collect() } /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;` pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource { - let (body, source_map) = db.body_with_source_map(self.parent); - match body.self_param.zip(source_map.self_param_syntax()) { - Some((param, source)) if param == self.binding_id => { - let root = source.file_syntax(db); + let b; + let s; + let (_, source_map) = match self.parent { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + s = ExpressionStore::with_source_map(db, generic_def_id.into()); + (s.0, s.1) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => { + b = Body::with_source_map(db, def_with_body_id); + if let Some((param, source)) = b.0.self_param.zip(b.1.self_param_syntax()) + && param == self.binding_id + { + let root = source.file_syntax(db); + return LocalSource { + local: self, + source: source.map(|ast| Either::Right(ast.to_node(&root))), + }; + } + (&b.0.store, &b.1.store) + } + }; + source_map + .patterns_for_binding(self.binding_id) + .first() + .map(|&definition| { + let src = source_map.pat_syntax(definition).unwrap(); // Hmm... + let root = src.file_syntax(db); LocalSource { local: self, - source: source.map(|ast| Either::Right(ast.to_node(&root))), + source: src.map(|ast| match ast.to_node(&root) { + Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), + _ => unreachable!("local with non ident-pattern"), + }), } - } - _ => source_map - .patterns_for_binding(self.binding_id) - .first() - .map(|&definition| { - let src = source_map.pat_syntax(definition).unwrap(); // Hmm... - let root = src.file_syntax(db); - LocalSource { - local: self, - source: src.map(|ast| match ast.to_node(&root) { - Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), - _ => unreachable!("local with non ident-pattern"), - }), - } - }) - .unwrap(), - } + }) + .unwrap() } } @@ -4457,7 +4528,7 @@ impl ToolModule { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Label { - pub(crate) parent: DefWithBodyId, + pub(crate) parent: ExpressionStoreOwnerId, pub(crate) label_id: LabelId, } @@ -4466,13 +4537,12 @@ impl Label { self.parent(db).module(db) } - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.parent.into() } pub fn name(self, db: &dyn HirDatabase) -> Name { - let body = db.body(self.parent); - body[self.label_id].name.clone() + ExpressionStore::of(db, self.parent)[self.label_id].name.clone() } } @@ -4781,7 +4851,7 @@ impl Impl { result.extend(module.scope.builtin_derive_impls().map(Impl::from)); for unnamed_const in module.scope.unnamed_consts() { - for (_, block_def_map) in db.body(unnamed_const.into()).blocks(db) { + for (_, block_def_map) in Body::of(db, unnamed_const.into()).blocks(db) { extend_with_def_map(db, block_def_map, result); } } @@ -4938,14 +5008,14 @@ impl Impl { pub fn is_negative(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::NEGATIVE), + AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::NEGATIVE), AnyImplId::BuiltinDeriveImplId(_) => false, } } pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::UNSAFE), + AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::UNSAFE), AnyImplId::BuiltinDeriveImplId(_) => false, } } @@ -5052,16 +5122,13 @@ impl<'db> Closure<'db> { return Vec::new(); }; let owner = db.lookup_intern_closure(id).0; - let Some(body_owner) = owner.as_def_with_body() else { - return Vec::new(); - }; - let infer = InferenceResult::for_body(db, body_owner); + let infer = InferenceResult::of(db, owner); let info = infer.closure_info(id); info.0 .iter() .cloned() .map(|capture| ClosureCapture { - owner: body_owner, + owner, closure: id, capture, _marker: PhantomCovariantLifetime::new(), @@ -5078,7 +5145,7 @@ impl<'db> Closure<'db> { let Some(body_owner) = owner.as_def_with_body() else { return Vec::new(); }; - let infer = InferenceResult::for_body(db, body_owner); + let infer = InferenceResult::of(db, body_owner); let (captures, _) = infer.closure_info(id); let env = body_param_env_from_has_crate(db, body_owner); captures.iter().map(|capture| Type { env, ty: capture.ty(db, self.subst) }).collect() @@ -5091,7 +5158,7 @@ impl<'db> Closure<'db> { let Some(body_owner) = owner.as_def_with_body() else { return FnTrait::FnOnce; }; - let infer = InferenceResult::for_body(db, body_owner); + let infer = InferenceResult::of(db, body_owner); let info = infer.closure_info(id); info.1.into() } @@ -5174,7 +5241,7 @@ impl FnTrait { #[derive(Clone, Debug, PartialEq, Eq)] pub struct ClosureCapture<'db> { - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, closure: InternedClosureId, capture: hir_ty::CapturedItem, _marker: PhantomCovariantLifetime<'db>, @@ -5233,17 +5300,16 @@ pub enum CaptureKind { #[derive(Debug, Clone)] pub struct CaptureUsages { - parent: DefWithBodyId, + parent: ExpressionStoreOwnerId, spans: SmallVec<[mir::MirSpan; 3]>, } impl CaptureUsages { pub fn sources(&self, db: &dyn HirDatabase) -> Vec<CaptureUsageSource> { - let (body, source_map) = db.body_with_source_map(self.parent); - + let (body, source_map) = ExpressionStore::with_source_map(db, self.parent); let mut result = Vec::with_capacity(self.spans.len()); for &span in self.spans.iter() { - let is_ref = span.is_ref_span(&body); + let is_ref = span.is_ref_span(body); match span { mir::MirSpan::ExprId(expr) => { if let Ok(expr) = source_map.expr_syntax(expr) { @@ -5411,7 +5477,7 @@ impl<'db> Type<'db> { fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool { match adt_id { AdtId::StructId(s) => { - let flags = db.struct_signature(s).flags; + let flags = StructSignature::of(db, s).flags; flags.contains(StructFlags::IS_PHANTOM_DATA) } AdtId::UnionId(_) | AdtId::EnumId(_) => false, @@ -6005,8 +6071,8 @@ impl<'db> Type<'db> { // for a nicer IDE experience. However, method resolution is always done on real code (either // existing code or code to be inserted), and there using PostAnalysis is dangerous - we may // suggest invalid methods. So we're using the TypingMode of the body we're in. - let typing_mode = if let Some(body_owner) = resolver.body_owner() { - TypingMode::analysis_in_body(interner, body_owner.into()) + let typing_mode = if let Some(store_owner) = resolver.expression_store_owner() { + TypingMode::analysis_in_body(interner, store_owner.into()) } else { TypingMode::non_body_analysis() }; @@ -6411,18 +6477,19 @@ impl<'db> TypeNs<'db> { #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct InlineAsmOperand { - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, expr: ExprId, index: usize, } impl InlineAsmOperand { - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.owner.into() } pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> { - match &db.body(self.owner)[self.expr] { + let body = ExpressionStore::of(db, self.owner); + match &body[self.expr] { hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(), _ => None, } @@ -7183,7 +7250,7 @@ fn param_env_from_resolver<'db>( ParamEnvAndCrate { param_env: resolver .generic_def() - .map_or_else(ParamEnv::empty, |generic_def| db.trait_environment(generic_def)), + .map_or_else(ParamEnv::empty, |generic_def| db.trait_environment(generic_def.into())), krate: resolver.krate(), } } @@ -7192,14 +7259,14 @@ fn param_env_from_has_crate<'db>( db: &'db dyn HirDatabase, id: impl hir_def::HasModule + Into<GenericDefId> + Copy, ) -> ParamEnvAndCrate<'db> { - ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(id.into().into()), krate: id.krate(db) } } fn body_param_env_from_has_crate<'db>( db: &'db dyn HirDatabase, id: impl hir_def::HasModule + Into<DefWithBodyId> + Copy, ) -> ParamEnvAndCrate<'db> { - ParamEnvAndCrate { param_env: db.trait_environment_for_body(id.into()), krate: id.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(id.into().into()), krate: id.krate(db) } } fn empty_param_env<'db>(krate: base_db::Crate) -> ParamEnvAndCrate<'db> { |