Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21859 from Veykril/push-nzszskmysqqm
Hookup Signature Inference in more places
77 files changed, 1666 insertions, 1440 deletions
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index ba0efe0ff1..9c7f4943db 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -9,24 +9,16 @@ use triomphe::Arc; use crate::{ AnonConstId, AnonConstLoc, AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, - DefWithBodyId, EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExpressionStoreOwner, - ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, - GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, MacroId, - MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, - StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, - UnionLoc, UseId, UseLoc, VariantId, + EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, + ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, + Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, + ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, + TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, attrs::AttrFlags, - expr_store::{ - Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, - }, hir::generics::GenericParams, import_map::ImportMap, item_tree::{ItemTree, file_item_tree_query}, nameres::crate_def_map, - signatures::{ - ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature, - StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, - }, visibility::{self, Visibility}, }; @@ -106,144 +98,10 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { #[salsa::invoke(macro_def)] fn macro_def(&self, m: MacroId) -> MacroDefId; - // region:data - - #[salsa::tracked] - fn trait_signature(&self, trait_: TraitId) -> Arc<TraitSignature> { - self.trait_signature_with_source_map(trait_).0 - } - - #[salsa::tracked] - fn impl_signature(&self, impl_: ImplId) -> Arc<ImplSignature> { - self.impl_signature_with_source_map(impl_).0 - } - - #[salsa::tracked] - fn struct_signature(&self, struct_: StructId) -> Arc<StructSignature> { - self.struct_signature_with_source_map(struct_).0 - } - - #[salsa::tracked] - fn union_signature(&self, union_: UnionId) -> Arc<UnionSignature> { - self.union_signature_with_source_map(union_).0 - } - - #[salsa::tracked] - fn enum_signature(&self, e: EnumId) -> Arc<EnumSignature> { - self.enum_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn const_signature(&self, e: ConstId) -> Arc<ConstSignature> { - self.const_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn static_signature(&self, e: StaticId) -> Arc<StaticSignature> { - self.static_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn function_signature(&self, e: FunctionId) -> Arc<FunctionSignature> { - self.function_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn type_alias_signature(&self, e: TypeAliasId) -> Arc<TypeAliasSignature> { - self.type_alias_signature_with_source_map(e).0 - } - - #[salsa::invoke(TraitSignature::query)] - fn trait_signature_with_source_map( - &self, - trait_: TraitId, - ) -> (Arc<TraitSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(ImplSignature::query)] - fn impl_signature_with_source_map( - &self, - impl_: ImplId, - ) -> (Arc<ImplSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(StructSignature::query)] - fn struct_signature_with_source_map( - &self, - struct_: StructId, - ) -> (Arc<StructSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(UnionSignature::query)] - fn union_signature_with_source_map( - &self, - union_: UnionId, - ) -> (Arc<UnionSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(EnumSignature::query)] - fn enum_signature_with_source_map( - &self, - e: EnumId, - ) -> (Arc<EnumSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(ConstSignature::query)] - fn const_signature_with_source_map( - &self, - e: ConstId, - ) -> (Arc<ConstSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(StaticSignature::query)] - fn static_signature_with_source_map( - &self, - e: StaticId, - ) -> (Arc<StaticSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(FunctionSignature::query)] - fn function_signature_with_source_map( - &self, - e: FunctionId, - ) -> (Arc<FunctionSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(TypeAliasSignature::query)] - fn type_alias_signature_with_source_map( - &self, - e: TypeAliasId, - ) -> (Arc<TypeAliasSignature>, Arc<ExpressionStoreSourceMap>); - - // endregion:data - - #[salsa::invoke(Body::body_with_source_map_query)] - #[salsa::lru(512)] - fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); - - #[salsa::invoke(Body::body_query)] - fn body(&self, def: DefWithBodyId) -> Arc<Body>; - - #[salsa::invoke(ExprScopes::body_expr_scopes_query)] - fn body_expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; - - #[salsa::invoke(ExprScopes::sig_expr_scopes_query)] - fn sig_expr_scopes(&self, def: GenericDefId) -> Arc<ExprScopes>; - - #[salsa::transparent] - #[salsa::invoke(ExprScopes::expr_scopes_query)] - fn expr_scopes(&self, def: ExpressionStoreOwner) -> Arc<ExprScopes>; - #[salsa::transparent] #[salsa::invoke(GenericParams::new)] fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; - #[salsa::transparent] - #[salsa::invoke(GenericParams::generic_params_and_store)] - fn generic_params_and_store( - &self, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>); - - #[salsa::transparent] - #[salsa::invoke(GenericParams::generic_params_and_store_and_source_map)] - fn generic_params_and_store_and_source_map( - &self, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>); - #[salsa::invoke(ImportMap::import_map_query)] fn import_map(&self, krate: Crate) -> Arc<ImportMap>; diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs index b5436f3ba3..1ae89e170d 100644 --- a/crates/hir-def/src/expr_store.rs +++ b/crates/hir-def/src/expr_store.rs @@ -9,10 +9,7 @@ pub mod scope; #[cfg(test)] mod tests; -use std::{ - ops::{Deref, Index}, - sync::LazyLock, -}; +use std::ops::{Deref, Index}; use cfg::{CfgExpr, CfgOptions}; use either::Either; @@ -23,11 +20,10 @@ use smallvec::SmallVec; use span::{Edition, SyntaxContext}; use syntax::{AstPtr, SyntaxNodePtr, ast}; use thin_vec::ThinVec; -use triomphe::Arc; use tt::TextRange; use crate::{ - BlockId, SyntheticSyntax, + AdtId, BlockId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, db::DefDatabase, expr_store::path::Path, hir::{ @@ -431,13 +427,85 @@ impl ExpressionStoreBuilder { } impl ExpressionStore { - pub fn empty_singleton() -> (Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) { - static EMPTY: LazyLock<(Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>)> = - LazyLock::new(|| { - let (store, source_map) = ExpressionStoreBuilder::default().finish(); - (Arc::new(store), Arc::new(source_map)) - }); - EMPTY.clone() + pub fn of(db: &dyn DefDatabase, def: ExpressionStoreOwnerId) -> &ExpressionStore { + match def { + ExpressionStoreOwnerId::Signature(def) => { + use crate::signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, + StaticSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, + }; + match def { + GenericDefId::AdtId(AdtId::EnumId(id)) => &EnumSignature::of(db, id).store, + GenericDefId::AdtId(AdtId::StructId(id)) => &StructSignature::of(db, id).store, + GenericDefId::AdtId(AdtId::UnionId(id)) => &UnionSignature::of(db, id).store, + GenericDefId::ConstId(id) => &ConstSignature::of(db, id).store, + GenericDefId::FunctionId(id) => &FunctionSignature::of(db, id).store, + GenericDefId::ImplId(id) => &ImplSignature::of(db, id).store, + GenericDefId::StaticId(id) => &StaticSignature::of(db, id).store, + GenericDefId::TraitId(id) => &TraitSignature::of(db, id).store, + GenericDefId::TypeAliasId(id) => &TypeAliasSignature::of(db, id).store, + } + } + ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store, + } + } + + pub fn with_source_map( + db: &dyn DefDatabase, + def: ExpressionStoreOwnerId, + ) -> (&ExpressionStore, &ExpressionStoreSourceMap) { + match def { + ExpressionStoreOwnerId::Signature(def) => { + use crate::signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, + StaticSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, + }; + match def { + GenericDefId::AdtId(AdtId::EnumId(id)) => { + let sig = EnumSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::AdtId(AdtId::StructId(id)) => { + let sig = StructSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::AdtId(AdtId::UnionId(id)) => { + let sig = UnionSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::ConstId(id) => { + let sig = ConstSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::FunctionId(id) => { + let sig = FunctionSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::ImplId(id) => { + let sig = ImplSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::StaticId(id) => { + let sig = StaticSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::TraitId(id) => { + let sig = TraitSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::TypeAliasId(id) => { + let sig = TypeAliasSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + } + } + ExpressionStoreOwnerId::Body(body) => { + let (store, sm) = Body::with_source_map(db, body); + (&store.store, &sm.store) + } + } } /// Returns all const expression root `ExprId`s found in this store. diff --git a/crates/hir-def/src/expr_store/body.rs b/crates/hir-def/src/expr_store/body.rs index ad8fa73ad8..60aaba5b84 100644 --- a/crates/hir-def/src/expr_store/body.rs +++ b/crates/hir-def/src/expr_store/body.rs @@ -68,11 +68,10 @@ impl ops::Deref for BodySourceMap { } } +#[salsa::tracked] impl Body { - pub(crate) fn body_with_source_map_query( - db: &dyn DefDatabase, - def: DefWithBodyId, - ) -> (Arc<Body>, Arc<BodySourceMap>) { + #[salsa::tracked(lru = 512, returns(ref))] + pub fn with_source_map(db: &dyn DefDatabase, def: DefWithBodyId) -> (Arc<Body>, BodySourceMap) { let _p = tracing::info_span!("body_with_source_map_query").entered(); let mut params = None; @@ -106,13 +105,16 @@ impl Body { let module = def.module(db); let (body, source_map) = lower_body(db, def, file_id, module, params, body, is_async_fn); - (Arc::new(body), Arc::new(source_map)) + (Arc::new(body), source_map) } - pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { - db.body_with_source_map(def).0 + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { + Self::with_source_map(db, def).0.clone() } +} +impl Body { pub fn pretty_print( &self, db: &dyn DefDatabase, diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 67ce5eafc6..3ed1b58741 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -53,6 +53,7 @@ use crate::{ item_tree::FieldsShape, lang_item::{LangItemTarget, LangItems}, nameres::{DefMap, LocalDefMap, MacroSubNs, block_def_map}, + signatures::StructSignature, type_ref::{ ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef, @@ -200,13 +201,13 @@ pub(crate) fn lower_generic_params( file_id: HirFileId, param_list: Option<ast::GenericParamList>, where_clause: Option<ast::WhereClause>, -) -> (Arc<ExpressionStore>, Arc<GenericParams>, ExpressionStoreSourceMap) { +) -> (ExpressionStore, Arc<GenericParams>, ExpressionStoreSourceMap) { let mut expr_collector = ExprCollector::signature(db, module, file_id); let mut collector = generics::GenericParamsCollector::new(def); collector.lower(&mut expr_collector, param_list, where_clause); let params = collector.finish(); let (store, source_map) = expr_collector.store.finish(); - (Arc::new(store), params, source_map) + (store, params, source_map) } pub(crate) fn lower_impl( @@ -2363,7 +2364,7 @@ impl<'db> ExprCollector<'db> { } Some(ModuleDefId::AdtId(AdtId::StructId(s))) // FIXME: This can cause a cycle if the user is writing invalid code - if self.db.struct_signature(s).shape != FieldsShape::Record => + if StructSignature::of(self.db, s).shape != FieldsShape::Record => { (None, Pat::Path(name.into())) } diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 35f3cd114e..405ebe9b7b 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -168,8 +168,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi match owner { GenericDefId::AdtId(id) => match id { AdtId::StructId(id) => { - let signature = db.struct_signature(id); - print_struct(db, id, &signature, edition) + let signature = StructSignature::of(db, id); + print_struct(db, id, signature, edition) } AdtId::UnionId(id) => { format!("unimplemented {id:?}") @@ -180,8 +180,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi }, GenericDefId::ConstId(id) => format!("unimplemented {id:?}"), GenericDefId::FunctionId(id) => { - let signature = db.function_signature(id); - print_function(db, id, &signature, edition) + let signature = FunctionSignature::of(db, id); + print_function(db, id, signature, edition) } GenericDefId::ImplId(id) => format!("unimplemented {id:?}"), GenericDefId::StaticId(id) => format!("unimplemented {id:?}"), diff --git a/crates/hir-def/src/expr_store/scope.rs b/crates/hir-def/src/expr_store/scope.rs index 43ce053836..2250cf5f16 100644 --- a/crates/hir-def/src/expr_store/scope.rs +++ b/crates/hir-def/src/expr_store/scope.rs @@ -1,13 +1,15 @@ //! Name resolution for expressions. use hir_expand::{MacroDefId, name::Name}; use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx}; -use triomphe::Arc; use crate::{ - BlockId, DefWithBodyId, ExpressionStoreOwner, GenericDefId, + BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, db::DefDatabase, expr_store::{Body, ExpressionStore, HygieneId}, - hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement}, + hir::{ + Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement, + generics::GenericParams, + }, }; pub type ScopeId = Idx<ScopeData>; @@ -50,36 +52,33 @@ pub struct ScopeData { entries: IdxRange<ScopeEntry>, } +#[salsa::tracked] impl ExprScopes { - pub(crate) fn expr_scopes_query( - db: &dyn DefDatabase, - def: ExpressionStoreOwner, - ) -> Arc<ExprScopes> { - match def { - ExpressionStoreOwner::Body(def) => db.body_expr_scopes(def), - ExpressionStoreOwner::Signature(def) => db.sig_expr_scopes(def), - } - } - - pub(crate) fn body_expr_scopes_query( - db: &dyn DefDatabase, - def: DefWithBodyId, - ) -> Arc<ExprScopes> { - let body = db.body(def); - let mut scopes = ExprScopes::new_body(&body); + #[salsa::tracked(returns(ref))] + pub fn body_expr_scopes(db: &dyn DefDatabase, def: DefWithBodyId) -> ExprScopes { + let body = Body::of(db, def); + let mut scopes = ExprScopes::new_body(body); scopes.shrink_to_fit(); - Arc::new(scopes) + scopes } - pub(crate) fn sig_expr_scopes_query( - db: &dyn DefDatabase, - def: GenericDefId, - ) -> Arc<ExprScopes> { - let (_, store) = db.generic_params_and_store(def); + #[salsa::tracked(returns(ref))] + pub fn sig_expr_scopes(db: &dyn DefDatabase, def: GenericDefId) -> ExprScopes { + let (_, store) = GenericParams::of(db, def); let roots = store.signature_const_expr_roots(); - let mut scopes = ExprScopes::new_store(&store, roots); + let mut scopes = ExprScopes::new_store(store, roots); scopes.shrink_to_fit(); - Arc::new(scopes) + scopes + } +} + +impl ExprScopes { + #[inline] + pub fn of(db: &dyn DefDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &ExprScopes { + match def.into() { + ExpressionStoreOwnerId::Body(def) => Self::body_expr_scopes(db, def), + ExpressionStoreOwnerId::Signature(def) => Self::sig_expr_scopes(db, def), + } } pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { @@ -367,7 +366,9 @@ mod tests { use test_utils::{assert_eq_text, extract_offset}; use crate::{ - DefWithBodyId, FunctionId, ModuleDefId, db::DefDatabase, nameres::crate_def_map, + DefWithBodyId, FunctionId, ModuleDefId, + expr_store::{Body, scope::ExprScopes}, + nameres::crate_def_map, test_db::TestDB, }; @@ -404,8 +405,8 @@ mod tests { let marker: ast::PathExpr = find_node_at_offset(&file_syntax, offset).unwrap(); let function = find_function(&db, file_id); - let scopes = db.expr_scopes(DefWithBodyId::from(function).into()); - let (_body, source_map) = db.body_with_source_map(function.into()); + let scopes = ExprScopes::of(&db, DefWithBodyId::from(function)); + let (_body, source_map) = Body::with_source_map(&db, function.into()); let expr_id = source_map .node_expr(InFile { file_id: editioned_file_id.into(), value: &marker.into() }) @@ -563,8 +564,8 @@ fn foo() { let function = find_function(&db, file_id); - let scopes = db.expr_scopes(DefWithBodyId::from(function).into()); - let (_, source_map) = db.body_with_source_map(function.into()); + let scopes = ExprScopes::body_expr_scopes(&db, DefWithBodyId::from(function)); + let (_, source_map) = Body::with_source_map(&db, function.into()); let expr_scope = { let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); diff --git a/crates/hir-def/src/expr_store/tests/body.rs b/crates/hir-def/src/expr_store/tests/body.rs index 8f857aeeff..985cd96662 100644 --- a/crates/hir-def/src/expr_store/tests/body.rs +++ b/crates/hir-def/src/expr_store/tests/body.rs @@ -4,11 +4,10 @@ use crate::{DefWithBodyId, ModuleDefId, hir::MatchArm, nameres::crate_def_map, t use expect_test::{Expect, expect}; use la_arena::RawIdx; use test_fixture::WithFixture; -use triomphe::Arc; use super::super::*; -fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) { +fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, DefWithBodyId) { let db = TestDB::with_files(ra_fixture); let krate = db.fetch_test_crate(); @@ -24,8 +23,27 @@ fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, } let fn_def = fn_def.unwrap().into(); - let body = db.body(fn_def); - (db, body, fn_def) + Body::of(&db, fn_def); + (db, fn_def) +} + +fn pretty_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { + let db = TestDB::with_files(ra_fixture); + + let krate = db.fetch_test_crate(); + let def_map = crate_def_map(&db, krate); + let mut fn_def = None; + 'outer: for (_, module) in def_map.modules() { + for decl in module.scope.declarations() { + if let ModuleDefId::FunctionId(it) = decl { + fn_def = Some(it); + break 'outer; + } + } + } + let fn_def = fn_def.unwrap().into(); + + expect.assert_eq(&Body::of(&db, fn_def).pretty_print(&db, fn_def, Edition::CURRENT)); } fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { @@ -144,7 +162,7 @@ mod m { #[test] fn desugar_for_loop() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: iterator fn main() { @@ -154,9 +172,7 @@ fn main() { } } "#, - ); - - expect![[r#" + expect![[r#" fn main() { match builtin#lang(into_iter)( 0..10, @@ -173,13 +189,13 @@ fn main() { } }, } - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ); } #[test] fn desugar_builtin_format_args_before_1_89_0() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt_before_1_89_0 fn main() { @@ -188,9 +204,7 @@ fn main() { builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!"); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -256,13 +270,13 @@ fn main() { } }, ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn desugar_builtin_format_args_before_1_93_0() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt_before_1_93_0 fn main() { @@ -271,9 +285,7 @@ fn main() { builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!"); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -339,13 +351,13 @@ fn main() { ) } }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn desugar_builtin_format_args() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt fn main() { @@ -356,9 +368,7 @@ fn main() { builtin#format_args("hello world", orphan = ()); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -392,13 +402,13 @@ fn main() { "hello world", ) }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn test_macro_hygiene() { - let (db, body, def) = lower( + pretty_print( r##" //- minicore: fmt, from //- /main.rs @@ -428,10 +438,7 @@ impl SsrError { } } "##, - ); - - assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]); - expect![[r#" + expect![[r#" fn main() { _ = ra_test_fixture::error::SsrError::new( { @@ -449,13 +456,13 @@ impl SsrError { } }, ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn regression_10300() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: concat, panic, fmt_before_1_89_0 mod private { @@ -472,16 +479,7 @@ fn f(a: i32, b: u32) -> String { m!(); } "#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" + expect![[r#" fn f(a, b) { { core::panicking::panic_fmt( @@ -497,8 +495,8 @@ fn f(a: i32, b: u32) -> String { ), ); }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] @@ -507,7 +505,7 @@ fn destructuring_assignment_tuple_macro() { // but in destructuring assignment it is valid, because `m!()()` is a valid expression, and destructuring // assignments start their lives as expressions. So we have to do the same. - let (db, body, def) = lower( + pretty_print( r#" struct Bar(); @@ -519,25 +517,16 @@ fn foo() { m!()() = Bar(); } "#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" + expect![[r#" fn foo() { Bar() = Bar(); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn shadowing_record_variant() { - let (_, body, _) = lower( + let (db, def) = lower( r#" enum A { B { field: i32 }, @@ -550,6 +539,7 @@ fn f() { } "#, ); + let body = Body::of(&db, def); assert_eq!(body.assert_expr_only().bindings.len(), 1, "should have a binding for `B`"); assert_eq!( body[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(), @@ -560,39 +550,35 @@ fn f() { #[test] fn regression_pretty_print_bind_pat() { - let (db, body, owner) = lower( + pretty_print( r#" fn foo() { let v @ u = 123; } "#, - ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - - expect![[r#" + expect![[r#" fn foo() { let v @ u = 123; - }"#]] - .assert_eq(&printed); + }"#]], + ); } #[test] fn skip_skips_body() { - let (db, body, owner) = lower( + pretty_print( r#" #[rust_analyzer::skip] async fn foo(a: (), b: i32) -> u32 { 0 + 1 + b() } "#, + expect!["fn foo(�, �) �"], ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - expect!["fn foo(�, �) �"].assert_eq(&printed); } #[test] fn range_bounds_are_hir_exprs() { - let (_, body, _) = lower( + let (db, body) = lower( r#" pub const L: i32 = 6; mod x { @@ -607,6 +593,7 @@ const fn f(x: i32) -> i32 { }"#, ); + let body = Body::of(&db, body); let mtch_arms = body .assert_expr_only() .exprs @@ -635,7 +622,7 @@ const fn f(x: i32) -> i32 { #[test] fn print_hir_precedences() { - let (db, body, def) = lower( + pretty_print( r#" fn main() { _ = &(1 - (2 - 3) + 4 * 5 * (6 + 7)); @@ -646,9 +633,7 @@ fn main() { let _ = &mut (*r as i32) } "#, - ); - - expect![[r#" + expect![[r#" fn main() { _ = &((1 - (2 - 3)) + (4 * 5) * (6 + 7)); _ = 1 + 2 < 3 && true && 4 < 5 && (a || b || c) || d && e; @@ -656,24 +641,22 @@ fn main() { break a && b || (return) || (return 2); let r = &2; let _ = &mut (*r as i32); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn async_fn_weird_param_patterns() { - let (db, body, def) = lower( + pretty_print( r#" async fn main(&self, param1: i32, ref mut param2: i32, _: i32, param4 @ _: i32, 123: i32) {} "#, - ); - - expect![[r#" + expect![[r#" fn main(self, param1, mut param2, mut <ra@gennew>0, param4 @ _, mut <ra@gennew>1) async { let ref mut param2 = param2; let _ = <ra@gennew>0; let 123 = <ra@gennew>1; {} - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } diff --git a/crates/hir-def/src/expr_store/tests/signatures.rs b/crates/hir-def/src/expr_store/tests/signatures.rs index f1db00cf6a..5e0184dfad 100644 --- a/crates/hir-def/src/expr_store/tests/signatures.rs +++ b/crates/hir-def/src/expr_store/tests/signatures.rs @@ -2,6 +2,7 @@ use crate::{ GenericDefId, ModuleDefId, expr_store::pretty::{print_function, print_struct}, nameres::crate_def_map, + signatures::{FunctionSignature, StructSignature}, test_db::TestDB, }; use expect_test::{Expect, expect}; @@ -41,7 +42,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe out += &print_struct( &db, struct_id, - &db.struct_signature(struct_id), + StructSignature::of(&db, struct_id), Edition::CURRENT, ); } @@ -53,7 +54,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe out += &print_function( &db, function_id, - &db.function_signature(function_id), + FunctionSignature::of(&db, function_id), Edition::CURRENT, ) } diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs index 022f8adfdb..41767131fc 100644 --- a/crates/hir-def/src/hir/generics.rs +++ b/crates/hir-def/src/hir/generics.rs @@ -11,6 +11,10 @@ use crate::{ AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId, db::DefDatabase, expr_store::{ExpressionStore, ExpressionStoreSourceMap}, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature, + StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, + }, type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId}, }; @@ -188,111 +192,90 @@ impl GenericParams { LocalTypeOrConstParamId::from_raw(RawIdx::from_u32(0)); pub fn new(db: &dyn DefDatabase, def: GenericDefId) -> Arc<GenericParams> { - match def { - GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature(it).generic_params.clone(), - GenericDefId::AdtId(AdtId::StructId(it)) => { - db.struct_signature(it).generic_params.clone() - } - GenericDefId::AdtId(AdtId::UnionId(it)) => { - db.union_signature(it).generic_params.clone() - } - GenericDefId::ConstId(_) => EMPTY.clone(), - GenericDefId::FunctionId(function_id) => { - db.function_signature(function_id).generic_params.clone() - } - GenericDefId::ImplId(impl_id) => db.impl_signature(impl_id).generic_params.clone(), - GenericDefId::StaticId(_) => EMPTY.clone(), - GenericDefId::TraitId(trait_id) => db.trait_signature(trait_id).generic_params.clone(), - GenericDefId::TypeAliasId(type_alias_id) => { - db.type_alias_signature(type_alias_id).generic_params.clone() - } - } + Self::of(db, def).0 } - pub fn generic_params_and_store( - db: &dyn DefDatabase, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>) { + pub fn of(db: &dyn DefDatabase, def: GenericDefId) -> (Arc<GenericParams>, &ExpressionStore) { match def { GenericDefId::AdtId(AdtId::EnumId(id)) => { - let sig = db.enum_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let sig = EnumSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::AdtId(AdtId::StructId(id)) => { - let sig = db.struct_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let sig = StructSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::AdtId(AdtId::UnionId(id)) => { - let sig = db.union_signature(id); - (sig.generic_params.clone(), sig.store.clone()) - } - GenericDefId::ConstId(id) => { - let sig = db.const_signature(id); - (EMPTY.clone(), sig.store.clone()) + let sig = UnionSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::FunctionId(id) => { - let sig = db.function_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let sig = FunctionSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::ImplId(id) => { - let sig = db.impl_signature(id); - (sig.generic_params.clone(), sig.store.clone()) - } - GenericDefId::StaticId(id) => { - let sig = db.static_signature(id); - (EMPTY.clone(), sig.store.clone()) + let sig = ImplSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::TraitId(id) => { - let sig = db.trait_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let sig = TraitSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) } GenericDefId::TypeAliasId(id) => { - let sig = db.type_alias_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let sig = TypeAliasSignature::of(db, id); + (sig.generic_params.clone(), &sig.store) + } + GenericDefId::ConstId(id) => { + let sig = ConstSignature::of(db, id); + (EMPTY.clone(), &sig.store) + } + GenericDefId::StaticId(id) => { + let sig = StaticSignature::of(db, id); + (EMPTY.clone(), &sig.store) } } } - pub fn generic_params_and_store_and_source_map( + pub fn with_source_map( db: &dyn DefDatabase, def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<GenericParams>, &ExpressionStore, &ExpressionStoreSourceMap) { match def { GenericDefId::AdtId(AdtId::EnumId(id)) => { - let (sig, sm) = db.enum_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = EnumSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::AdtId(AdtId::StructId(id)) => { - let (sig, sm) = db.struct_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = StructSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::AdtId(AdtId::UnionId(id)) => { - let (sig, sm) = db.union_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = UnionSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::ConstId(id) => { - let (sig, sm) = db.const_signature_with_source_map(id); - (EMPTY.clone(), sig.store.clone(), sm) + let (sig, sm) = ConstSignature::with_source_map(db, id); + (EMPTY.clone(), &sig.store, sm) } GenericDefId::FunctionId(id) => { - let (sig, sm) = db.function_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = FunctionSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::ImplId(id) => { - let (sig, sm) = db.impl_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = ImplSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::StaticId(id) => { - let (sig, sm) = db.static_signature_with_source_map(id); - (EMPTY.clone(), sig.store.clone(), sm) + let (sig, sm) = StaticSignature::with_source_map(db, id); + (EMPTY.clone(), &sig.store, sm) } GenericDefId::TraitId(id) => { - let (sig, sm) = db.trait_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = TraitSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } GenericDefId::TypeAliasId(id) => { - let (sig, sm) = db.type_alias_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = TypeAliasSignature::with_source_map(db, id); + (sig.generic_params.clone(), &sig.store, sm) } } } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index ffad5fee47..4387ef055f 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -49,7 +49,6 @@ pub mod visibility; use intern::{Interned, Symbol}; pub use rustc_abi as layout; use thin_vec::ThinVec; -use triomphe::Arc; pub use crate::signatures::LocalFieldId; @@ -96,7 +95,9 @@ use crate::{ block_def_map, crate_def_map, crate_local_def_map, diagnostics::DefDiagnostics, }, - signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields}, + signatures::{ + ConstSignature, EnumVariants, InactiveEnumVariantCode, StaticSignature, VariantFields, + }, }; type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>; @@ -264,8 +265,9 @@ impl StructId { pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -280,8 +282,9 @@ impl UnionId { pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -315,7 +318,7 @@ impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); #[derive(Debug, Hash, PartialEq, Eq, Clone)] pub struct AnonConstLoc { /// The owner store containing this expression. - pub owner: ExpressionStoreOwner, + pub owner: ExpressionStoreOwnerId, /// The ExprId within the owner's ExpressionStore that is the root /// of this anonymous const expression. pub expr: ExprId, @@ -399,8 +402,9 @@ impl EnumVariantId { pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -739,10 +743,10 @@ impl GeneralConstId { pub fn name(self, db: &dyn DefDatabase) -> String { match self { GeneralConstId::StaticId(it) => { - db.static_signature(it).name.display(db, Edition::CURRENT).to_string() + StaticSignature::of(db, it).name.display(db, Edition::CURRENT).to_string() } GeneralConstId::ConstId(const_id) => { - db.const_signature(const_id).name.as_ref().map_or_else( + ConstSignature::of(db, const_id).name.as_ref().map_or_else( || "_".to_owned(), |name| name.display(db, Edition::CURRENT).to_string(), ) @@ -837,20 +841,21 @@ impl_from!( /// This is used for queries that operate on expression stores generically, /// such as `expr_scopes`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum ExpressionStoreOwner { +pub enum ExpressionStoreOwnerId { Signature(GenericDefId), Body(DefWithBodyId), } -impl ExpressionStoreOwner { +impl ExpressionStoreOwnerId { + // FIXME: Check callers of this, this method likely can be removed pub fn as_def_with_body(self) -> Option<DefWithBodyId> { if let Self::Body(v) = self { Some(v) } else { None } } pub fn generic_def(self, db: &dyn DefDatabase) -> GenericDefId { match self { - ExpressionStoreOwner::Signature(generic_def_id) => generic_def_id, - ExpressionStoreOwner::Body(def_with_body_id) => match def_with_body_id { + ExpressionStoreOwnerId::Signature(generic_def_id) => generic_def_id, + ExpressionStoreOwnerId::Body(def_with_body_id) => match def_with_body_id { DefWithBodyId::FunctionId(id) => GenericDefId::FunctionId(id), DefWithBodyId::StaticId(id) => GenericDefId::StaticId(id), DefWithBodyId::ConstId(id) => GenericDefId::ConstId(id), @@ -860,15 +865,15 @@ impl ExpressionStoreOwner { } } -impl From<GenericDefId> for ExpressionStoreOwner { +impl From<GenericDefId> for ExpressionStoreOwnerId { fn from(id: GenericDefId) -> Self { - ExpressionStoreOwner::Signature(id) + ExpressionStoreOwnerId::Signature(id) } } -impl From<DefWithBodyId> for ExpressionStoreOwner { +impl From<DefWithBodyId> for ExpressionStoreOwnerId { fn from(id: DefWithBodyId) -> Self { - ExpressionStoreOwner::Body(id) + ExpressionStoreOwnerId::Body(id) } } @@ -1028,8 +1033,9 @@ impl VariantId { pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self); + (&r.0, &r.1) } pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId { @@ -1230,11 +1236,11 @@ impl HasModule for DefWithBodyId { } } -impl HasModule for ExpressionStoreOwner { +impl HasModule for ExpressionStoreOwnerId { fn module(&self, db: &dyn DefDatabase) -> ModuleId { match self { - ExpressionStoreOwner::Signature(def) => def.module(db), - ExpressionStoreOwner::Body(def) => def.module(db), + ExpressionStoreOwnerId::Signature(def) => def.module(db), + ExpressionStoreOwnerId::Body(def) => def.module(db), } } } diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index 8ee93dcaa3..8317c56caf 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -45,6 +45,7 @@ use tt::{TextRange, TextSize}; use crate::{ AdtId, Lookup, ModuleDefId, db::DefDatabase, + expr_store::Body, nameres::{DefMap, ModuleSource, crate_def_map}, src::HasSource, test_db::TestDB, @@ -276,7 +277,7 @@ fn resolve_macro_call_id( _ => continue, }; - let (body, sm) = db.body_with_source_map(body); + let (body, sm) = Body::with_source_map(db, body); if let Some(it) = body .blocks(db) .find_map(|block| resolve_macro_call_id(db, block.1, ast_id, ast_ptr)) diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 38b461770c..9ffa80346c 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -17,7 +17,7 @@ use triomphe::Arc; use crate::{ AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, - ExpressionStoreOwner, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, + ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UseId, VariantId, @@ -36,6 +36,7 @@ use crate::{ lang_item::LangItemTarget, nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map}, per_ns::PerNs, + signatures::ImplSignature, src::HasSource, type_ref::LifetimeRef, visibility::{RawVisibility, Visibility}, @@ -65,13 +66,13 @@ impl fmt::Debug for ModuleItemMap<'_> { } #[derive(Clone)] -struct ExprScope { - owner: ExpressionStoreOwner, - expr_scopes: Arc<ExprScopes>, +struct ExprScope<'db> { + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, } -impl fmt::Debug for ExprScope { +impl fmt::Debug for ExprScope<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ExprScope") .field("owner", &self.owner) @@ -88,7 +89,7 @@ enum Scope<'db> { /// generic for ADTs and impls. GenericParams { def: GenericDefId, params: Arc<GenericParams> }, /// Local bindings - ExprScope(ExprScope), + ExprScope(ExprScope<'db>), /// Macro definition inside bodies that affects all paths after it in the same block. MacroDefScope(MacroDefId), } @@ -653,7 +654,7 @@ impl<'db> Resolver<'db> { match scope { Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()), &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => { - let impl_data = db.impl_signature(impl_); + let impl_data = ImplSignature::of(db, impl_); if let Some(target_trait) = impl_data.target_trait && let Some(TypeNs::TraitId(trait_)) = self .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path]) @@ -736,12 +737,9 @@ impl<'db> Resolver<'db> { }) } - pub fn body_owner(&self) -> Option<DefWithBodyId> { + pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwnerId> { self.scopes().find_map(|scope| match scope { - Scope::ExprScope(it) => match it.owner { - ExpressionStoreOwner::Body(def) => Some(def), - ExpressionStoreOwner::Signature(_) => None, - }, + Scope::ExprScope(it) => Some(it.owner), _ => None, }) } @@ -857,7 +855,7 @@ impl<'db> Resolver<'db> { pub fn update_to_inner_scope( &mut self, db: &'db dyn DefDatabase, - owner: impl Into<ExpressionStoreOwner>, + owner: impl Into<ExpressionStoreOwnerId>, expr_id: ExprId, ) -> UpdateGuard { self.update_to_inner_scope_(db, owner.into(), expr_id) @@ -866,25 +864,21 @@ impl<'db> Resolver<'db> { fn update_to_inner_scope_( &mut self, db: &'db dyn DefDatabase, - owner: ExpressionStoreOwner, + owner: ExpressionStoreOwnerId, expr_id: ExprId, ) -> UpdateGuard { #[inline(always)] fn append_expr_scope<'db>( db: &'db dyn DefDatabase, resolver: &mut Resolver<'db>, - owner: ExpressionStoreOwner, - expr_scopes: &Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) { if let Some(macro_id) = expr_scopes.macro_def(scope_id) { resolver.scopes.push(Scope::MacroDefScope(**macro_id)); } - resolver.scopes.push(Scope::ExprScope(ExprScope { - owner, - expr_scopes: expr_scopes.clone(), - scope_id, - })); + resolver.scopes.push(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); let local_def_map = block.lookup(db).module.only_local_def_map(db); @@ -902,21 +896,20 @@ impl<'db> Resolver<'db> { let start = self.scopes.len(); let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_))); match innermost_scope { - Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => { - let expr_scopes = expr_scopes.clone(); + Some(&Scope::ExprScope(ExprScope { scope_id, expr_scopes, owner })) => { let scope_chain = expr_scopes .scope_chain(expr_scopes.scope_for(expr_id)) .take_while(|&it| it != scope_id); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } _ => { - let expr_scopes = db.expr_scopes(owner); + let expr_scopes = ExprScopes::of(db, owner); let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id)); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } } @@ -1072,21 +1065,21 @@ impl<'db> Scope<'db> { pub fn resolver_for_scope( db: &dyn DefDatabase, - owner: impl Into<ExpressionStoreOwner> + HasResolver, + owner: impl Into<ExpressionStoreOwnerId> + HasResolver, scope_id: Option<ScopeId>, ) -> Resolver<'_> { let store_owner = owner.into(); let r = store_owner.resolver(db); - let scopes = db.expr_scopes(store_owner); + let scopes = ExprScopes::of(db, store_owner); resolver_for_scope_(db, scopes, scope_id, r, store_owner) } fn resolver_for_scope_<'db>( db: &'db dyn DefDatabase, - scopes: Arc<ExprScopes>, + scopes: &'db ExprScopes, scope_id: Option<ScopeId>, mut r: Resolver<'db>, - owner: ExpressionStoreOwner, + owner: ExpressionStoreOwnerId, ) -> Resolver<'db> { let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); r.scopes.reserve(scope_chain.len()); @@ -1106,7 +1099,7 @@ fn resolver_for_scope_<'db>( r = r.push_scope(Scope::MacroDefScope(**macro_id)); } - r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); + r = r.push_expr_scope(owner, scopes, scope); } r } @@ -1137,8 +1130,8 @@ impl<'db> Resolver<'db> { fn push_expr_scope( self, - owner: ExpressionStoreOwner, - expr_scopes: Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) -> Resolver<'db> { self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) @@ -1422,11 +1415,11 @@ impl HasResolver for GenericDefId { } } -impl HasResolver for ExpressionStoreOwner { +impl HasResolver for ExpressionStoreOwnerId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { match self { - ExpressionStoreOwner::Signature(def) => def.resolver(db), - ExpressionStoreOwner::Body(def) => def.resolver(db), + ExpressionStoreOwnerId::Signature(def) => def.resolver(db), + ExpressionStoreOwnerId::Body(def) => def.resolver(db), } } } diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs index ce76158151..7862049f99 100644 --- a/crates/hir-def/src/signatures.rs +++ b/crates/hir-def/src/signatures.rs @@ -24,7 +24,7 @@ use crate::{ attrs::AttrFlags, db::DefDatabase, expr_store::{ - ExpressionStore, ExpressionStoreSourceMap, + Body, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreSourceMap, lower::{ ExprCollector, lower_function, lower_generic_params, lower_trait, lower_type_alias, }, @@ -44,7 +44,7 @@ fn as_name_opt(name: Option<ast::Name>) -> Name { pub struct StructSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub flags: StructFlags, pub shape: FieldsShape, } @@ -71,8 +71,18 @@ bitflags! { } } +#[salsa::tracked] impl StructSignature { - pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: StructId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: StructId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let InFile { file_id, value: source } = loc.source(db); let attrs = AttrFlags::query(db, id.into()); @@ -115,10 +125,12 @@ impl StructSignature { shape, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } +} +impl StructSignature { #[inline] pub fn repr(&self, db: &dyn DefDatabase, id: StructId) -> Option<ReprOptions> { if self.flags.contains(StructFlags::HAS_REPR) { @@ -142,12 +154,22 @@ fn adt_shape(adt_kind: ast::StructKind) -> FieldsShape { pub struct UnionSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub flags: StructFlags, } +#[salsa::tracked] impl UnionSignature { - pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: UnionId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: UnionId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let attrs = AttrFlags::query(db, id.into()); let mut flags = StructFlags::empty(); @@ -177,7 +199,7 @@ impl UnionSignature { flags, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } } @@ -196,12 +218,22 @@ bitflags! { pub struct EnumSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub flags: EnumFlags, } +#[salsa::tracked] impl EnumSignature { - pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: EnumId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: EnumId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let attrs = AttrFlags::query(db, id.into()); let mut flags = EnumFlags::empty(); @@ -229,10 +261,12 @@ impl EnumSignature { flags, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } +} +impl EnumSignature { pub fn variant_body_type(db: &dyn DefDatabase, id: EnumId) -> IntegerType { match AttrFlags::repr(db, id.into()) { Some(ReprOptions { int: Some(builtin), .. }) => builtin, @@ -257,13 +291,23 @@ bitflags::bitflags! { pub struct ConstSignature { pub name: Option<Name>, // generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub type_ref: TypeRefId, pub flags: ConstFlags, } +#[salsa::tracked] impl ConstSignature { - pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: ConstId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: ConstId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -282,15 +326,17 @@ impl ConstSignature { ( Arc::new(ConstSignature { - store: Arc::new(store), + store, type_ref, flags, name: source.value.name().map(|it| it.as_name()), }), - Arc::new(source_map), + source_map, ) } +} +impl ConstSignature { pub fn has_body(&self) -> bool { self.flags.contains(ConstFlags::HAS_BODY) } @@ -313,12 +359,23 @@ pub struct StaticSignature { pub name: Name, // generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub type_ref: TypeRefId, pub flags: StaticFlags, } + +#[salsa::tracked] impl StaticSignature { - pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: StaticId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: StaticId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -351,12 +408,12 @@ impl StaticSignature { ( Arc::new(StaticSignature { - store: Arc::new(store), + store, type_ref, flags, name: as_name_opt(source.value.name()), }), - Arc::new(source_map), + source_map, ) } } @@ -373,14 +430,24 @@ bitflags::bitflags! { #[derive(Debug, PartialEq, Eq)] pub struct ImplSignature { pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub self_ty: TypeRefId, pub target_trait: Option<TraitRef>, pub flags: ImplFlags, } +#[salsa::tracked] impl ImplSignature { - pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: ImplId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: ImplId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = ImplFlags::empty(); @@ -399,17 +466,13 @@ impl ImplSignature { crate::expr_store::lower::lower_impl(db, loc.container, src, id); ( - Arc::new(ImplSignature { - store: Arc::new(store), - generic_params, - self_ty, - target_trait, - flags, - }), - Arc::new(source_map), + Arc::new(ImplSignature { store, generic_params, self_ty, target_trait, flags }), + source_map, ) } +} +impl ImplSignature { #[inline] pub fn is_negative(&self) -> bool { self.flags.contains(ImplFlags::NEGATIVE) @@ -440,12 +503,22 @@ bitflags::bitflags! { pub struct TraitSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub flags: TraitFlags, } +#[salsa::tracked] impl TraitSignature { - pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: TraitId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: TraitId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = TraitFlags::empty(); @@ -483,10 +556,7 @@ impl TraitSignature { let name = as_name_opt(source.value.name()); let (store, source_map, generic_params) = lower_trait(db, loc.container, source, id); - ( - Arc::new(TraitSignature { store: Arc::new(store), generic_params, flags, name }), - Arc::new(source_map), - ) + (Arc::new(TraitSignature { store, generic_params, flags, name }), source_map) } } @@ -517,18 +587,25 @@ bitflags! { pub struct FunctionSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub params: Box<[TypeRefId]>, pub ret_type: Option<TypeRefId>, pub abi: Option<Symbol>, pub flags: FnFlags, } +#[salsa::tracked] impl FunctionSignature { - pub fn query( + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: FunctionId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( db: &dyn DefDatabase, id: FunctionId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -589,17 +666,19 @@ impl FunctionSignature { ( Arc::new(FunctionSignature { generic_params, - store: Arc::new(store), + store, params, ret_type, abi, flags, name, }), - Arc::new(source_map), + source_map, ) } +} +impl FunctionSignature { pub fn has_body(&self) -> bool { self.flags.contains(FnFlags::HAS_BODY) } @@ -656,7 +735,7 @@ impl FunctionSignature { } pub fn is_intrinsic(db: &dyn DefDatabase, id: FunctionId) -> bool { - let data = db.function_signature(id); + let data = FunctionSignature::of(db, id); data.flags.contains(FnFlags::RUSTC_INTRINSIC) // Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used || match &data.abi { @@ -684,17 +763,24 @@ bitflags! { pub struct TypeAliasSignature { pub name: Name, pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub bounds: Box<[TypeBound]>, pub ty: Option<TypeRefId>, pub flags: TypeAliasFlags, } +#[salsa::tracked] impl TypeAliasSignature { - pub fn query( + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: TypeAliasId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( db: &dyn DefDatabase, id: TypeAliasId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = TypeAliasFlags::empty(); @@ -714,28 +800,21 @@ impl TypeAliasSignature { lower_type_alias(db, loc.container.module(db), source, id); ( - Arc::new(TypeAliasSignature { - store: Arc::new(store), - generic_params, - flags, - bounds, - name, - ty, - }), - Arc::new(source_map), + Arc::new(TypeAliasSignature { store, generic_params, flags, bounds, name, ty }), + source_map, ) } } #[derive(Debug, PartialEq, Eq)] pub struct FunctionBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub parameters: Box<[PatId]>, } #[derive(Debug, PartialEq, Eq)] pub struct SimpleBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, } pub type StaticBody = SimpleBody; pub type ConstBody = SimpleBody; @@ -743,7 +822,7 @@ pub type EnumVariantBody = SimpleBody; #[derive(Debug, PartialEq, Eq)] pub struct VariantFieldsBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub fields: Box<[Option<ExprId>]>, } @@ -762,17 +841,17 @@ pub type LocalFieldId = Idx<FieldData>; #[derive(Debug, Clone, PartialEq, Eq)] pub struct VariantFields { fields: Arena<FieldData>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub shape: FieldsShape, } #[salsa::tracked] impl VariantFields { - #[salsa::tracked(returns(clone))] - pub(crate) fn query( + #[salsa::tracked(returns(ref))] + pub(crate) fn with_source_map( db: &dyn DefDatabase, id: VariantId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let (shape, result) = match id { VariantId::EnumVariantId(id) => { let loc = id.lookup(db); @@ -809,20 +888,26 @@ impl VariantFields { } }; match result { - Some((fields, store, source_map)) => ( - Arc::new(VariantFields { fields, store: Arc::new(store), shape }), - Arc::new(source_map), - ), + Some((fields, store, source_map)) => { + (Arc::new(VariantFields { fields, store, shape }), source_map) + } None => { - let (store, source_map) = ExpressionStore::empty_singleton(); - (Arc::new(VariantFields { fields: Arena::default(), store, shape }), source_map) + let source_map = ExpressionStoreSourceMap::default(); + ( + Arc::new(VariantFields { + fields: Arena::default(), + store: ExpressionStoreBuilder::default().finish().0, + shape, + }), + source_map, + ) } } } #[salsa::tracked(returns(deref))] pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> { - Self::query(db, id).0 + Self::with_source_map(db, id).0.clone() } } @@ -1014,7 +1099,7 @@ impl EnumVariants { } // The outer if condition is whether this variant has const ctor or not if !matches!(variant.shape, FieldsShape::Unit) { - let body = db.body(v.into()); + let body = Body::of(db, v.into()); // A variant with explicit discriminant if !matches!(body[body.body_expr], crate::hir::Expr::Missing) { return false; diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index d2921db6f4..0d260279f9 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -15,6 +15,7 @@ use triomphe::Arc; use crate::{ Lookup, ModuleDefId, ModuleId, db::DefDatabase, + expr_store::{Body, scope::ExprScopes}, nameres::{DefMap, ModuleSource, block_def_map, crate_def_map}, src::HasSource, }; @@ -284,8 +285,8 @@ impl TestDB { // Find the innermost block expression that has a `DefMap`. let (def_with_body, file_id) = fn_def?; let def_with_body = def_with_body.into(); - let source_map = self.body_with_source_map(def_with_body).1; - let scopes = self.expr_scopes(def_with_body.into()); + let source_map = &Body::with_source_map(self, def_with_body).1; + let scopes = ExprScopes::body_expr_scopes(self, def_with_body); let root_syntax_node = self.parse(file_id).syntax_node(); let scope_iter = diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index c294238030..673d00d956 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -5,10 +5,11 @@ mod tests; use base_db::Crate; use hir_def::{ - ConstId, EnumVariantId, GeneralConstId, HasModule, StaticId, + ConstId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericDefId, HasModule, + StaticId, attrs::AttrFlags, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, - expr_store::ExpressionStore, + expr_store::{Body, ExpressionStore}, hir::{Expr, ExprId, Literal}, }; use hir_expand::Lookup; @@ -273,7 +274,7 @@ pub(crate) fn const_eval_discriminant_variant( ) -> Result<i128, ConstEvalError> { let interner = DbInterner::new_no_crate(db); let def = variant_id.into(); - let body = db.body(def); + let body = Body::of(db, def); let loc = variant_id.lookup(db); if matches!(body[body.body_expr], Expr::Missing) { let prev_idx = loc.index.checked_sub(1); @@ -294,7 +295,7 @@ pub(crate) fn const_eval_discriminant_variant( let mir_body = db.monomorphized_mir_body( def, GenericArgs::empty(interner).store(), - ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) } .store(), )?; let c = interpret_mir(db, mir_body, false, None)?.0?; @@ -337,7 +338,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd } if let Some(body_owner) = ctx.owner.as_def_with_body() && let Ok(mir_body) = - lower_body_to_mir(ctx.db, body_owner, &ctx.db.body(body_owner), &infer, expr) + lower_body_to_mir(ctx.db, body_owner, Body::of(ctx.db, body_owner), &infer, expr) && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None) { return result; @@ -374,8 +375,12 @@ pub(crate) fn const_eval<'db>( let body = db.monomorphized_mir_body( def.into(), subst, - ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) } - .store(), + ParamEnvAndCrate { + param_env: db + .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))), + krate: def.krate(db), + } + .store(), )?; let c = interpret_mir(db, body, false, trait_env.as_ref().map(|env| env.as_ref()))?.0?; Ok(c.store()) @@ -411,7 +416,8 @@ pub(crate) fn const_eval_static<'db>( def.into(), GenericArgs::empty(interner).store(), ParamEnvAndCrate { - param_env: db.trait_environment_for_body(def.into()), + param_env: db + .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))), krate: def.krate(db), } .store(), diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 5f6bcb4a60..31cf86476f 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -1,5 +1,5 @@ use base_db::RootQueryDb; -use hir_def::db::DefDatabase; +use hir_def::signatures::ConstSignature; use hir_expand::EditionedFileId; use rustc_apfloat::{ Float, @@ -131,7 +131,11 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEv .declarations() .find_map(|x| match x { hir_def::ModuleDefId::ConstId(x) => { - if db.const_signature(x).name.as_ref()?.display(db, file_id.edition(db)).to_string() + if ConstSignature::of(db, x) + .name + .as_ref()? + .display(db, file_id.edition(db)) + .to_string() == "GOAL" { Some(x) diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index ca5b1b7716..a0fb75397a 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -5,7 +5,7 @@ use base_db::{Crate, target::TargetLoadError}; use either::Either; use hir_def::{ AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, - ExpressionStoreOwner, FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, + ExpressionStoreOwnerId, FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod, db::DefDatabase, hir::ExprId, layout::TargetDataLayout, }; @@ -178,13 +178,9 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { def: CallableDefId, ) -> EarlyBinder<'db, PolyFnSig<'db>>; - #[salsa::invoke(crate::lower::trait_environment_for_body_query)] - #[salsa::transparent] - fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>; - #[salsa::invoke(crate::lower::trait_environment)] #[salsa::transparent] - fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>; + fn trait_environment<'db>(&'db self, def: ExpressionStoreOwnerId) -> ParamEnv<'db>; #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)] #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)] @@ -240,7 +236,7 @@ pub struct InternedOpaqueTyId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct InternedClosure(pub ExpressionStoreOwner, pub ExprId); +pub struct InternedClosure(pub ExpressionStoreOwnerId, pub ExprId); #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] #[derive(PartialOrd, Ord)] @@ -249,7 +245,7 @@ pub struct InternedClosureId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct InternedCoroutine(pub ExpressionStoreOwner, pub ExprId); +pub struct InternedCoroutine(pub ExpressionStoreOwnerId, pub ExprId); #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] #[derive(PartialOrd, Ord)] diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs index 0931b85965..89d8c0e91d 100644 --- a/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/crates/hir-ty/src/diagnostics/decl_check.rs @@ -17,8 +17,17 @@ use std::fmt; use hir_def::{ AdtId, ConstId, EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, - ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags, - db::DefDatabase, hir::Pat, item_tree::FieldsShape, signatures::StaticFlags, src::HasSource, + ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + attrs::AttrFlags, + db::DefDatabase, + expr_store::Body, + hir::Pat, + item_tree::FieldsShape, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, StaticFlags, StaticSignature, + StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, + }, + src::HasSource, }; use hir_expand::{ HirFileId, @@ -178,7 +187,7 @@ impl<'a> DeclValidator<'a> { fn validate_trait(&mut self, trait_id: TraitId) { // Check the trait name. - let data = self.db.trait_signature(trait_id); + let data = TraitSignature::of(self.db, trait_id); self.create_incorrect_case_diagnostic_for_item_name( trait_id, &data.name, @@ -197,7 +206,7 @@ impl<'a> DeclValidator<'a> { // Check the function name. // Skipped if function is an associated item of a trait implementation. if !self.is_trait_impl_container(container) { - let data = self.db.function_signature(func); + let data = FunctionSignature::of(self.db, func); // Don't run the lint on extern "[not Rust]" fn items with the // #[no_mangle] attribute. @@ -223,7 +232,7 @@ impl<'a> DeclValidator<'a> { /// Check incorrect names for patterns inside the function body. /// This includes function parameters except for trait implementation associated functions. fn validate_func_body(&mut self, func: FunctionId) { - let body = self.db.body(func.into()); + let body = Body::of(self.db, func.into()); let edition = self.edition(func); let mut pats_replacements = body .pats() @@ -250,7 +259,7 @@ impl<'a> DeclValidator<'a> { return; } - let source_map = self.db.body_with_source_map(func.into()).1; + let source_map = &Body::with_source_map(self.db, func.into()).1; for (id, replacement) in pats_replacements { let Ok(source_ptr) = source_map.pat_syntax(id) else { continue; @@ -292,7 +301,7 @@ impl<'a> DeclValidator<'a> { fn validate_struct(&mut self, struct_id: StructId) { // Check the structure name. - let data = self.db.struct_signature(struct_id); + let data = StructSignature::of(self.db, struct_id); // rustc implementation excuses repr(C) since C structs predominantly don't // use camel case. @@ -385,7 +394,7 @@ impl<'a> DeclValidator<'a> { fn validate_union(&mut self, union_id: UnionId) { // Check the union name. - let data = self.db.union_signature(union_id); + let data = UnionSignature::of(self.db, union_id); // rustc implementation excuses repr(C) since C unions predominantly don't // use camel case. @@ -473,7 +482,7 @@ impl<'a> DeclValidator<'a> { fn validate_enum(&mut self, enum_id: EnumId) { // Check the enum name. - let data = self.db.enum_signature(enum_id); + let data = EnumSignature::of(self.db, enum_id); // rustc implementation excuses repr(C) since C structs predominantly don't // use camel case. @@ -644,7 +653,7 @@ impl<'a> DeclValidator<'a> { return; } - let data = self.db.const_signature(const_id); + let data = ConstSignature::of(self.db, const_id); let Some(name) = &data.name else { return; }; @@ -657,7 +666,7 @@ impl<'a> DeclValidator<'a> { } fn validate_static(&mut self, static_id: StaticId) { - let data = self.db.static_signature(static_id); + let data = StaticSignature::of(self.db, static_id); if data.flags.contains(StaticFlags::EXTERN) { cov_mark::hit!(extern_static_incorrect_case_ignored); return; @@ -683,7 +692,7 @@ impl<'a> DeclValidator<'a> { } // Check the type alias name. - let data = self.db.type_alias_signature(type_alias_id); + let data = TypeAliasSignature::of(self.db, type_alias_id); self.create_incorrect_case_diagnostic_for_item_name( type_alias_id, &data.name, diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index 4e1bb6f4c5..e227be6995 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -21,7 +21,7 @@ use syntax::{ ast::{self, UnaryOp}, }; use tracing::debug; -use triomphe::Arc; + use typed_arena::Arena; use crate::{ @@ -76,9 +76,9 @@ impl BodyValidationDiagnostic { validate_lints: bool, ) -> Vec<BodyValidationDiagnostic> { let _p = tracing::info_span!("BodyValidationDiagnostic::collect").entered(); - let infer = InferenceResult::for_body(db, owner); - let body = db.body(owner); - let env = db.trait_environment_for_body(owner); + let infer = InferenceResult::of(db, owner); + let body = Body::of(db, owner); + let env = db.trait_environment(owner.into()); let interner = DbInterner::new_with(db, owner.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::typeck_for_body(interner, owner.into())); @@ -98,7 +98,7 @@ impl BodyValidationDiagnostic { struct ExprValidator<'db> { owner: DefWithBodyId, - body: Arc<Body>, + body: &'db Body, infer: &'db InferenceResult, env: ParamEnv<'db>, diagnostics: Vec<BodyValidationDiagnostic>, @@ -116,10 +116,10 @@ impl<'db> ExprValidator<'db> { let db = self.db(); let mut filter_map_next_checker = None; // we'll pass &mut self while iterating over body.exprs, so they need to be disjoint - let body = Arc::clone(&self.body); + let body = self.body; if matches!(self.owner, DefWithBodyId::FunctionId(_)) { - self.check_for_trailing_return(body.body_expr, &body); + self.check_for_trailing_return(body.body_expr, body); } for (id, expr) in body.exprs() { @@ -141,7 +141,7 @@ impl<'db> ExprValidator<'db> { self.validate_call(id, expr, &mut filter_map_next_checker); } Expr::Closure { body: body_expr, .. } => { - self.check_for_trailing_return(*body_expr, &body); + self.check_for_trailing_return(*body_expr, body); } Expr::If { .. } => { self.check_for_unnecessary_else(id, expr); @@ -240,7 +240,7 @@ impl<'db> ExprValidator<'db> { .as_reference() .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty) .unwrap_or(false)) - && types_of_subpatterns_do_match(arm.pat, &self.body, self.infer) + && types_of_subpatterns_do_match(arm.pat, self.body, self.infer) { // If we had a NotUsefulMatchArm diagnostic, we could // check the usefulness of each pattern as we added it @@ -388,7 +388,7 @@ impl<'db> ExprValidator<'db> { pat: PatId, have_errors: &mut bool, ) -> DeconstructedPat<'a, 'db> { - let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, &self.body); + let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, self.body); let pattern = patcx.lower_pattern(pat); let pattern = cx.lower_pat(&pattern); if !patcx.errors.is_empty() { @@ -451,7 +451,7 @@ impl<'db> ExprValidator<'db> { && last_then_expr_ty.is_never() { // Only look at sources if the then branch diverges and we have an else branch. - let source_map = self.db().body_with_source_map(self.owner).1; + let source_map = &Body::with_source_map(self.db(), self.owner).1; let Ok(source_ptr) = source_map.expr_syntax(id) else { return; }; diff --git a/crates/hir-ty/src/diagnostics/match_check.rs b/crates/hir-ty/src/diagnostics/match_check.rs index 8e6101e6a0..f559c26bf5 100644 --- a/crates/hir-ty/src/diagnostics/match_check.rs +++ b/crates/hir-ty/src/diagnostics/match_check.rs @@ -14,6 +14,7 @@ use hir_def::{ expr_store::{Body, path::Path}, hir::PatId, item_tree::FieldsShape, + signatures::{StructSignature, UnionSignature}, }; use hir_expand::name::Name; use rustc_type_ir::inherent::IntoKind; @@ -340,12 +341,12 @@ impl<'db> HirDisplay<'db> for Pat<'db> { VariantId::StructId(s) => write!( f, "{}", - f.db.struct_signature(s).name.display(f.db, f.edition()) + StructSignature::of(f.db, s).name.display(f.db, f.edition()) )?, VariantId::UnionId(u) => write!( f, "{}", - f.db.union_signature(u).name.display(f.db, f.edition()) + UnionSignature::of(f.db, u).name.display(f.db, f.edition()) )?, }; diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs index 21f263723b..ba9b7416b7 100644 --- a/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -9,7 +9,7 @@ use hir_def::{ expr_store::{Body, path::Path}, hir::{AsmOperand, Expr, ExprId, ExprOrPatId, InlineAsmKind, Pat, PatId, Statement, UnaryOp}, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, - signatures::StaticFlags, + signatures::{FunctionSignature, StaticFlags, StaticSignature}, type_ref::Rawness, }; use rustc_type_ir::inherent::IntoKind; @@ -34,15 +34,15 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe let _p = tracing::info_span!("missing_unsafe").entered(); let is_unsafe = match def { - DefWithBodyId::FunctionId(it) => db.function_signature(it).is_unsafe(), + DefWithBodyId::FunctionId(it) => FunctionSignature::of(db, it).is_unsafe(), DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => { false } }; let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() }; - let body = db.body(def); - let infer = InferenceResult::for_body(db, def); + let body = Body::of(db, def); + let infer = InferenceResult::of(db, def); let mut callback = |diag| match diag { UnsafeDiagnostic::UnsafeOperation { node, inside_unsafe_block, reason } => { if inside_unsafe_block == InsideUnsafeBlock::No { @@ -55,7 +55,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe } } }; - let mut visitor = UnsafeVisitor::new(db, infer, &body, def, &mut callback); + let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut callback); visitor.walk_expr(body.body_expr); if !is_unsafe { @@ -431,7 +431,7 @@ impl<'db> UnsafeVisitor<'db> { let hygiene = self.body.expr_or_pat_path_hygiene(node); let value_or_partial = self.resolver.resolve_path_in_value_ns(self.db, path, hygiene); if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial { - let static_data = self.db.static_signature(id); + let static_data = StaticSignature::of(self.db, id); if static_data.flags.contains(StaticFlags::MUTABLE) { self.on_unsafe_op(node, UnsafetyReason::MutableStatic); } else if static_data.flags.contains(StaticFlags::EXTERN) diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index f4d0ed1484..54cd750de6 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -10,15 +10,18 @@ use std::{ use base_db::{Crate, FxIndexMap}; use either::Either; use hir_def::{ - FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, ModuleDefId, - ModuleId, TraitId, + ExpressionStoreOwnerId, FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, + Lookup, ModuleDefId, ModuleId, TraitId, expr_store::{ExpressionStore, path::Path}, find_path::{self, PrefixKind}, hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_scope::ItemInNs, item_tree::FieldsShape, lang_item::LangItems, - signatures::VariantFields, + signatures::{ + EnumSignature, FunctionSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, VariantFields, + }, type_ref::{ ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef, @@ -671,7 +674,9 @@ fn write_projection<'db>( write!( f, ">::{}", - f.db.type_alias_signature(alias.def_id.expect_type_alias()).name.display(f.db, f.edition()) + TypeAliasSignature::of(f.db, alias.def_id.expect_type_alias()) + .name + .display(f.db, f.edition()) )?; let proj_params = &alias.args.as_slice()[trait_ref.args.len()..]; hir_fmt_generics(f, proj_params, None, None) @@ -853,7 +858,7 @@ fn render_const_scalar_inner<'db>( } TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id().0 { hir_def::AdtId::StructId(s) => { - let data = f.db.struct_signature(s); + let data = StructSignature::of(f.db, s); write!(f, "&{}", data.name.display(f.db, f.edition()))?; Ok(()) } @@ -911,14 +916,16 @@ fn render_const_scalar_inner<'db>( }; match def { hir_def::AdtId::StructId(s) => { - let data = f.db.struct_signature(s); + let data = StructSignature::of(f.db, s); write!(f, "{}", data.name.display(f.db, f.edition()))?; let field_types = f.db.field_types(s.into()); render_variant_after_name( s.fields(f.db), f, field_types, - f.db.trait_environment(def.into()), + f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + def, + ))), &layout, args, b, @@ -926,7 +933,7 @@ fn render_const_scalar_inner<'db>( ) } hir_def::AdtId::UnionId(u) => { - write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition())) + write!(f, "{}", UnionSignature::of(f.db, u).name.display(f.db, f.edition())) } hir_def::AdtId::EnumId(e) => { let Ok(target_data_layout) = f.db.target_data_layout(f.krate()) else { @@ -950,7 +957,9 @@ fn render_const_scalar_inner<'db>( var_id.fields(f.db), f, field_types, - f.db.trait_environment(def.into()), + f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + def, + ))), var_layout, args, b, @@ -1152,11 +1161,13 @@ impl<'db> HirDisplay<'db> for Ty<'db> { write!(f, "fn ")?; f.start_location_link(def.into()); match def { - CallableDefId::FunctionId(ff) => { - write!(f, "{}", db.function_signature(ff).name.display(f.db, f.edition()))? - } + CallableDefId::FunctionId(ff) => write!( + f, + "{}", + FunctionSignature::of(db, ff).name.display(f.db, f.edition()) + )?, CallableDefId::StructId(s) => { - write!(f, "{}", db.struct_signature(s).name.display(f.db, f.edition()))? + write!(f, "{}", StructSignature::of(db, s).name.display(f.db, f.edition()))? } CallableDefId::EnumVariantId(e) => { let loc = e.lookup(db); @@ -1235,9 +1246,11 @@ impl<'db> HirDisplay<'db> for Ty<'db> { match f.display_kind { DisplayKind::Diagnostics | DisplayKind::Test => { let name = match def_id { - hir_def::AdtId::StructId(it) => db.struct_signature(it).name.clone(), - hir_def::AdtId::UnionId(it) => db.union_signature(it).name.clone(), - hir_def::AdtId::EnumId(it) => db.enum_signature(it).name.clone(), + hir_def::AdtId::StructId(it) => { + StructSignature::of(db, it).name.clone() + } + hir_def::AdtId::UnionId(it) => UnionSignature::of(db, it).name.clone(), + hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it).name.clone(), }; write!(f, "{}", name.display(f.db, f.edition()))?; } @@ -1272,7 +1285,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { write_projection(f, &alias_ty, trait_bounds_need_parens)? } TyKind::Foreign(alias) => { - let type_alias = db.type_alias_signature(alias.0); + let type_alias = TypeAliasSignature::of(db, alias.0); f.start_location_link(alias.0.into()); write!(f, "{}", type_alias.name.display(f.db, f.edition()))?; f.end_location_link(); @@ -1337,11 +1350,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe); let sig = sig.skip_binder(); let InternedClosure(owner, _) = db.lookup_intern_closure(id); - let Some(def) = owner.as_def_with_body() else { - write!(f, "{{closure}}")?; - return Ok(()); - }; - let infer = InferenceResult::for_body(db, def); + let infer = InferenceResult::of(db, owner); let (_, kind) = infer.closure_info(id); match f.closure_style { ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?, @@ -1530,13 +1539,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { let InternedCoroutine(owner, expr_id) = coroutine_id.0.loc(db); let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } = subst.split_coroutine_args(); - let Some(body_owner) = owner.as_def_with_body() else { - write!(f, "impl Future<Output = ")?; - return_ty.hir_fmt(f)?; - write!(f, ">")?; - return Ok(()); - }; - let body = db.body(body_owner); + let body = ExpressionStore::of(db, owner); let expr = &body[expr_id]; match expr { hir_def::hir::Expr::Closure { @@ -1877,7 +1880,7 @@ fn write_bounds_like_dyn_trait<'db>( // existential) here, which is the only thing that's // possible in actual Rust, and hence don't print it f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?; + write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?; f.end_location_link(); if is_fn_trait { if let [_self, params @ ..] = trait_ref.trait_ref.args.as_slice() @@ -1940,7 +1943,7 @@ fn write_bounds_like_dyn_trait<'db>( angle_open = true; } let assoc_ty_id = projection.def_id().expect_type_alias(); - let type_alias = f.db.type_alias_signature(assoc_ty_id); + let type_alias = TypeAliasSignature::of(f.db, assoc_ty_id); f.start_location_link(assoc_ty_id.into()); write!(f, "{}", type_alias.name.display(f.db, f.edition()))?; f.end_location_link(); @@ -2031,7 +2034,7 @@ impl<'db> HirDisplay<'db> for TraitRef<'db> { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { let trait_ = self.def_id.0; f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?; + write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?; f.end_location_link(); let substs = self.args.as_slice(); hir_fmt_generic_args(f, &substs[1..], None, Some(self.self_ty())) diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs index 1303e08801..ddc4e4ce85 100644 --- a/crates/hir-ty/src/drop.rs +++ b/crates/hir-ty/src/drop.rs @@ -1,6 +1,9 @@ //! Utilities for computing drop info about types. -use hir_def::{AdtId, signatures::StructFlags}; +use hir_def::{ + AdtId, + signatures::{StructFlags, StructSignature}, +}; use rustc_hash::FxHashSet; use rustc_type_ir::inherent::{AdtDef, IntoKind}; use stdx::never; @@ -73,8 +76,7 @@ fn has_drop_glue_impl<'db>( } match adt_id { AdtId::StructId(id) => { - if db - .struct_signature(id) + if StructSignature::of(db, id) .flags .intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA) { @@ -132,12 +134,9 @@ fn has_drop_glue_impl<'db>( TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited), TyKind::Closure(closure_id, subst) => { let owner = db.lookup_intern_closure(closure_id.0).0; - let Some(body_owner) = owner.as_def_with_body() else { - return DropGlue::None; - }; - let infer = InferenceResult::for_body(db, body_owner); + let infer = InferenceResult::of(db, owner); let (captures, _) = infer.closure_info(closure_id.0); - let env = db.trait_environment_for_body(body_owner); + let env = db.trait_environment(owner); captures .iter() .map(|capture| has_drop_glue_impl(infcx, capture.ty(db, subst), env, visited)) diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 59cfd3fdc9..d8093b3eb1 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -4,8 +4,10 @@ use std::ops::ControlFlow; use hir_def::{ AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId, - nameres::crate_def_map, signatures::TraitFlags, + TypeOrConstParamId, TypeParamId, + hir::generics::LocalTypeOrConstParamId, + nameres::crate_def_map, + signatures::{FunctionSignature, TraitFlags, TraitSignature}, }; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -318,7 +320,7 @@ fn virtual_call_violations_for_method<F>( where F: FnMut(MethodViolationCode) -> ControlFlow<()>, { - let func_data = db.function_signature(func); + let func_data = FunctionSignature::of(db, func); if !func_data.has_self_param() { cb(MethodViolationCode::StaticMethod)?; } @@ -371,7 +373,7 @@ where trait_ref: pred_trait_ref, polarity: PredicatePolarity::Positive, }) = pred - && let trait_data = db.trait_signature(pred_trait_ref.def_id.0) + && let trait_data = TraitSignature::of(db, pred_trait_ref.def_id.0) && trait_data.flags.contains(TraitFlags::AUTO) && let rustc_type_ir::TyKind::Param(ParamTy { index: 0, .. }) = pred_trait_ref.self_ty().kind() diff --git a/crates/hir-ty/src/dyn_compatibility/tests.rs b/crates/hir-ty/src/dyn_compatibility/tests.rs index 5c9b06e39a..a70f98a0fe 100644 --- a/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/crates/hir-ty/src/dyn_compatibility/tests.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use hir_def::db::DefDatabase; +use hir_def::signatures::TraitSignature; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::ToSmolStr; use test_fixture::WithFixture; @@ -40,8 +40,7 @@ fn check_dyn_compatibility<'a>( .declarations() .filter_map(|def| { if let hir_def::ModuleDefId::TraitId(trait_id) = def { - let name = db - .trait_signature(trait_id) + let name = TraitSignature::of(&db, trait_id) .name .display_no_db(file_id.edition(&db)) .to_smolstr(); diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs index b3c888da8e..57fe4d749b 100644 --- a/crates/hir-ty/src/generics.rs +++ b/crates/hir-ty/src/generics.rs @@ -22,22 +22,22 @@ use hir_def::{ use itertools::chain; use triomphe::Arc; -pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics { +pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics<'_> { let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def))); - let (params, store) = db.generic_params_and_store(def); + let (params, store) = GenericParams::of(db, def); let has_trait_self_param = params.trait_self_param().is_some(); Generics { def, params, parent_generics, has_trait_self_param, store } } #[derive(Clone, Debug)] -pub struct Generics { +pub struct Generics<'db> { def: GenericDefId, params: Arc<GenericParams>, - store: Arc<ExpressionStore>, - parent_generics: Option<Box<Generics>>, + store: &'db ExpressionStore, + parent_generics: Option<Box<Generics<'db>>>, has_trait_self_param: bool, } -impl<T> ops::Index<T> for Generics +impl<T> ops::Index<T> for Generics<'_> where GenericParams: ops::Index<T>, { @@ -47,13 +47,13 @@ where } } -impl Generics { +impl<'db> Generics<'db> { pub(crate) fn def(&self) -> GenericDefId { self.def } pub(crate) fn store(&self) -> &ExpressionStore { - &self.store + self.store } pub(crate) fn where_predicates(&self) -> impl Iterator<Item = &WherePredicate> { @@ -97,7 +97,7 @@ impl Generics { ) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &ExpressionStore)> + '_ { self.iter_parent() - .zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(&*it.store))) + .zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(it.store))) } /// Iterate over the params without parent params. @@ -219,7 +219,7 @@ impl Generics { } } - pub(crate) fn parent_generics(&self) -> Option<&Generics> { + pub(crate) fn parent_generics(&self) -> Option<&Generics<'db>> { self.parent_generics.as_deref() } } @@ -243,7 +243,7 @@ pub(crate) fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Opt } fn from_toc_id<'a>( - it: &'a Generics, + it: &'a Generics<'a>, ) -> impl Fn( (LocalTypeOrConstParamId, &'a TypeOrConstParamData), ) -> (GenericParamId, GenericParamDataRef<'a>) { @@ -263,7 +263,7 @@ fn from_toc_id<'a>( } fn from_lt_id<'a>( - it: &'a Generics, + it: &'a Generics<'a>, ) -> impl Fn((LocalLifetimeParamId, &'a LifetimeParamData)) -> (GenericParamId, GenericParamDataRef<'a>) { move |(local_id, p): (_, _)| { diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 9d78f5de9e..52edbc899f 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -33,15 +33,15 @@ use std::{cell::OnceCell, convert::identity, iter}; use base_db::Crate; use either::Either; use hir_def::{ - AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, ExpressionStoreOwner, FieldId, + AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId, GenericParamId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, TypeOrConstParamId, VariantId, - expr_store::{ConstExprOrigin, ExpressionStore, HygieneId, path::Path}, + expr_store::{Body, ConstExprOrigin, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::LangItems, layout::Integer, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, - signatures::{ConstSignature, EnumSignature, StaticSignature}, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, type_ref::{ConstRef, LifetimeRefId, TypeRef, TypeRefId}, }; use hir_expand::{mod_path::ModPath, name::Name}; @@ -105,8 +105,9 @@ pub fn infer_query_with_inspect<'db>( ) -> InferenceResult { let _p = tracing::info_span!("infer_query").entered(); let resolver = def.resolver(db); - let body = db.body(def); - let mut ctx = InferenceContext::new(db, ExpressionStoreOwner::Body(def), &body.store, resolver); + let body = Body::of(db, def); + let mut ctx = + InferenceContext::new(db, ExpressionStoreOwnerId::Body(def), &body.store, resolver); if let Some(inspect) = inspect { ctx.table.infer_ctxt.attach_obligation_inspector(inspect); @@ -114,8 +115,8 @@ pub fn infer_query_with_inspect<'db>( match def { DefWithBodyId::FunctionId(f) => ctx.collect_fn(f, body.self_param, &body.params), - DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)), - DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)), + DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)), + DefWithBodyId::StaticId(s) => ctx.collect_static(StaticSignature::of(db, s)), DefWithBodyId::VariantId(v) => { ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) { hir_def::layout::IntegerType::Pointer(signed) => match signed { @@ -146,33 +147,7 @@ pub fn infer_query_with_inspect<'db>( ctx.infer_mut_body(body.body_expr); - finalize_infer(ctx) -} - -fn finalize_infer(mut ctx: InferenceContext<'_, '_>) -> InferenceResult { - ctx.handle_opaque_type_uses(); - - ctx.type_inference_fallback(); - - // Comment from rustc: - // Even though coercion casts provide type hints, we check casts after fallback for - // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. - let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks); - for mut cast in cast_checks.into_iter() { - if let Err(diag) = cast.check(&mut ctx) { - ctx.diagnostics.push(diag); - } - } - - ctx.table.select_obligations_where_possible(); - - ctx.infer_closures(); - - ctx.table.select_obligations_where_possible(); - - ctx.handle_opaque_type_uses(); - - ctx.resolve_all() + infer_finalize(ctx) } fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult { @@ -190,16 +165,16 @@ fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> I /// a shared `InferenceContext`, accumulating results into a single `InferenceResult`. fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { let _p = tracing::info_span!("infer_signature_query").entered(); - let (_, store) = db.generic_params_and_store(def); + let store = ExpressionStore::of(db, def.into()); let mut roots = store.signature_const_expr_roots_with_origins().peekable(); let Some(_) = roots.peek() else { return InferenceResult::new(crate::next_solver::default_types(db).types.error); }; let resolver = def.resolver(db); - let owner = ExpressionStoreOwner::Signature(def); + let owner = ExpressionStoreOwnerId::Signature(def); - let mut ctx = InferenceContext::new(db, owner, &store, resolver); + let mut ctx = InferenceContext::new(db, owner, store, resolver); for (root_expr, origin) in roots { let expected = match origin { @@ -217,7 +192,7 @@ fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceRe ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes); } - finalize_infer(ctx) + infer_finalize(ctx) } fn infer_signature_cycle_result( @@ -231,6 +206,31 @@ fn infer_signature_cycle_result( } } +fn infer_finalize(mut ctx: InferenceContext<'_, '_>) -> InferenceResult { + ctx.handle_opaque_type_uses(); + + ctx.type_inference_fallback(); + + // Comment from rustc: + // Even though coercion casts provide type hints, we check casts after fallback for + // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. + let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks); + for mut cast in cast_checks.into_iter() { + if let Err(diag) = cast.check(&mut ctx) { + ctx.diagnostics.push(diag); + } + } + + ctx.table.select_obligations_where_possible(); + + ctx.infer_closures(); + + ctx.table.select_obligations_where_possible(); + + ctx.handle_opaque_type_uses(); + + ctx.resolve_all() +} /// Binding modes inferred for patterns. /// <https://doc.rust-lang.org/reference/patterns.html#binding-modes> #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] @@ -604,7 +604,7 @@ pub struct InferenceResult { #[salsa::tracked] impl InferenceResult { #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)] - pub fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { + fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { infer_query(db, def) } @@ -614,12 +614,21 @@ impl InferenceResult { /// const generic arguments, and other const expressions appearing in type /// positions within the item's signature. #[salsa::tracked(returns(ref), cycle_result = infer_signature_cycle_result)] - pub fn for_signature(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { + fn for_signature(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { infer_signature_query(db, def) } } impl InferenceResult { + pub fn of(db: &dyn HirDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &InferenceResult { + match def.into() { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + Self::for_signature(db, generic_def_id) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Self::for_body(db, def_with_body_id), + } + } + fn new(error_ty: Ty<'_>) -> Self { Self { method_resolutions: Default::default(), @@ -816,7 +825,7 @@ impl InferenceResult { #[derive(Clone, Debug)] pub(crate) struct InferenceContext<'body, 'db> { pub(crate) db: &'db dyn HirDatabase, - pub(crate) owner: ExpressionStoreOwner, + pub(crate) owner: ExpressionStoreOwnerId, pub(crate) store: &'body ExpressionStore, /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext /// and resolve the path via its methods. This will ensure proper error reporting. @@ -917,14 +926,16 @@ fn find_continuable<'a, 'db>( impl<'body, 'db> InferenceContext<'body, 'db> { fn new( db: &'db dyn HirDatabase, - owner: ExpressionStoreOwner, + owner: ExpressionStoreOwnerId, store: &'body ExpressionStore, resolver: Resolver<'db>, ) -> Self { let trait_env = match owner { - ExpressionStoreOwner::Signature(generic_def_id) => db.trait_environment(generic_def_id), - ExpressionStoreOwner::Body(def_with_body_id) => { - db.trait_environment_for_body(def_with_body_id) + ExpressionStoreOwnerId::Signature(generic_def_id) => { + db.trait_environment(ExpressionStoreOwnerId::from(generic_def_id)) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => { + db.trait_environment(ExpressionStoreOwnerId::Body(def_with_body_id)) } }; let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner)); @@ -970,7 +981,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) { let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| { let target_features = match self.owner { - ExpressionStoreOwner::Body(DefWithBodyId::FunctionId(id)) => { + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => { TargetFeatures::from_fn(self.db, id) } _ => TargetFeatures::default(), @@ -1167,11 +1178,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn collect_fn(&mut self, func: FunctionId, self_param: Option<BindingId>, params: &[PatId]) { - let data = self.db.function_signature(func); + let data = FunctionSignature::of(self.db, func); let mut param_tys = self.with_ty_lowering( &data.store, InferenceTyDiagnosticSource::Signature, - LifetimeElisionKind::for_fn_params(&data), + LifetimeElisionKind::for_fn_params(data), |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(), ); diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs index fc38361d7e..e5ee734474 100644 --- a/crates/hir-ty/src/infer/cast.rs +++ b/crates/hir-ty/src/infer/cast.rs @@ -1,6 +1,10 @@ //! Type cast logic. Basically coercion + additional casts. -use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags}; +use hir_def::{ + AdtId, + hir::ExprId, + signatures::{TraitFlags, TraitSignature}, +}; use rustc_ast_ir::Mutability; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -383,8 +387,7 @@ impl<'db> CastCheck<'db> { .chain( elaborate::supertrait_def_ids(ctx.interner(), src_principal) .filter(|trait_| { - ctx.db - .trait_signature(trait_.0) + TraitSignature::of(ctx.db, trait_.0) .flags .contains(TraitFlags::AUTO) }), diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index 2b9d3a7f5d..913d54e969 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -4,8 +4,8 @@ use std::{cmp, mem}; use base_db::Crate; use hir_def::{ - DefWithBodyId, FieldId, HasModule, VariantId, - expr_store::path::Path, + ExpressionStoreOwnerId, FieldId, HasModule, VariantId, + expr_store::{Body, ExpressionStore, path::Path}, hir::{ Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId, RecordSpread, Statement, UnaryOp, @@ -179,9 +179,22 @@ impl CapturedItem { } /// Converts the place to a name that can be inserted into source code. - pub fn place_to_name(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); - let mut result = body[self.place.local].name.as_str().to_owned(); + pub fn place_to_name(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String { + let krate = owner.krate(db); + let edition = krate.data(db).edition; + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + }; for proj in &self.place.projections { match proj { HirPlaceProjection::Deref => {} @@ -213,11 +226,26 @@ impl CapturedItem { result } - pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); + pub fn display_place_source_code( + &self, + owner: ExpressionStoreOwnerId, + db: &dyn HirDatabase, + ) -> String { let krate = owner.krate(db); let edition = krate.data(db).edition; - let mut result = body[self.place.local].name.display(db, edition).to_string(); + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + }; for proj in &self.place.projections { match proj { // In source code autoderef kicks in. @@ -258,11 +286,22 @@ impl CapturedItem { result } - pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); + pub fn display_place(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String { let krate = owner.krate(db); let edition = krate.data(db).edition; - let mut result = body[self.place.local].name.display(db, edition).to_string(); + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + }; let mut field_need_paren = false; for proj in &self.place.projections { match proj { diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 2e80bad614..c4c217b010 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -11,6 +11,7 @@ use hir_def::{ InlineAsmKind, LabelId, Literal, Pat, PatId, RecordSpread, Statement, UnaryOp, }, resolver::ValueNs, + signatures::FunctionSignature, }; use hir_def::{FunctionId, hir::ClosureKind}; use hir_expand::name::Name; @@ -2194,7 +2195,7 @@ impl<'db> InferenceContext<'_, 'db> { _ => return Default::default(), }; - let data = self.db.function_signature(func); + let data = FunctionSignature::of(self.db, func); let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func) else { return Default::default(); diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index 17d4901123..71d68ccd47 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -4,6 +4,7 @@ use hir_def::{ AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, expr_store::path::{Path, PathSegment}, resolver::{ResolveValueResult, TypeNs, ValueNs}, + signatures::{ConstSignature, FunctionSignature}, }; use hir_expand::name::Name; use rustc_type_ir::inherent::{SliceLike, Ty as _}; @@ -263,7 +264,7 @@ impl<'db> InferenceContext<'_, 'db> { trait_.trait_items(self.db).items.iter().map(|(_name, id)| *id).find_map(|item| { match item { AssocItemId::FunctionId(func) => { - if segment.name == &self.db.function_signature(func).name { + if segment.name == &FunctionSignature::of(self.db, func).name { Some(CandidateId::FunctionId(func)) } else { None @@ -271,7 +272,7 @@ impl<'db> InferenceContext<'_, 'db> { } AssocItemId::ConstId(konst) => { - if self.db.const_signature(konst).name.as_ref() == Some(segment.name) { + if ConstSignature::of(self.db, konst).name.as_ref() == Some(segment.name) { Some(CandidateId::ConstId(konst)) } else { None diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index 77f76c97b8..d093412b42 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -3,7 +3,7 @@ use std::fmt; use base_db::Crate; -use hir_def::{AdtId, ExpressionStoreOwner, GenericParamId}; +use hir_def::{AdtId, ExpressionStoreOwnerId, GenericParamId}; use hir_expand::name::Name; use intern::sym; use rustc_hash::FxHashSet; @@ -147,7 +147,7 @@ impl<'db> InferenceTable<'db> { db: &'db dyn HirDatabase, trait_env: ParamEnv<'db>, krate: Crate, - owner: Option<ExpressionStoreOwner>, + owner: Option<ExpressionStoreOwnerId>, ) -> Self { let interner = DbInterner::new_with(db, krate); let typing_mode = match owner { diff --git a/crates/hir-ty/src/lang_items.rs b/crates/hir-ty/src/lang_items.rs index 18feb0f46a..ae53276f56 100644 --- a/crates/hir-ty/src/lang_items.rs +++ b/crates/hir-ty/src/lang_items.rs @@ -1,13 +1,17 @@ //! Functions to detect special lang items -use hir_def::{AdtId, TraitId, lang_item::LangItems, signatures::StructFlags}; +use hir_def::{ + AdtId, TraitId, + lang_item::LangItems, + signatures::{StructFlags, StructSignature}, +}; use intern::{Symbol, sym}; use crate::db::HirDatabase; pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool { let AdtId::StructId(id) = adt else { return false }; - db.struct_signature(id).flags.contains(StructFlags::IS_BOX) + StructSignature::of(db, id).flags.contains(StructFlags::IS_BOX) } pub fn lang_items_for_bin_op( diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index a325b2e174..54332122d0 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -333,10 +333,7 @@ pub fn layout_of_ty_query( } TyKind::Closure(id, args) => { let def = db.lookup_intern_closure(id.0); - let Some(body_owner) = def.0.as_def_with_body() else { - return Err(LayoutError::HasErrorType); - }; - let infer = InferenceResult::for_body(db, body_owner); + let infer = InferenceResult::of(db, def.0); let (captures, _) = infer.closure_info(id.0); let fields = captures .iter() diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs index d249591718..6090ddfd45 100644 --- a/crates/hir-ty/src/layout/adt.rs +++ b/crates/hir-ty/src/layout/adt.rs @@ -5,7 +5,7 @@ use std::{cmp, ops::Bound}; use hir_def::{ AdtId, VariantId, attrs::AttrFlags, - signatures::{StructFlags, VariantFields}, + signatures::{StructFlags, StructSignature, VariantFields}, }; use rustc_abi::{Integer, ReprOptions, TargetDataLayout}; use rustc_index::IndexVec; @@ -41,7 +41,7 @@ pub fn layout_of_adt_query( }; let (variants, repr, is_special_no_niche) = match def { AdtId::StructId(s) => { - let sig = db.struct_signature(s); + let sig = StructSignature::of(db, s); let mut r = SmallVec::<[_; 1]>::new(); r.push(handle_variant(s.into(), s.fields(db))?); ( diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs index e491c29df3..484ecebba5 100644 --- a/crates/hir-ty/src/layout/tests.rs +++ b/crates/hir-ty/src/layout/tests.rs @@ -1,6 +1,12 @@ use base_db::target::TargetData; use either::Either; -use hir_def::{HasModule, db::DefDatabase}; +use hir_def::{ + DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, HasModule, + expr_store::Body, + signatures::{ + EnumSignature, FunctionSignature, StructSignature, TypeAliasSignature, UnionSignature, + }, +}; use project_model::{Sysroot, toolchain_info::QueryConfig}; use rustc_hash::FxHashMap; use rustc_type_ir::inherent::GenericArgs as _; @@ -49,18 +55,15 @@ fn eval_goal( let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { - hir_def::AdtId::StructId(x) => db - .struct_signature(x) + hir_def::AdtId::StructId(x) => StructSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), - hir_def::AdtId::UnionId(x) => db - .union_signature(x) + hir_def::AdtId::UnionId(x) => UnionSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), - hir_def::AdtId::EnumId(x) => db - .enum_signature(x) + hir_def::AdtId::EnumId(x) => EnumSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), @@ -68,8 +71,7 @@ fn eval_goal( (name == "Goal").then_some(Either::Left(x)) } hir_def::ModuleDefId::TypeAliasId(x) => { - let name = db - .type_alias_signature(x) + let name = TypeAliasSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(); @@ -90,10 +92,13 @@ fn eval_goal( ), Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(), }; - let param_env = db.trait_environment(match adt_or_type_alias_id { - Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), - Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), - }); + let param_env = db.trait_environment( + match adt_or_type_alias_id { + Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), + Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), + } + .into(), + ); let krate = match adt_or_type_alias_id { Either::Left(it) => it.krate(&db), Either::Right(it) => it.krate(&db), @@ -123,8 +128,7 @@ fn eval_expr( .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - let name = db - .function_signature(x) + let name = FunctionSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(); @@ -133,15 +137,16 @@ fn eval_expr( _ => None, }) .unwrap(); - let hir_body = db.body(function_id.into()); + let hir_body = Body::of(&db, function_id.into()); let b = hir_body .bindings() .find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal") .unwrap() .0; - let infer = InferenceResult::for_body(&db, function_id.into()); + let infer = InferenceResult::of(&db, DefWithBodyId::from(function_id)); let goal_ty = infer.type_of_binding[b].clone(); - let param_env = db.trait_environment(function_id.into()); + let param_env = + db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(function_id))); let krate = function_id.krate(&db); db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }.store()) }) diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 8d87276a0b..e6b8329ca8 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -61,8 +61,8 @@ mod tests; use std::{hash::Hash, ops::ControlFlow}; use hir_def::{ - CallableDefId, GenericDefId, TypeAliasId, TypeOrConstParamId, TypeParamId, - hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness, + CallableDefId, ExpressionStoreOwnerId, GenericDefId, TypeAliasId, TypeOrConstParamId, + TypeParamId, hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness, }; use hir_expand::name::Name; use indexmap::{IndexMap, map::Entry}; @@ -507,7 +507,7 @@ pub fn associated_type_shorthand_candidates( let mut dedup_map = FxHashSet::default(); let param_ty = Ty::new_param(interner, param, param_idx(db, param.into()).unwrap() as u32); // We use the ParamEnv and not the predicates because the ParamEnv elaborates bounds. - let param_env = db.trait_environment(def); + let param_env = db.trait_environment(ExpressionStoreOwnerId::from(def)); for clause in param_env.clauses { let ClauseKind::Trait(trait_clause) = clause.kind().skip_binder() else { continue }; if trait_clause.self_ty() != param_ty { diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index c0bd897571..3ed563315e 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -13,10 +13,10 @@ use std::{cell::OnceCell, iter, mem}; use arrayvec::ArrayVec; use either::Either; use hir_def::{ - AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, - FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, - LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, UnionId, VariantId, + AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, EnumId, EnumVariantId, + ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, + ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, + TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId, builtin_type::BuiltinType, expr_store::{ExpressionStore, HygieneId, path::Path}, hir::generics::{ @@ -26,7 +26,10 @@ use hir_def::{ item_tree::FieldsShape, lang_item::LangItems, resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs}, - signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, + signatures::{ + ConstSignature, FunctionSignature, ImplSignature, StaticSignature, StructSignature, + TraitFlags, TraitSignature, TypeAliasFlags, TypeAliasSignature, + }, type_ref::{ ConstRef, FnType, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, @@ -178,7 +181,7 @@ pub struct TyLoweringContext<'db, 'a> { resolver: &'a Resolver<'db>, store: &'a ExpressionStore, def: GenericDefId, - generics: OnceCell<Generics>, + generics: OnceCell<Generics<'db>>, in_binders: DebruijnIndex, impl_trait_mode: ImplTraitLoweringState, /// Tracks types with explicit `?Sized` bounds. @@ -404,7 +407,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type)) } - fn generics(&self) -> &Generics { + fn generics(&self) -> &Generics<'db> { self.generics.get_or_init(|| generics(self.db, self.def)) } @@ -782,7 +785,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { match b.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); - let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO); + let is_auto = + TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO); if is_auto { auto_traits.push(t.def_id().0); } else { @@ -1166,7 +1170,7 @@ pub(crate) fn impl_trait_with_diagnostics<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> Option<(StoredEarlyBinder<(TraitId, StoredGenericArgs)>, Diagnostics)> { - let impl_data = db.impl_signature(impl_id); + let impl_data = ImplSignature::of(db, impl_id); let resolver = impl_id.resolver(db); let mut ctx = TyLoweringContext::new( db, @@ -1251,7 +1255,7 @@ impl ImplTraits { def: hir_def::FunctionId, ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe - let data = db.function_signature(def); + let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); let mut ctx_ret = TyLoweringContext::new( db, @@ -1279,7 +1283,7 @@ impl ImplTraits { db: &dyn HirDatabase, def: hir_def::TypeAliasId, ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { - let data = db.type_alias_signature(def); + let data = TypeAliasSignature::of(db, def); let resolver = def.resolver(db); let mut ctx = TyLoweringContext::new( db, @@ -1369,7 +1373,7 @@ fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Store /// Build the declared type of a const. fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); - let data = db.const_signature(def); + let data = ConstSignature::of(db, def); let parent = def.loc(db).container; let mut ctx = TyLoweringContext::new( db, @@ -1385,7 +1389,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<Store /// Build the declared type of a static. fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); - let data = db.static_signature(def); + let data = StaticSignature::of(db, def); let mut ctx = TyLoweringContext::new( db, &resolver, @@ -1402,7 +1406,7 @@ fn type_for_struct_constructor( db: &dyn HirDatabase, def: StructId, ) -> Option<StoredEarlyBinder<StoredTy>> { - let struct_data = db.struct_signature(def); + let struct_data = StructSignature::of(db, def); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.into())), @@ -1477,7 +1481,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics<'db>( db: &'db dyn HirDatabase, t: TypeAliasId, ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { - let type_alias_data = db.type_alias_signature(t); + let type_alias_data = TypeAliasSignature::of(db, t); let mut diags = None; let resolver = t.resolver(db); let interner = DbInterner::new_no_crate(db); @@ -1540,7 +1544,7 @@ pub(crate) fn impl_self_ty_with_diagnostics<'db>( ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { let resolver = impl_id.resolver(db); - let impl_data = db.impl_signature(impl_id); + let impl_data = ImplSignature::of(db, impl_id); let mut ctx = TyLoweringContext::new( db, &resolver, @@ -1586,14 +1590,14 @@ pub(crate) fn const_param_ty_with_diagnostics<'db>( _: (), def: ConstParamId, ) -> (StoredTy, Diagnostics) { - let (parent_data, store) = db.generic_params_and_store(def.parent()); + let (parent_data, store) = GenericParams::of(db, def.parent()); let data = &parent_data[def.local_id()]; let resolver = def.parent().resolver(db); let interner = DbInterner::new_no_crate(db); let mut ctx = TyLoweringContext::new( db, &resolver, - &store, + store, def.parent(), LifetimeElisionKind::AnonymousReportError, ); @@ -1684,7 +1688,7 @@ impl SupertraitsInfo { )); let resolver = trait_.resolver(db); - let signature = db.trait_signature(trait_); + let signature = TraitSignature::of(db, trait_); for pred in signature.generic_params.where_predicates() { let (WherePredicate::TypeBound { target, bound } | WherePredicate::ForLifetime { lifetimes: _, target, bound }) = pred @@ -1955,7 +1959,7 @@ fn type_alias_bounds_with_diagnostics<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> (TypeAliasBounds<StoredEarlyBinder<StoredClauses>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(type_alias); + let type_alias_data = TypeAliasSignature::of(db, type_alias); let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); let mut ctx = TyLoweringContext::new( db, @@ -2134,16 +2138,6 @@ impl GenericPredicates { } } -pub(crate) fn trait_environment_for_body_query( - db: &dyn HirDatabase, - def: DefWithBodyId, -) -> ParamEnv<'_> { - let Some(def) = def.as_generic_def_id(db) else { - return ParamEnv::empty(); - }; - db.trait_environment(def) -} - pub(crate) fn param_env_from_predicates<'db>( interner: DbInterner<'db>, predicates: &'db GenericPredicates, @@ -2158,7 +2152,18 @@ pub(crate) fn param_env_from_predicates<'db>( ParamEnv { clauses } } -pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> { +pub(crate) fn trait_environment<'db>( + db: &'db dyn HirDatabase, + def: ExpressionStoreOwnerId, +) -> ParamEnv<'db> { + let def = match def { + ExpressionStoreOwnerId::Signature(def) => def, + ExpressionStoreOwnerId::Body(def) => match def.as_generic_def_id(db) { + Some(def) => def, + None => return ParamEnv::empty(), + }, + }; + return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; #[salsa::tracked(returns(ref))] @@ -2358,7 +2363,7 @@ fn generic_predicates(db: &dyn HirDatabase, def: GenericDefId) -> (GenericPredic fn push_const_arg_has_type_predicates<'db>( db: &'db dyn HirDatabase, predicates: &mut Vec<Clause<'db>>, - generics: &Generics, + generics: &Generics<'db>, ) { let interner = DbInterner::new_no_crate(db); let const_params_offset = generics.len_parent() + generics.len_lifetimes_self(); @@ -2504,7 +2509,7 @@ pub(crate) fn callable_item_signature<'db>( } fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<StoredPolyFnSig> { - let data = db.function_signature(def); + let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); let mut ctx_params = TyLoweringContext::new( @@ -2512,7 +2517,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Sto &resolver, &data.store, def.into(), - LifetimeElisionKind::for_fn_params(&data), + LifetimeElisionKind::for_fn_params(data), ); let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr)); @@ -2590,7 +2595,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> { - let type_alias_data = db.type_alias_signature(type_alias); + let type_alias_data = TypeAliasSignature::of(db, type_alias); let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); let interner = DbInterner::new_no_crate(db); let mut ctx = TyLoweringContext::new( @@ -2612,7 +2617,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( .map_bound(|c| match c { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); - let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO); + let is_auto = TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO); if is_auto { Some(ExistentialPredicate::AutoTrait(t.def_id())) } else { diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs index 81a944128d..889f0792d3 100644 --- a/crates/hir-ty/src/lower/path.rs +++ b/crates/hir-ty/src/lower/path.rs @@ -14,7 +14,7 @@ use hir_def::{ GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance, }, resolver::{ResolveValueResult, TypeNs, ValueNs}, - signatures::TraitFlags, + signatures::{TraitFlags, TraitSignature}, type_ref::{TypeRef, TypeRefId}, }; use rustc_type_ir::{ @@ -625,10 +625,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { GenericDefId::TraitId(trait_) => { // RTN is prohibited anyways if we got here. let is_rtn = args.parenthesized == GenericArgsParentheses::ReturnTypeNotation; - let is_fn_trait = self - .ctx - .db - .trait_signature(trait_) + let is_fn_trait = TraitSignature::of(self.ctx.db, trait_) .flags .contains(TraitFlags::RUSTC_PAREN_SUGAR); is_rtn || !is_fn_trait @@ -1024,7 +1021,7 @@ pub(crate) trait GenericArgsLowerer<'db> { fn check_generic_args_len<'db>( args_and_bindings: Option<&HirGenericArgs>, def: GenericDefId, - def_generics: &Generics, + def_generics: &Generics<'db>, infer_args: bool, lifetime_elision: &LifetimeElisionKind<'db>, lowering_assoc_type_generics: bool, diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index ad4d79e68a..e058a25420 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -17,11 +17,12 @@ use hir_def::{ ImplId, ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, builtin_derive::BuiltinDeriveImplMethod, - expr_store::path::GenericArgs as HirGenericArgs, + expr_store::{Body, path::GenericArgs as HirGenericArgs}, hir::ExprId, lang_item::LangItems, nameres::{DefMap, block_def_map, crate_def_map}, resolver::Resolver, + signatures::{ConstSignature, FunctionSignature}, }; use intern::{Symbol, sym}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -366,7 +367,7 @@ pub fn lookup_impl_const<'db>( }; let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), subs); - let const_signature = db.const_signature(const_id); + let const_signature = ConstSignature::of(db, const_id); let name = match const_signature.name.as_ref() { Some(name) => name, None => return (const_id, subs), @@ -439,7 +440,7 @@ pub(crate) fn lookup_impl_method_query<'db>( GenericArgs::new_from_slice(&fn_subst[..trait_params]), ); - let name = &db.function_signature(func).name; + let name = &FunctionSignature::of(db, func).name; let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env.param_env, name).and_then( |(assoc, impl_args)| { @@ -623,7 +624,7 @@ impl InherentImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; for konst in module_data.scope.unnamed_consts() { - let body = db.body(konst.into()); + let body = Body::of(db, konst.into()); for (_, block_def_map) in body.blocks(db) { collect(db, block_def_map, map); } @@ -766,7 +767,7 @@ impl TraitImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; for konst in module_data.scope.unnamed_consts() { - let body = db.body(konst.into()); + let body = Body::of(db, konst.into()); for (_, block_def_map) in body.blocks(db) { collect(db, block_def_map, lang_items, map); } diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs index fc2bd87ee4..e2a53cc830 100644 --- a/crates/hir-ty/src/method_resolution/probe.rs +++ b/crates/hir-ty/src/method_resolution/probe.rs @@ -5,7 +5,7 @@ use std::{cell::RefCell, convert::Infallible, ops::ControlFlow}; use hir_def::{ AssocItemId, FunctionId, GenericParamId, ImplId, ItemContainerId, TraitId, - signatures::TraitFlags, + signatures::{FunctionSignature, TraitFlags, TraitSignature}, }; use hir_expand::name::Name; use rustc_ast_ir::Mutability; @@ -1605,7 +1605,8 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { // Some trait methods are excluded for arrays before 2021. // (`array.into_iter()` wants a slice iterator for compatibility.) if self_ty.is_array() && !self.ctx.edition.at_least_2021() { - let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0); + let trait_signature = + TraitSignature::of(self.db(), poly_trait_ref.def_id().0); if trait_signature .flags .contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH) @@ -1619,7 +1620,8 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { if self_ty.boxed_ty().is_some_and(Ty::is_slice) && !self.ctx.edition.at_least_2024() { - let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0); + let trait_signature = + TraitSignature::of(self.db(), poly_trait_ref.def_id().0); if trait_signature .flags .contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH) @@ -1963,7 +1965,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { // associated value (i.e., methods, constants). match item { CandidateId::FunctionId(id) if self.mode == Mode::MethodCall => { - self.db().function_signature(id).has_self_param() + FunctionSignature::of(self.db(), id).has_self_param() } _ => true, } diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs index 2dcc2d1062..3ff2db15aa 100644 --- a/crates/hir-ty/src/mir/borrowck.rs +++ b/crates/hir-ty/src/mir/borrowck.rs @@ -5,10 +5,10 @@ use std::iter; -use hir_def::{DefWithBodyId, HasModule}; +use hir_def::{DefWithBodyId, ExpressionStoreOwnerId, HasModule}; use la_arena::ArenaMap; use rustc_hash::FxHashMap; -use rustc_type_ir::inherent::{GenericArgs as _, Ty as _}; +use rustc_type_ir::inherent::GenericArgs as _; use stdx::never; use triomphe::Arc; @@ -18,7 +18,7 @@ use crate::{ display::DisplayTarget, mir::OperandKind, next_solver::{ - DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, StoredTy, Ty, TypingMode, + DbInterner, GenericArgs, ParamEnv, StoredTy, Ty, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, }; @@ -99,7 +99,7 @@ pub fn borrowck_query( let _p = tracing::info_span!("borrowck_query").entered(); let module = def.module(db); let interner = DbInterner::new_with(db, module.krate(db)); - let env = db.trait_environment_for_body(def); + let env = db.trait_environment(ExpressionStoreOwnerId::from(def)); let mut res = vec![]; // This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`. let typing_mode = TypingMode::borrowck(interner, def.into()); @@ -123,10 +123,7 @@ fn make_fetch_closure_field<'db>( |c: InternedClosureId, subst: GenericArgs<'db>, f: usize| { let InternedClosure(owner, _) = db.lookup_intern_closure(c); let interner = DbInterner::new_no_crate(db); - let Some(def) = owner.as_def_with_body() else { - return Ty::new_error(interner, ErrorGuaranteed); - }; - let infer = InferenceResult::for_body(db, def); + let infer = InferenceResult::of(db, owner); let (captures, _) = infer.closure_info(c); let parent_subst = subst.as_closure().parent_args(); captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst) diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index a85b3ef50a..c013e78d81 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -5,14 +5,17 @@ use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range}; use base_db::{Crate, target::TargetLoadError}; use either::Either; use hir_def::{ - AdtId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, HasModule, ItemContainerId, - Lookup, StaticId, VariantId, - expr_store::HygieneId, + AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, + HasModule, ItemContainerId, Lookup, StaticId, VariantId, + expr_store::{Body, HygieneId}, item_tree::FieldsShape, lang_item::LangItems, layout::{TagEncoding, Variants}, resolver::{HasResolver, TypeNs, ValueNs}, - signatures::{StaticFlags, StructFlags}, + signatures::{ + EnumSignature, FunctionSignature, StaticFlags, StaticSignature, StructFlags, + StructSignature, TraitSignature, + }, }; use hir_expand::{InFile, mod_path::path, name::Name}; use intern::sym; @@ -386,7 +389,7 @@ impl MirEvalError { for (func, span, def) in stack.iter().take(30).rev() { match func { Either::Left(func) => { - let function_name = db.function_signature(*func); + let function_name = FunctionSignature::of(db, *func); writeln!( f, "In function {} ({:?})", @@ -398,7 +401,7 @@ impl MirEvalError { writeln!(f, "In {closure:?}")?; } } - let source_map = db.body_with_source_map(*def).1; + let source_map = &Body::with_source_map(db, *def).1; let span: InFile<SyntaxNodePtr> = match span { MirSpan::ExprId(e) => match source_map.expr_syntax(*e) { Ok(s) => s.map(|it| it.into()), @@ -441,7 +444,7 @@ impl MirEvalError { )?; } MirEvalError::MirLowerError(func, err) => { - let function_name = db.function_signature(*func); + let function_name = FunctionSignature::of(db, *func); let self_ = match func.lookup(db).container { ItemContainerId::ImplId(impl_id) => Some({ db.impl_self_ty(impl_id) @@ -450,7 +453,10 @@ impl MirEvalError { .to_string() }), ItemContainerId::TraitId(it) => Some( - db.trait_signature(it).name.display(db, display_target.edition).to_string(), + TraitSignature::of(db, it) + .name + .display(db, display_target.edition) + .to_string(), ), _ => None, }; @@ -660,7 +666,7 @@ impl<'db> Evaluator<'db> { db, random_state: oorandom::Rand64::new(0), param_env: trait_env.unwrap_or_else(|| ParamEnvAndCrate { - param_env: db.trait_environment_for_body(owner), + param_env: db.trait_environment(ExpressionStoreOwnerId::from(owner)), krate: crate_id, }), crate_id, @@ -731,10 +737,7 @@ impl<'db> Evaluator<'db> { ty, |c, subst, f| { let InternedClosure(owner, _) = self.db.lookup_intern_closure(c); - let Some(def) = owner.as_def_with_body() else { - return Ty::new_error(self.interner(), ErrorGuaranteed); - }; - let infer = InferenceResult::for_body(self.db, def); + let infer = InferenceResult::of(self.db, owner); let (captures, _) = infer.closure_info(c); let parent_subst = subst.as_closure().parent_args(); captures @@ -896,8 +899,8 @@ impl<'db> Evaluator<'db> { OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?, OperandKind::Constant { konst: _, ty } => ty.as_ref(), &OperandKind::Static(s) => { - let ty = InferenceResult::for_body(self.db, s.into()) - .expr_ty(self.db.body(s.into()).body_expr); + let ty = InferenceResult::of(self.db, DefWithBodyId::from(s)) + .expr_ty(Body::of(self.db, s.into()).body_expr); Ty::new_ref( self.interner(), Region::new_static(self.interner()), @@ -2824,15 +2827,15 @@ impl<'db> Evaluator<'db> { if let Some(o) = self.static_locations.get(&st) { return Ok(*o); }; - let static_data = self.db.static_signature(st); + let static_data = StaticSignature::of(self.db, st); let result = if !static_data.flags.contains(StaticFlags::EXTERN) { let konst = self.db.const_eval_static(st).map_err(|e| { MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e)) })?; self.allocate_const_in_heap(locals, konst)? } else { - let ty = InferenceResult::for_body(self.db, st.into()) - .expr_ty(self.db.body(st.into()).body_expr); + let ty = InferenceResult::of(self.db, DefWithBodyId::from(st)) + .expr_ty(Body::of(self.db, st.into()).body_expr); let Some((size, align)) = self.size_align_of(ty, locals)? else { not_supported!("unsized extern static"); }; @@ -2855,7 +2858,7 @@ impl<'db> Evaluator<'db> { let edition = self.crate_id.data(self.db).edition; let name = format!( "{}::{}", - self.db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(self.db, loc.parent).name.display(db, edition), loc.parent .enum_variants(self.db) .variant_name_by_id(variant) @@ -2915,7 +2918,7 @@ impl<'db> Evaluator<'db> { let id = adt_def.def_id().0; match id { AdtId::StructId(s) => { - let data = self.db.struct_signature(s); + let data = StructSignature::of(self.db, s); if data.flags.contains(StructFlags::IS_MANUALLY_DROP) { return Ok(()); } diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 86d9510601..ff6c99ca53 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -45,7 +45,7 @@ impl<'db> Evaluator<'db> { return Ok(false); } - let function_data = self.db.function_signature(def); + let function_data = FunctionSignature::of(self.db, def); let attrs = AttrFlags::query(self.db, def.into()); let is_intrinsic = FunctionSignature::is_intrinsic(self.db, def); @@ -153,10 +153,7 @@ impl<'db> Evaluator<'db> { }; let addr = Address::from_bytes(arg.get(self)?)?; let InternedClosure(owner, _) = self.db.lookup_intern_closure(id.0); - let Some(closure_owner) = owner.as_def_with_body() else { - not_supported!("closure in non-body context"); - }; - let infer = InferenceResult::for_body(self.db, closure_owner); + let infer = InferenceResult::of(self.db, owner); let (captures, _) = infer.closure_info(id.0); let layout = self.layout(self_ty)?; let db = self.db; diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs index 61dd7757c9..6bf966c3ef 100644 --- a/crates/hir-ty/src/mir/eval/tests.rs +++ b/crates/hir-ty/src/mir/eval/tests.rs @@ -1,4 +1,4 @@ -use hir_def::{HasModule, db::DefDatabase}; +use hir_def::{GenericDefId, HasModule, signatures::FunctionSignature}; use hir_expand::EditionedFileId; use span::Edition; use syntax::{TextRange, TextSize}; @@ -25,7 +25,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - if db.function_signature(x).name.display(db, Edition::CURRENT).to_string() + if FunctionSignature::of(db, x).name.display(db, Edition::CURRENT).to_string() == "main" { Some(x) @@ -41,7 +41,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), func_id.into(), GenericArgs::empty(interner).store(), crate::ParamEnvAndCrate { - param_env: db.trait_environment(func_id.into()), + param_env: db.trait_environment(GenericDefId::from(func_id).into()), krate: func_id.krate(db), } .store(), diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 269d8729ba..8d85e2412f 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -4,8 +4,8 @@ use std::{fmt::Write, iter, mem}; use base_db::Crate; use hir_def::{ - AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, GenericParamId, HasModule, - ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, + AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericParamId, + HasModule, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm, @@ -14,6 +14,7 @@ use hir_def::{ item_tree::FieldsShape, lang_item::LangItems, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -185,7 +186,7 @@ impl MirLowerError { } } MirLowerError::MissingFunctionDefinition(owner, it) => { - let body = db.body(*owner); + let body = Body::of(db, *owner); writeln!( f, "Missing function definition for {}", @@ -307,7 +308,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { closures: vec![], }; let resolver = owner.resolver(db); - let env = db.trait_environment_for_body(owner); + let env = db.trait_environment(ExpressionStoreOwnerId::from(owner)); let interner = DbInterner::new_with(db, resolver.krate()); // FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body? let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); @@ -472,7 +473,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { if let DefWithBodyId::FunctionId(f) = self.owner { let assoc = f.lookup(self.db); if let ItemContainerId::TraitId(t) = assoc.container { - let name = &self.db.function_signature(f).name; + let name = &FunctionSignature::of(self.db, f).name; return Err(MirLowerError::TraitFunctionDefinition(t, name.clone())); } } @@ -1993,7 +1994,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { let loc = variant.lookup(db); let name = format!( "{}::{}", - self.db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(db, loc.parent).name.display(db, edition), loc.parent .enum_variants(self.db) .variant_name_by_id(variant) @@ -2112,8 +2113,8 @@ pub fn mir_body_for_closure_query<'db>( let InternedClosure(owner, expr) = db.lookup_intern_closure(closure); let body_owner = owner.as_def_with_body().expect("MIR lowering should only happen for body-owned closures"); - let body = db.body(body_owner); - let infer = InferenceResult::for_body(db, body_owner); + let body = Body::of(db, body_owner); + let infer = InferenceResult::of(db, body_owner); let Expr::Closure { args, body: root, .. } = &body[expr] else { implementation_error!("closure expression is not closure"); }; @@ -2228,13 +2229,12 @@ pub fn mir_body_query<'db>( let edition = krate.data(db).edition; let detail = match def { DefWithBodyId::FunctionId(it) => { - db.function_signature(it).name.display(db, edition).to_string() + FunctionSignature::of(db, it).name.display(db, edition).to_string() } DefWithBodyId::StaticId(it) => { - db.static_signature(it).name.display(db, edition).to_string() + StaticSignature::of(db, it).name.display(db, edition).to_string() } - DefWithBodyId::ConstId(it) => db - .const_signature(it) + DefWithBodyId::ConstId(it) => ConstSignature::of(db, it) .name .clone() .unwrap_or_else(Name::missing) @@ -2249,9 +2249,9 @@ pub fn mir_body_query<'db>( } }; let _p = tracing::info_span!("mir_body_query", ?detail).entered(); - let body = db.body(def); - let infer = InferenceResult::for_body(db, def); - let mut result = lower_body_to_mir(db, def, &body, infer, body.body_expr)?; + let body = Body::of(db, def); + let infer = InferenceResult::of(db, def); + let mut result = lower_body_to_mir(db, def, body, infer, body.body_expr)?; result.shrink_to_fit(); Ok(Arc::new(result)) } diff --git a/crates/hir-ty/src/mir/pretty.rs b/crates/hir-ty/src/mir/pretty.rs index 96b90a3f40..4b654a0fbe 100644 --- a/crates/hir-ty/src/mir/pretty.rs +++ b/crates/hir-ty/src/mir/pretty.rs @@ -6,7 +6,11 @@ use std::{ }; use either::Either; -use hir_def::{expr_store::Body, hir::BindingId}; +use hir_def::{ + expr_store::Body, + hir::BindingId, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, +}; use hir_expand::{Lookup, name::Name}; use la_arena::ArenaMap; @@ -38,19 +42,19 @@ macro_rules! wln { impl MirBody { pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { - let hir_body = db.body(self.owner); - let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target); + let hir_body = Body::of(db, self.owner); + let mut ctx = MirPrettyCtx::new(self, hir_body, db, display_target); ctx.for_body(|this| match ctx.body.owner { hir_def::DefWithBodyId::FunctionId(id) => { - let data = db.function_signature(id); + let data = FunctionSignature::of(db, id); w!(this, "fn {}() ", data.name.display(db, this.display_target.edition)); } hir_def::DefWithBodyId::StaticId(id) => { - let data = db.static_signature(id); + let data = StaticSignature::of(db, id); w!(this, "static {}: _ = ", data.name.display(db, this.display_target.edition)); } hir_def::DefWithBodyId::ConstId(id) => { - let data = db.const_signature(id); + let data = ConstSignature::of(db, id); w!( this, "const {}: _ = ", @@ -66,7 +70,7 @@ impl MirBody { w!( this, "enum {}::{} = ", - db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(db, loc.parent).name.display(db, edition), loc.parent .enum_variants(db) .variant_name_by_id(id) diff --git a/crates/hir-ty/src/next_solver/def_id.rs b/crates/hir-ty/src/next_solver/def_id.rs index f725af320d..5d122ce446 100644 --- a/crates/hir-ty/src/next_solver/def_id.rs +++ b/crates/hir-ty/src/next_solver/def_id.rs @@ -2,8 +2,12 @@ use hir_def::{ AdtId, AnonConstId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, - EnumId, EnumVariantId, ExpressionStoreOwner, FunctionId, GeneralConstId, GenericDefId, ImplId, - StaticId, StructId, TraitId, TypeAliasId, UnionId, + EnumId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, + ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, StaticSignature, StructSignature, + TraitSignature, TypeAliasSignature, UnionSignature, + }, }; use rustc_type_ir::inherent; use stdx::impl_from; @@ -42,32 +46,33 @@ impl std::fmt::Debug for SolverDefId { let db = interner.db; match *self { SolverDefId::AdtId(AdtId::StructId(id)) => { - f.debug_tuple("AdtId").field(&db.struct_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&StructSignature::of(db, id).name.as_str()).finish() } SolverDefId::AdtId(AdtId::EnumId(id)) => { - f.debug_tuple("AdtId").field(&db.enum_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&EnumSignature::of(db, id).name.as_str()).finish() } SolverDefId::AdtId(AdtId::UnionId(id)) => { - f.debug_tuple("AdtId").field(&db.union_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&UnionSignature::of(db, id).name.as_str()).finish() } SolverDefId::ConstId(id) => f .debug_tuple("ConstId") - .field(&db.const_signature(id).name.as_ref().map_or("_", |name| name.as_str())) + .field(&ConstSignature::of(db, id).name.as_ref().map_or("_", |name| name.as_str())) + .finish(), + SolverDefId::FunctionId(id) => f + .debug_tuple("FunctionId") + .field(&FunctionSignature::of(db, id).name.as_str()) .finish(), - SolverDefId::FunctionId(id) => { - f.debug_tuple("FunctionId").field(&db.function_signature(id).name.as_str()).finish() - } SolverDefId::ImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), SolverDefId::BuiltinDeriveImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), SolverDefId::StaticId(id) => { - f.debug_tuple("StaticId").field(&db.static_signature(id).name.as_str()).finish() + f.debug_tuple("StaticId").field(&StaticSignature::of(db, id).name.as_str()).finish() } SolverDefId::TraitId(id) => { - f.debug_tuple("TraitId").field(&db.trait_signature(id).name.as_str()).finish() + f.debug_tuple("TraitId").field(&TraitSignature::of(db, id).name.as_str()).finish() } SolverDefId::TypeAliasId(id) => f .debug_tuple("TypeAliasId") - .field(&db.type_alias_signature(id).name.as_str()) + .field(&TypeAliasSignature::of(db, id).name.as_str()) .finish(), SolverDefId::InternedClosureId(id) => { f.debug_tuple("InternedClosureId").field(&id).finish() @@ -83,21 +88,21 @@ impl std::fmt::Debug for SolverDefId { f.debug_tuple("EnumVariantId") .field(&format_args!( "\"{}::{}\"", - db.enum_signature(parent_enum).name.as_str(), + EnumSignature::of(db, parent_enum).name.as_str(), parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str() )) .finish() } SolverDefId::AnonConstId(id) => f.debug_tuple("AnonConstId").field(&id).finish(), SolverDefId::Ctor(Ctor::Struct(id)) => { - f.debug_tuple("Ctor").field(&db.struct_signature(id).name.as_str()).finish() + f.debug_tuple("Ctor").field(&StructSignature::of(db, id).name.as_str()).finish() } SolverDefId::Ctor(Ctor::Enum(id)) => { let parent_enum = id.loc(db).parent; f.debug_tuple("Ctor") .field(&format_args!( "\"{}::{}\"", - db.enum_signature(parent_enum).name.as_str(), + EnumSignature::of(db, parent_enum).name.as_str(), parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str() )) .finish() @@ -138,15 +143,6 @@ impl From<GenericDefId> for SolverDefId { } } -impl From<ExpressionStoreOwner> for SolverDefId { - fn from(value: ExpressionStoreOwner) -> Self { - match value { - ExpressionStoreOwner::Signature(generic_def_id) => generic_def_id.into(), - ExpressionStoreOwner::Body(def_with_body_id) => def_with_body_id.into(), - } - } -} - impl From<GeneralConstId> for SolverDefId { #[inline] fn from(value: GeneralConstId) -> Self { @@ -170,6 +166,16 @@ impl From<DefWithBodyId> for SolverDefId { } } +impl From<ExpressionStoreOwnerId> for SolverDefId { + #[inline] + fn from(value: ExpressionStoreOwnerId) -> Self { + match value { + ExpressionStoreOwnerId::Body(body_id) => body_id.into(), + ExpressionStoreOwnerId::Signature(sig_id) => sig_id.into(), + } + } +} + impl TryFrom<SolverDefId> for AttrDefId { type Error = (); #[inline] diff --git a/crates/hir-ty/src/next_solver/fulfill/errors.rs b/crates/hir-ty/src/next_solver/fulfill/errors.rs index 8f798b4ade..0e8218b33a 100644 --- a/crates/hir-ty/src/next_solver/fulfill/errors.rs +++ b/crates/hir-ty/src/next_solver/fulfill/errors.rs @@ -617,6 +617,7 @@ impl<'db> NextSolverError<'db> { } mod wf { + use hir_def::signatures::ImplSignature; use hir_def::{GeneralConstId, ItemContainerId}; use rustc_type_ir::inherent::{ AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Term as _, @@ -1054,7 +1055,7 @@ mod wf { if let GeneralConstId::ConstId(uv_def) = uv.def.0 && let ItemContainerId::ImplId(impl_) = uv_def.loc(self.interner().db).container - && self.interner().db.impl_signature(impl_).target_trait.is_none() + && ImplSignature::of(self.interner().db, impl_).target_trait.is_none() { return; // Subtree is handled by above function } else { diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs index dba4e74730..5b81c7675d 100644 --- a/crates/hir-ty/src/next_solver/interner.rs +++ b/crates/hir-ty/src/next_solver/interner.rs @@ -10,11 +10,15 @@ pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db}; use base_db::Crate; use hir_def::{ - AdtId, CallableDefId, DefWithBodyId, EnumVariantId, ExpressionStoreOwner, HasModule, + AdtId, CallableDefId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, HasModule, ItemContainerId, StructId, UnionId, VariantId, attrs::AttrFlags, + expr_store::{Body, ExpressionStore}, lang_item::LangItems, - signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags}, + signatures::{ + EnumSignature, FieldData, FnFlags, FunctionSignature, ImplFlags, ImplSignature, + StructFlags, StructSignature, TraitFlags, TraitSignature, UnionSignature, + }, }; use la_arena::Idx; use rustc_abi::{ReprFlags, ReprOptions}; @@ -548,7 +552,7 @@ impl AdtDef { let db = interner.db(); let (flags, variants, repr) = match def_id { AdtId::StructId(struct_id) => { - let data = db.struct_signature(struct_id); + let data = StructSignature::of(db, struct_id); let flags = AdtFlags { is_enum: false, @@ -775,15 +779,15 @@ impl fmt::Debug for AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { crate::with_attached_db(|db| match self.inner().id { AdtId::StructId(struct_id) => { - let data = db.struct_signature(struct_id); + let data = StructSignature::of(db, struct_id); f.write_str(data.name.as_str()) } AdtId::UnionId(union_id) => { - let data = db.union_signature(union_id); + let data = UnionSignature::of(db, union_id); f.write_str(data.name.as_str()) } AdtId::EnumId(enum_id) => { - let data = db.enum_signature(enum_id); + let data = EnumSignature::of(db, enum_id); f.write_str(data.name.as_str()) } }) @@ -1231,7 +1235,7 @@ impl<'db> Interner for DbInterner<'db> { SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque, SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container { ItemContainerId::ImplId(impl_) - if self.db.impl_signature(impl_).target_trait.is_none() => + if ImplSignature::of(self.db, impl_).target_trait.is_none() => { AliasTyKind::Inherent } @@ -1250,7 +1254,7 @@ impl<'db> Interner for DbInterner<'db> { SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy, SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container { ItemContainerId::ImplId(impl_) - if self.db.impl_signature(impl_).target_trait.is_none() => + if ImplSignature::of(self.db, impl_).target_trait.is_none() => { AliasTermKind::InherentTy } @@ -1353,11 +1357,8 @@ impl<'db> Interner for DbInterner<'db> { // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let Some(body_owner) = owner.as_def_with_body() else { - return rustc_ast_ir::Movability::Static; - }; - let body = self.db.body(body_owner); - let expr = &body[expr_id]; + let store = ExpressionStore::of(self.db, owner); + let expr = &store[expr_id]; match *expr { hir_def::hir::Expr::Closure { closure_kind, .. } => match closure_kind { hir_def::hir::ClosureKind::Coroutine(movability) => match movability { @@ -1929,7 +1930,7 @@ impl<'db> Interner for DbInterner<'db> { fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool { match impl_def_id { - AnyImplId::ImplId(impl_id) => self.db.impl_signature(impl_id).is_default(), + AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(), AnyImplId::BuiltinDeriveImplId(_) => false, } } @@ -1956,7 +1957,7 @@ impl<'db> Interner for DbInterner<'db> { let AnyImplId::ImplId(impl_id) = impl_id else { return ImplPolarity::Positive; }; - let impl_data = self.db().impl_signature(impl_id); + let impl_data = ImplSignature::of(self.db(), impl_id); if impl_data.flags.contains(ImplFlags::NEGATIVE) { ImplPolarity::Negative } else { @@ -1965,12 +1966,12 @@ impl<'db> Interner for DbInterner<'db> { } fn trait_is_auto(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::AUTO) } fn trait_is_alias(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::ALIAS) } @@ -1979,7 +1980,7 @@ impl<'db> Interner for DbInterner<'db> { } fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::FUNDAMENTAL) } @@ -2002,12 +2003,9 @@ impl<'db> Interner for DbInterner<'db> { // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let Some(body_owner) = owner.as_def_with_body() else { - return false; - }; - let body = self.db.body(body_owner); + let store = ExpressionStore::of(self.db, owner); matches!( - body[expr_id], + store[expr_id], hir_def::hir::Expr::Closure { closure_kind: hir_def::hir::ClosureKind::Coroutine(_), .. @@ -2019,12 +2017,9 @@ impl<'db> Interner for DbInterner<'db> { // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let Some(body_owner) = owner.as_def_with_body() else { - return false; - }; - let body = self.db.body(body_owner); + let store = ExpressionStore::of(self.db, owner); matches!( - body[expr_id], + store[expr_id], hir_def::hir::Expr::Closure { closure_kind: hir_def::hir::ClosureKind::Async, .. } | hir_def::hir::Expr::Async { .. } ) @@ -2145,7 +2140,7 @@ impl<'db> Interner for DbInterner<'db> { crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result); // Collect coroutines. - let body = self.db.body(def_id); + let body = Body::of(self.db, def_id); body.exprs().for_each(|(expr_id, expr)| { if matches!( expr, @@ -2158,7 +2153,7 @@ impl<'db> Interner for DbInterner<'db> { ) { let coroutine = InternedCoroutineId::new( self.db, - InternedCoroutine(ExpressionStoreOwner::Body(def_id), expr_id), + InternedCoroutine(ExpressionStoreOwnerId::Body(def_id), expr_id), ); result.push(coroutine.into()); } @@ -2188,7 +2183,7 @@ impl<'db> Interner for DbInterner<'db> { CallableDefId::FunctionId(id) => id, _ => return false, }; - self.db().function_signature(id).flags.contains(FnFlags::CONST) + FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST) } fn impl_is_const(self, _def_id: Self::ImplId) -> bool { @@ -2236,11 +2231,11 @@ impl<'db> Interner for DbInterner<'db> { } fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool { - self.db().trait_signature(trait_.0).flags.contains(TraitFlags::COINDUCTIVE) + TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE) } fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool { - self.db().trait_signature(trait_.0).flags.contains(TraitFlags::UNSAFE) + TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE) } fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool { diff --git a/crates/hir-ty/src/next_solver/ir_print.rs b/crates/hir-ty/src/next_solver/ir_print.rs index 65931549db..e0732b3473 100644 --- a/crates/hir-ty/src/next_solver/ir_print.rs +++ b/crates/hir-ty/src/next_solver/ir_print.rs @@ -1,5 +1,6 @@ //! Things related to IR printing in the next-trait-solver. +use hir_def::signatures::{TraitSignature, TypeAliasSignature}; use rustc_type_ir::{self as ty, ir_print::IrPrint}; use super::SolverDefId; @@ -14,7 +15,7 @@ impl<'db> IrPrint<ty::AliasTy<Self>> for DbInterner<'db> { crate::with_attached_db(|db| match t.def_id { SolverDefId::TypeAliasId(id) => fmt.write_str(&format!( "AliasTy({:?}[{:?}])", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args )), SolverDefId::InternedOpaqueTyId(id) => { @@ -34,7 +35,7 @@ impl<'db> IrPrint<ty::AliasTerm<Self>> for DbInterner<'db> { crate::with_attached_db(|db| match t.def_id { SolverDefId::TypeAliasId(id) => fmt.write_str(&format!( "AliasTerm({:?}[{:?}])", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args )), SolverDefId::InternedOpaqueTyId(id) => { @@ -58,13 +59,13 @@ impl<'db> IrPrint<ty::TraitRef<Self>> for DbInterner<'db> { fmt.write_str(&format!( "{:?}: {}", self_ty, - db.trait_signature(trait_).name.as_str() + TraitSignature::of(db, trait_).name.as_str() )) } else { fmt.write_str(&format!( "{:?}: {}<{:?}>", self_ty, - db.trait_signature(trait_).name.as_str(), + TraitSignature::of(db, trait_).name.as_str(), trait_args )) } @@ -121,7 +122,7 @@ impl<'db> IrPrint<ty::ExistentialTraitRef<Self>> for DbInterner<'db> { let trait_ = t.def_id.0; fmt.write_str(&format!( "ExistentialTraitRef({:?}[{:?}])", - db.trait_signature(trait_).name.as_str(), + TraitSignature::of(db, trait_).name.as_str(), t.args )) }) @@ -146,7 +147,7 @@ impl<'db> IrPrint<ty::ExistentialProjection<Self>> for DbInterner<'db> { }; fmt.write_str(&format!( "ExistentialProjection(({:?}[{:?}]) -> {:?})", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args, t.term )) @@ -172,7 +173,7 @@ impl<'db> IrPrint<ty::ProjectionPredicate<Self>> for DbInterner<'db> { }; fmt.write_str(&format!( "ProjectionPredicate(({:?}[{:?}]) -> {:?})", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.projection_term.args, t.term )) diff --git a/crates/hir-ty/src/next_solver/solver.rs b/crates/hir-ty/src/next_solver/solver.rs index 54baa8ac41..848bb110af 100644 --- a/crates/hir-ty/src/next_solver/solver.rs +++ b/crates/hir-ty/src/next_solver/solver.rs @@ -1,6 +1,9 @@ //! Defining `SolverContext` for next-trait-solver. -use hir_def::{AssocItemId, GeneralConstId}; +use hir_def::{ + AssocItemId, GeneralConstId, + signatures::{ConstSignature, TypeAliasSignature}, +}; use rustc_next_trait_solver::delegate::SolverDelegate; use rustc_type_ir::{ AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags, @@ -181,52 +184,53 @@ impl<'db> SolverDelegate for SolverContext<'db> { return Ok(None); }; let impl_items = impl_id.impl_items(self.0.interner.db()); - let id = - match trait_assoc_def_id { - SolverDefId::TypeAliasId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id - && *impl_assoc_name == trait_assoc_data.name - { - Some(impl_assoc_id) - } else { - None - } - }) - .or_else(|| { - if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None } - }) - .map(SolverDefId::TypeAliasId) - } - SolverDefId::ConstId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id); - let trait_assoc_name = trait_assoc_data - .name - .as_ref() - .expect("unnamed consts should not get passed to the solver"); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id - && impl_assoc_name == trait_assoc_name - { - Some(impl_assoc_id) - } else { - None - } - }) - .or_else(|| { + let id = match trait_assoc_def_id { + SolverDefId::TypeAliasId(trait_assoc_id) => { + let trait_assoc_data = TypeAliasSignature::of(self.0.interner.db, trait_assoc_id); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id + && *impl_assoc_name == trait_assoc_data.name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else(|| { + if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None } + }) + .map(SolverDefId::TypeAliasId) + } + SolverDefId::ConstId(trait_assoc_id) => { + let trait_assoc_data = ConstSignature::of(self.0.interner.db, trait_assoc_id); + let trait_assoc_name = trait_assoc_data + .name + .as_ref() + .expect("unnamed consts should not get passed to the solver"); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id + && impl_assoc_name == trait_assoc_name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else( + || { if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None } - }) - .map(SolverDefId::ConstId) - } - _ => panic!("Unexpected SolverDefId"), - }; + }, + ) + .map(SolverDefId::ConstId) + } + _ => panic!("Unexpected SolverDefId"), + }; Ok(id) } diff --git a/crates/hir-ty/src/opaques.rs b/crates/hir-ty/src/opaques.rs index 27ae5e39d5..ce93a33422 100644 --- a/crates/hir-ty/src/opaques.rs +++ b/crates/hir-ty/src/opaques.rs @@ -1,7 +1,8 @@ //! Handling of opaque types, detection of defining scope and hidden type. use hir_def::{ - AssocItemId, AssocItemLoc, DefWithBodyId, FunctionId, HasModule, ItemContainerId, TypeAliasId, + AssocItemId, AssocItemLoc, DefWithBodyId, ExpressionStoreOwnerId, FunctionId, GenericDefId, + HasModule, ItemContainerId, TypeAliasId, signatures::ImplSignature, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -55,7 +56,7 @@ pub(crate) fn opaque_types_defined_by( }; let extend_with_atpit_from_container = |container| match container { ItemContainerId::ImplId(impl_id) => { - if db.impl_signature(impl_id).target_trait.is_some() { + if ImplSignature::of(db, impl_id).target_trait.is_some() { extend_with_atpit_from_assoc_items(&impl_id.impl_items(db).items); } } @@ -94,7 +95,7 @@ pub(crate) fn rpit_hidden_types<'db>( db: &'db dyn HirDatabase, function: FunctionId, ) -> ArenaMap<ImplTraitIdx, StoredEarlyBinder<StoredTy>> { - let infer = InferenceResult::for_body(db, function.into()); + let infer = InferenceResult::of(db, DefWithBodyId::from(function)); let mut result = ArenaMap::new(); for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) { result.insert(opaque, StoredEarlyBinder::bind(hidden_type.store())); @@ -122,13 +123,14 @@ pub(crate) fn tait_hidden_types<'db>( let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); - let param_env = db.trait_environment(type_alias.into()); + let param_env = + db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(type_alias))); let defining_bodies = tait_defining_bodies(db, &loc); let mut result = ArenaMap::with_capacity(taits_count); for defining_body in defining_bodies { - let infer = InferenceResult::for_body(db, defining_body); + let infer = InferenceResult::of(db, defining_body); for (&opaque, hidden_type) in &infer.type_of_opaque { let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else { continue; @@ -195,7 +197,7 @@ fn tait_defining_bodies( }; match loc.container { ItemContainerId::ImplId(impl_id) => { - if db.impl_signature(impl_id).target_trait.is_some() { + if ImplSignature::of(db, impl_id).target_trait.is_some() { return from_assoc_items(&impl_id.impl_items(db).items); } } diff --git a/crates/hir-ty/src/specialization.rs b/crates/hir-ty/src/specialization.rs index d97a35549c..90cbcfea6a 100644 --- a/crates/hir-ty/src/specialization.rs +++ b/crates/hir-ty/src/specialization.rs @@ -1,6 +1,9 @@ //! Impl specialization related things -use hir_def::{HasModule, ImplId, nameres::crate_def_map}; +use hir_def::{ + ExpressionStoreOwnerId, GenericDefId, HasModule, ImplId, nameres::crate_def_map, + signatures::ImplSignature, +}; use intern::sym; use tracing::debug; @@ -45,11 +48,13 @@ fn specializes_query( specializing_impl_def_id: ImplId, parent_impl_def_id: ImplId, ) -> bool { - let trait_env = db.trait_environment(specializing_impl_def_id.into()); + let trait_env = db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + specializing_impl_def_id, + ))); let interner = DbInterner::new_with(db, specializing_impl_def_id.krate(db)); - let specializing_impl_signature = db.impl_signature(specializing_impl_def_id); - let parent_impl_signature = db.impl_signature(parent_impl_def_id); + let specializing_impl_signature = ImplSignature::of(db, specializing_impl_def_id); + let parent_impl_signature = ImplSignature::of(db, parent_impl_def_id); // We determine whether there's a subset relationship by: // diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs index 042f0568f3..430a570444 100644 --- a/crates/hir-ty/src/tests.rs +++ b/crates/hir-ty/src/tests.rs @@ -18,7 +18,6 @@ use expect_test::Expect; use hir_def::{ AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax, - db::DefDatabase, expr_store::{Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap}, hir::{ExprId, Pat, PatId}, item_scope::ItemScope, @@ -146,15 +145,15 @@ fn check_impl( let mut unexpected_type_mismatches = String::new(); for (def, krate) in defs { let display_target = DisplayTarget::from_crate(&db, krate); - let (body, body_source_map) = db.body_with_source_map(def); - let inference_result = InferenceResult::for_body(&db, def); + let (body, body_source_map) = Body::with_source_map(&db, def); + let inference_result = InferenceResult::of(&db, def); for (pat, ty) in inference_result.type_of_pat.iter() { let mut ty = ty.as_ref(); if let Pat::Bind { id, .. } = body[pat] { ty = inference_result.type_of_binding[id].as_ref(); } - let node = match pat_node(&body_source_map, pat, &db) { + let node = match pat_node(body_source_map, pat, &db) { Some(value) => value, None => continue, }; @@ -171,7 +170,7 @@ fn check_impl( for (expr, ty) in inference_result.type_of_expr.iter() { let ty = ty.as_ref(); - let node = match expr_node(&body_source_map, expr, &db) { + let node = match expr_node(body_source_map, expr, &db) { Some(value) => value, None => continue, }; @@ -202,9 +201,9 @@ fn check_impl( for (expr_or_pat, mismatch) in inference_result.type_mismatches() { let Some(node) = (match expr_or_pat { hir_def::hir::ExprOrPatId::ExprId(expr) => { - expr_node(&body_source_map, expr, &db) + expr_node(body_source_map, expr, &db) } - hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db), + hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(body_source_map, pat, &db), }) else { continue; }; @@ -223,7 +222,7 @@ fn check_impl( } for (type_ref, ty) in inference_result.placeholder_types() { - let node = match type_node(&body_source_map, type_ref, &db) { + let node = match type_node(body_source_map, type_ref, &db) { Some(value) => value, None => continue, }; @@ -487,22 +486,22 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } }); for (def, krate) in defs { - let (body, source_map) = db.body_with_source_map(def); - let infer = InferenceResult::for_body(&db, def); + let (body, source_map) = Body::with_source_map(&db, def); + let infer = InferenceResult::of(&db, def); let self_param = body.self_param.map(|id| (id, source_map.self_param_syntax())); - infer_def(infer, &body, &source_map, self_param, krate); + infer_def(infer, body, source_map, self_param, krate); } // Also infer signature const expressions (array lengths, const generic args, etc.) generic_defs.dedup(); for (def, krate) in generic_defs { - let (_, store, source_map) = db.generic_params_and_store_and_source_map(def); + let (store, source_map) = ExpressionStore::with_source_map(&db, def.into()); // Skip if there are no const expressions in the signature if store.const_expr_origins().is_empty() { continue; } - let infer = InferenceResult::for_signature(&db, def); - infer_def(infer, &store, &source_map, None, krate); + let infer = InferenceResult::of(&db, def); + infer_def(infer, store, source_map, None, krate); } buf.truncate(buf.trim_end().len()); @@ -522,14 +521,14 @@ pub(crate) fn visit_module( for &(_, item) in impl_data.items.iter() { match item { AssocItemId::FunctionId(it) => { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); } AssocItemId::ConstId(it) => { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); } AssocItemId::TypeAliasId(it) => { cb(it.into()); @@ -548,22 +547,22 @@ pub(crate) fn visit_module( cb(decl); match decl { ModuleDefId::FunctionId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::ConstId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::StaticId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => { it.enum_variants(db).variants.iter().for_each(|&(it, _, _)| { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); }); } ModuleDefId::TraitId(it) => { @@ -653,16 +652,14 @@ fn salsa_bug() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { - InferenceResult::for_body( - &db, - match def { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::EnumVariantId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => return, - }, - ); + let body_def: DefWithBodyId = match def { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::EnumVariantId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => return, + }; + InferenceResult::of(&db, body_def); }); }); @@ -697,16 +694,14 @@ fn salsa_bug() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { - InferenceResult::for_body( - &db, - match def { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::EnumVariantId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => return, - }, - ); + let body_def: DefWithBodyId = match def { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::EnumVariantId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => return, + }; + InferenceResult::of(&db, body_def); }); }) } diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index 6e55641e56..9e68756821 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -1,5 +1,8 @@ use expect_test::{Expect, expect}; -use hir_def::db::DefDatabase; +use hir_def::{ + DefWithBodyId, + expr_store::{Body, ExpressionStore}, +}; use hir_expand::{HirFileId, files::InFileWrapper}; use itertools::Itertools; use span::TextRange; @@ -28,20 +31,20 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let mut captures_info = Vec::new(); for def in defs { - let def = match def { + let def: DefWithBodyId = match def { hir_def::ModuleDefId::FunctionId(it) => it.into(), hir_def::ModuleDefId::EnumVariantId(it) => it.into(), hir_def::ModuleDefId::ConstId(it) => it.into(), hir_def::ModuleDefId::StaticId(it) => it.into(), _ => continue, }; - let infer = InferenceResult::for_body(&db, def); + let infer = InferenceResult::of(&db, def); let db = &db; captures_info.extend(infer.closure_info.iter().flat_map( |(closure_id, (captures, _))| { let closure = db.lookup_intern_closure(*closure_id); - let body_owner = closure.0.as_def_with_body().unwrap(); - let source_map = db.body_with_source_map(body_owner).1; + let body_owner = closure.0; + let source_map = ExpressionStore::with_source_map(db, body_owner).1; let closure_text_range = source_map .expr_syntax(closure.1) .expect("failed to map closure to SyntaxNode") @@ -57,7 +60,8 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec } // FIXME: Deduplicate this with hir::Local::sources(). - let (body, source_map) = db.body_with_source_map(body_owner); + let (body, source_map) = + Body::with_source_map(db, body_owner.as_def_with_body().unwrap()); let local_text_range = match body.self_param.zip(source_map.self_param_syntax()) { Some((param, source)) if param == capture.local() => { diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs index 0fbf8acf53..3e8089c9c1 100644 --- a/crates/hir-ty/src/tests/incremental.rs +++ b/crates/hir-ty/src/tests/incremental.rs @@ -24,7 +24,7 @@ fn foo() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -38,17 +38,17 @@ fn foo() -> i32 { "parse_shim", "real_span_map_shim", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", + "ExprScopes::body_expr_scopes_", ] "#]], ); @@ -69,7 +69,7 @@ fn foo() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -81,10 +81,10 @@ fn foo() -> i32 { "file_item_tree_query", "real_span_map_shim", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", ] "#]], ); @@ -112,7 +112,7 @@ fn baz() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -126,37 +126,37 @@ fn baz() -> i32 { "parse_shim", "real_span_map_shim", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", + "ExprScopes::body_expr_scopes_", ] "#]], ); @@ -182,7 +182,7 @@ fn baz() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -194,22 +194,22 @@ fn baz() -> i32 { "file_item_tree_query", "real_span_map_shim", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "InferenceResult::for_body_", - "body_expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", ] "#]], ); @@ -562,7 +562,7 @@ fn main() { }); for def in defs { - let _inference_result = InferenceResult::for_body(&db, def); + let _inference_result = InferenceResult::of(&db, def); } }, &[("trait_solve_shim", 0)], @@ -575,19 +575,19 @@ fn main() { "parse_shim", "real_span_map_shim", "TraitItems::query_with_diagnostics_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "AttrFlags::query_", "ImplItems::of_", "InferenceResult::for_body_", - "trait_signature_shim", - "trait_signature_with_source_map_shim", + "TraitSignature::of_", + "TraitSignature::with_source_map_", "AttrFlags::query_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", @@ -595,14 +595,14 @@ fn main() { "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", - "struct_signature_shim", - "struct_signature_with_source_map_shim", + "ExprScopes::body_expr_scopes_", + "StructSignature::of_", + "StructSignature::with_source_map_", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "value_ty_query", @@ -611,8 +611,8 @@ fn main() { "TraitImpls::for_crate_and_deps_", "TraitImpls::for_crate_", "impl_trait_with_diagnostics_query", - "impl_signature_shim", - "impl_signature_with_source_map_shim", + "ImplSignature::of_", + "ImplSignature::with_source_map_", "impl_self_ty_with_diagnostics_query", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", @@ -658,7 +658,7 @@ fn main() { }); for def in defs { - let _inference_result = InferenceResult::for_body(&db, def); + let _inference_result = InferenceResult::of(&db, def); } }, &[("trait_solve_shim", 0)], @@ -670,35 +670,35 @@ fn main() { "real_span_map_shim", "crate_local_def_map", "TraitItems::query_with_diagnostics_", - "body_with_source_map_shim", + "Body::with_source_map_", "AttrFlags::query_", - "body_shim", + "Body::of_", "ImplItems::of_", "InferenceResult::for_body_", "AttrFlags::query_", - "trait_signature_with_source_map_shim", + "TraitSignature::with_source_map_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", "InferenceResult::for_body_", - "function_signature_with_source_map_shim", + "FunctionSignature::with_source_map_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "body_expr_scopes_shim", - "struct_signature_with_source_map_shim", + "ExprScopes::body_expr_scopes_", + "StructSignature::with_source_map_", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "InherentImpls::for_crate_", "callable_item_signature_query", "TraitImpls::for_crate_", - "impl_signature_with_source_map_shim", - "impl_signature_shim", + "ImplSignature::with_source_map_", + "ImplSignature::of_", "impl_trait_with_diagnostics_query", "impl_self_ty_with_diagnostics_query", "AttrFlags::query_", diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index fb598fe5ac..878696c721 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -7,7 +7,11 @@ use hir_def::{ AdtId, AssocItemId, HasModule, ImplId, Lookup, TraitId, lang_item::LangItems, nameres::DefMap, - signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags}, + signatures::{ + ConstFlags, ConstSignature, EnumFlags, EnumSignature, FnFlags, FunctionSignature, + StructFlags, StructSignature, TraitFlags, TraitSignature, TypeAliasFlags, + TypeAliasSignature, UnionSignature, + }, }; use hir_expand::name::Name; use intern::sym; @@ -279,21 +283,18 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id | TyKind::Float(_) => true, TyKind::Adt(adt_def, _) => match adt_def.def_id().0 { - hir_def::AdtId::StructId(id) => db - .struct_signature(id) + hir_def::AdtId::StructId(id) => StructSignature::of(db, id) .flags .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), - hir_def::AdtId::UnionId(id) => db - .union_signature(id) + hir_def::AdtId::UnionId(id) => UnionSignature::of(db, id) .flags .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), - hir_def::AdtId::EnumId(it) => db - .enum_signature(it) + hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it) .flags .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), }, TyKind::Dynamic(it, _) => it.principal_def_id().is_some_and(|trait_id| { - db.trait_signature(trait_id.0) + TraitSignature::of(db, trait_id.0) .flags .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) }), @@ -304,14 +305,13 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id rustc_has_incoherent_inherent_impls && !items.items.is_empty() && items.items.iter().all(|&(_, assoc)| match assoc { - AssocItemId::FunctionId(it) => { - db.function_signature(it).flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL) - } - AssocItemId::ConstId(it) => { - db.const_signature(it).flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL) - } - AssocItemId::TypeAliasId(it) => db - .type_alias_signature(it) + AssocItemId::FunctionId(it) => FunctionSignature::of(db, it) + .flags + .contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL), + AssocItemId::ConstId(it) => ConstSignature::of(db, it) + .flags + .contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL), + AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it) .flags .contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL), }) @@ -350,7 +350,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool let AdtId::StructId(s) = adt_def.def_id().0 else { break ty; }; - let struct_signature = db.struct_signature(s); + let struct_signature = StructSignature::of(db, s); if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) { let next = subs.types().next(); match next { diff --git a/crates/hir-ty/src/upvars.rs b/crates/hir-ty/src/upvars.rs index ee864ab068..d19fbbc187 100644 --- a/crates/hir-ty/src/upvars.rs +++ b/crates/hir-ty/src/upvars.rs @@ -44,10 +44,10 @@ pub fn upvars_mentioned( db: &dyn HirDatabase, owner: DefWithBodyId, ) -> Option<Box<FxHashMap<ExprId, Upvars>>> { - let body = db.body(owner); + let body = Body::of(db, owner); let mut resolver = owner.resolver(db); let mut result = FxHashMap::default(); - handle_expr_outside_closure(db, &mut resolver, owner, &body, body.body_expr, &mut result); + handle_expr_outside_closure(db, &mut resolver, owner, body, body.body_expr, &mut result); return if result.is_empty() { None } else { @@ -198,7 +198,7 @@ fn resolve_maybe_upvar<'db>( #[cfg(test)] mod tests { use expect_test::{Expect, expect}; - use hir_def::{ModuleDefId, db::DefDatabase, nameres::crate_def_map}; + use hir_def::{ModuleDefId, expr_store::Body, nameres::crate_def_map}; use itertools::Itertools; use span::Edition; use test_fixture::WithFixture; @@ -219,7 +219,7 @@ mod tests { }) .exactly_one() .unwrap_or_else(|_| panic!("expected one function")); - let (body, source_map) = db.body_with_source_map(func.into()); + let (body, source_map) = Body::with_source_map(&db, func.into()); let Some(upvars) = upvars_mentioned(&db, func.into()) else { expectation.assert_eq(""); return; diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index be64f55ea5..509109543c 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -4,6 +4,7 @@ use base_db::target::{self, TargetData}; use hir_def::{ EnumId, EnumVariantId, FunctionId, Lookup, TraitId, attrs::AttrFlags, lang_item::LangItems, + signatures::FunctionSignature, }; use intern::sym; use rustc_abi::TargetDataLayout; @@ -79,7 +80,7 @@ pub fn is_fn_unsafe_to_call( call_edition: Edition, target_feature_is_safe: TargetFeatureIsSafeInTarget, ) -> Unsafety { - let data = db.function_signature(func); + let data = FunctionSignature::of(db, func); if data.is_unsafe() { return Unsafety::Unsafe; } diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index 6f415a5289..1945b04bb3 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -13,7 +13,10 @@ //! by the next salsa version. If not, we will likely have to adapt and go with the rustc approach //! while installing firewall per item queries to prevent invalidation issues. -use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId, signatures::StructFlags}; +use hir_def::{ + AdtId, GenericDefId, GenericParamId, VariantId, + signatures::{StructFlags, StructSignature}, +}; use rustc_ast_ir::Mutability; use rustc_type_ir::{ Variance, @@ -45,7 +48,7 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance GenericDefId::FunctionId(_) => (), GenericDefId::AdtId(adt) => { if let AdtId::StructId(id) = adt { - let flags = &db.struct_signature(id).flags; + let flags = &StructSignature::of(db, id).flags; let types = || crate::next_solver::default_types(db); if flags.contains(StructFlags::IS_UNSAFE_CELL) { return types().one_invariant.store(); @@ -113,7 +116,7 @@ pub(crate) fn variances_of_cycle_initial( struct Context<'db> { db: &'db dyn HirDatabase, - generics: Generics, + generics: Generics<'db>, variances: Box<[Variance]>, } diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 91fdcb8e63..826b8d5f80 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -4,10 +4,13 @@ use either::Either; use hir_def::{ AdtId, BuiltinDeriveImplId, FunctionId, GenericDefId, ImplId, ItemContainerId, builtin_derive::BuiltinDeriveImplMethod, - expr_store::ExpressionStore, + expr_store::{Body, ExpressionStore}, hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_tree::FieldsShape, - signatures::{StaticFlags, TraitFlags}, + signatures::{ + ConstSignature, FunctionSignature, ImplSignature, StaticFlags, StaticSignature, TraitFlags, + TraitSignature, TypeAliasSignature, + }, type_ref::{TypeBound, TypeRef, TypeRefId}, }; use hir_expand::name::Name; @@ -38,7 +41,7 @@ fn write_builtin_derive_impl_method<'db>( ) -> Result { let db = f.db; let loc = impl_.loc(db); - let (adt_params, _adt_params_store) = db.generic_params_and_store(loc.adt.into()); + let (adt_params, _adt_params_store) = GenericParams::of(db, loc.adt.into()); if f.show_container_bounds() && !adt_params.is_empty() { f.write_str("impl")?; @@ -94,22 +97,22 @@ impl<'db> HirDisplay<'db> for Function { // Write container (trait or impl) let container_params = match container { ItemContainerId::TraitId(trait_) => { - let (params, params_store) = f.db.generic_params_and_store(trait_.into()); + let (params, params_store) = GenericParams::of(f.db, trait_.into()); if f.show_container_bounds() && !params.is_empty() { write_trait_header(trait_.into(), f)?; f.write_char('\n')?; - has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) + has_disaplayable_predicates(f.db, ¶ms, params_store) .then_some((params, params_store)) } else { None } } ItemContainerId::ImplId(impl_) => { - let (params, params_store) = f.db.generic_params_and_store(impl_.into()); + let (params, params_store) = GenericParams::of(f.db, impl_.into()); if f.show_container_bounds() && !params.is_empty() { write_impl_header(impl_, f)?; f.write_char('\n')?; - has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) + has_disaplayable_predicates(f.db, ¶ms, params_store) .then_some((params, params_store)) } else { None @@ -131,7 +134,7 @@ impl<'db> HirDisplay<'db> for Function { _ => unreachable!(), }; write!(f, "\n // Bounds from {container_name}:",)?; - write_where_predicates(&container_params, &container_params_store, f)?; + write_where_predicates(&container_params, container_params_store, f)?; } Ok(()) } @@ -140,7 +143,7 @@ impl<'db> HirDisplay<'db> for Function { fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Result<bool> { let db = f.db; let func = Function::from(func_id); - let data = db.function_signature(func_id); + let data = FunctionSignature::of(db, func_id); let mut module = func.module(db); // Block-local impls are "hoisted" to the nearest (non-block) module. @@ -189,7 +192,7 @@ fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Re let comma = if too_long_param { ",\n " } else { ", " }; // FIXME: Use resolved `param.ty` once we no longer discard lifetimes - let body = db.body(func_id.into()); + let body = Body::of(db, func_id.into()); for (type_ref, param) in data.params.iter().zip(func.assoc_fn_params(db)).skip(skip_self) { if !first { f.write_str(comma)?; @@ -268,7 +271,7 @@ fn write_impl_header<'db>(impl_: ImplId, f: &mut HirFormatter<'_, 'db>) -> Resul let def_id = GenericDefId::ImplId(impl_); write_generic_params(def_id, f)?; - let impl_data = db.impl_signature(impl_); + let impl_data = ImplSignature::of(db, impl_); if let Some(target_trait) = &impl_data.target_trait { f.write_char(' ')?; hir_display_with_store(&impl_data.store[target_trait.path], &impl_data.store).hir_fmt(f)?; @@ -297,7 +300,7 @@ impl<'db> HirDisplay<'db> for SelfParam { } }, }; - let data = f.db.function_signature(func); + let data = FunctionSignature::of(f.db, func); let param = *data.params.first().unwrap(); match &data.store[param] { TypeRef::Path(p) if p.is_self_type() => f.write_str("self"), @@ -657,7 +660,7 @@ fn write_generic_params_or_args<'db>( f: &mut HirFormatter<'_, 'db>, include_defaults: bool, ) -> Result { - let (params, store) = f.db.generic_params_and_store(def); + let (params, store) = GenericParams::of(f.db, def); if params.iter_lt().next().is_none() && params.iter_type_or_consts().all(|it| it.1.const_param().is_none()) && params @@ -693,17 +696,17 @@ fn write_generic_params_or_args<'db>( write!(f, "{}", name.display(f.db, f.edition()))?; if include_defaults && let Some(default) = &ty.default { f.write_str(" = ")?; - default.hir_fmt(f, &store)?; + default.hir_fmt(f, store)?; } } TypeOrConstParamData::ConstParamData(c) => { delim(f)?; write!(f, "const {}: ", name.display(f.db, f.edition()))?; - c.ty.hir_fmt(f, &store)?; + c.ty.hir_fmt(f, store)?; if include_defaults && let Some(default) = &c.default { f.write_str(" = ")?; - default.hir_fmt(f, &store)?; + default.hir_fmt(f, store)?; } } } @@ -715,13 +718,13 @@ fn write_generic_params_or_args<'db>( } fn write_where_clause<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result<bool> { - let (params, store) = f.db.generic_params_and_store(def); - if !has_disaplayable_predicates(f.db, ¶ms, &store) { + let (params, store) = GenericParams::of(f.db, def); + if !has_disaplayable_predicates(f.db, ¶ms, store) { return Ok(false); } f.write_str("\nwhere")?; - write_where_predicates(¶ms, &store, f)?; + write_where_predicates(¶ms, store, f)?; Ok(true) } @@ -816,7 +819,7 @@ impl<'db> HirDisplay<'db> for Const { module = module.nearest_non_block_module(db); } write_visibility(module.id, self.visibility(db), f)?; - let data = db.const_signature(self.id); + let data = ConstSignature::of(db, self.id); f.write_str("const ")?; match &data.name { Some(name) => write!(f, "{}: ", name.display(f.db, f.edition()))?, @@ -830,7 +833,7 @@ impl<'db> HirDisplay<'db> for Const { impl<'db> HirDisplay<'db> for Static { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; - let data = f.db.static_signature(self.id); + let data = StaticSignature::of(f.db, self.id); f.write_str("static ")?; if data.flags.contains(StaticFlags::MUTABLE) { f.write_str("mut ")?; @@ -889,7 +892,7 @@ impl<'db> HirDisplay<'db> for Trait { fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?; - let data = f.db.trait_signature(trait_.id); + let data = TraitSignature::of(f.db, trait_.id); if data.flags.contains(TraitFlags::UNSAFE) { f.write_str("unsafe ")?; } @@ -904,7 +907,7 @@ fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Resu impl<'db> HirDisplay<'db> for TypeAlias { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; - let data = f.db.type_alias_signature(self.id); + let data = TypeAliasSignature::of(f.db, self.id); write!(f, "type {}", data.name.display(f.db, f.edition()))?; let def_id = GenericDefId::TypeAliasId(self.id); write_generic_params(def_id, f)?; diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index fc20f4b46b..1aeed874af 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -4,8 +4,8 @@ //! are splitting the hir. use hir_def::{ - AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, - GenericParamId, ModuleDefId, VariantId, + AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, + FieldId, GenericDefId, GenericParamId, ModuleDefId, VariantId, hir::{BindingId, LabelId}, }; use hir_ty::next_solver::AnyImplId; @@ -255,14 +255,19 @@ impl TryFrom<AssocItem> for GenericDefId { } } +impl From<(ExpressionStoreOwnerId, BindingId)> for Local { + fn from((parent, binding_id): (ExpressionStoreOwnerId, BindingId)) -> Self { + Local { parent, binding_id } + } +} impl From<(DefWithBodyId, BindingId)> for Local { fn from((parent, binding_id): (DefWithBodyId, BindingId)) -> Self { - Local { parent, binding_id } + Local { parent: parent.into(), binding_id } } } -impl From<(DefWithBodyId, LabelId)> for Label { - fn from((parent, label_id): (DefWithBodyId, LabelId)) -> Self { +impl From<(ExpressionStoreOwnerId, LabelId)> for Label { + fn from((parent, label_id): (ExpressionStoreOwnerId, LabelId)) -> Self { Label { parent, label_id } } } diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 6a1aeb64f3..752c4f3173 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -3,6 +3,7 @@ use either::Either; use hir_def::{ CallableDefId, Lookup, MacroId, VariantId, + expr_store::ExpressionStore, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource as _}, }; @@ -293,8 +294,7 @@ impl HasSource for Param<'_> { } Callee::Closure(closure, _) => { let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure); - let body_owner = owner.as_def_with_body()?; - let (_, source_map) = db.body_with_source_map(body_owner); + let (_, source_map) = ExpressionStore::with_source_map(db, owner); let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?; let root = db.parse_or_expand(file_id); match value.to_node(&root) { @@ -328,8 +328,7 @@ impl HasSource for Label { type Ast = ast::Label; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { - let (_body, source_map) = db.body_with_source_map(self.parent); - let src = source_map.label_syntax(self.label_id); + let src = ExpressionStore::with_source_map(db, self.parent).1.label_syntax(self.label_id); let root = src.file_syntax(db); src.map(|ast| ast.to_node(&root).left()).transpose() } @@ -346,7 +345,7 @@ impl HasSource for ExternCrateDecl { impl HasSource for InlineAsmOperand { type Ast = ast::AsmOperandNamed; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { - let source_map = db.body_with_source_map(self.owner).1; + let (_, source_map) = ExpressionStore::with_source_map(db, self.owner); if let Ok(src) = source_map.expr_syntax(self.expr) { let root = src.file_syntax(db); return src 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> { diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index a231f4aff5..f1aabb5933 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -13,7 +13,8 @@ use std::{ use base_db::FxIndexSet; use either::Either; use hir_def::{ - BuiltinDeriveImplId, DefWithBodyId, HasModule, MacroId, StructId, TraitId, VariantId, + BuiltinDeriveImplId, DefWithBodyId, ExpressionStoreOwnerId, HasModule, MacroId, StructId, + TraitId, VariantId, attrs::parse_extra_crate_attrs, expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, @@ -54,10 +55,10 @@ use syntax::{ use crate::{ Adjust, Adjustment, Adt, AnyFunctionId, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, - ConstParam, Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, - HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, - Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, Trait, - TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + ConstParam, Crate, DefWithBody, DeriveHelper, Enum, ExpressionStoreOwner, Field, Function, + GenericSubstitution, HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, + Local, Macro, Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, + Trait, TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{SourceAnalyzer, resolve_hir_path}, @@ -785,16 +786,20 @@ impl<'db> SemanticsImpl<'db> { /// Checks if renaming `renamed` to `new_name` may introduce conflicts with other locals, /// and returns the conflicting locals. pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &Name) -> Vec<Local> { - let body = self.db.body(to_be_renamed.parent); + // FIXME: signatures + let Some(def) = to_be_renamed.parent.as_def_with_body() else { + return Vec::new(); + }; + let body = Body::of(self.db, def); let resolver = to_be_renamed.parent.resolver(self.db); let starting_expr = body.binding_owner(to_be_renamed.binding_id).unwrap_or(body.body_expr); let mut visitor = RenameConflictsVisitor { - body: &body, + body, conflicts: FxHashSet::default(), db: self.db, new_name: new_name.symbol().clone(), old_name: to_be_renamed.name(self.db).symbol().clone(), - owner: to_be_renamed.parent, + owner: def, to_be_renamed: to_be_renamed.binding_id, resolver, }; @@ -1917,10 +1922,10 @@ impl<'db> SemanticsImpl<'db> { let Ok(def) = DefWithBodyId::try_from(def) else { return FxHashSet::default(); }; - let (body, source_map) = self.db.body_with_source_map(def); - let infer = InferenceResult::for_body(self.db, def); + let (body, source_map) = Body::with_source_map(self.db, def); + let infer = InferenceResult::of(self.db, def); let mut res = FxHashSet::default(); - unsafe_operations_for_body(self.db, infer, def, &body, &mut |node| { + unsafe_operations_for_body(self.db, infer, def, body, &mut |node| { if let Ok(node) = source_map.expr_or_pat_syntax(node) { res.insert(node); } @@ -1935,13 +1940,13 @@ impl<'db> SemanticsImpl<'db> { let Ok(def) = def.try_into() else { return Vec::new(); }; - let (body, source_map) = self.db.body_with_source_map(def); - let infer = InferenceResult::for_body(self.db, def); + let (body, source_map) = Body::with_source_map(self.db, def); + let infer = InferenceResult::of(self.db, def); let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else { return Vec::new(); }; let mut res = Vec::default(); - unsafe_operations(self.db, infer, def, &body, block, &mut |node, _| { + unsafe_operations(self.db, infer, def, body, block, &mut |node, _| { if let Ok(node) = source_map.expr_or_pat_syntax(node) { res.push(node); } @@ -2275,7 +2280,7 @@ impl<'db> SemanticsImpl<'db> { let Some(def) = def else { return false }; let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax()); - let (body, source_map) = self.db.body_with_source_map(def); + let (body, source_map) = Body::with_source_map(self.db, def); let file_id = self.find_file(expr.syntax()).file_id; @@ -2326,7 +2331,7 @@ impl<'db> SemanticsImpl<'db> { let sa = self.analyze(element.either(|e| e.syntax(), |s| s.syntax()))?; let store = sa.store()?; let mut resolver = sa.resolver.clone(); - let def = resolver.body_owner()?; + let def = resolver.expression_store_owner()?; let is_not_generated = |path: &Path| { !path.mod_path().and_then(|path| path.as_ident()).is_some_and(Name::is_generated) @@ -2576,13 +2581,18 @@ impl<'db> SemanticsScope<'db> { Crate { id: self.resolver.krate() } } + // FIXME: This is a weird function, we shouldn't have this? pub fn containing_function(&self) -> Option<Function> { - self.resolver.body_owner().and_then(|owner| match owner { - DefWithBodyId::FunctionId(id) => Some(id.into()), + self.resolver.expression_store_owner().and_then(|owner| match owner { + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => Some(id.into()), _ => None, }) } + pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwner> { + self.resolver.expression_store_owner().map(Into::into) + } + pub(crate) fn resolver(&self) -> &Resolver<'db> { &self.resolver } @@ -2604,14 +2614,18 @@ impl<'db> SemanticsScope<'db> { resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()), - resolver::ScopeDef::Local(binding_id) => match self.resolver.body_owner() { - Some(parent) => ScopeDef::Local(Local { parent, binding_id }), - None => continue, - }, - resolver::ScopeDef::Label(label_id) => match self.resolver.body_owner() { - Some(parent) => ScopeDef::Label(Label { parent, label_id }), - None => continue, - }, + resolver::ScopeDef::Local(binding_id) => { + match self.resolver.expression_store_owner() { + Some(parent) => ScopeDef::Local(Local { parent, binding_id }), + None => continue, + } + } + resolver::ScopeDef::Label(label_id) => { + match self.resolver.expression_store_owner() { + Some(parent) => ScopeDef::Label(Label { parent, label_id }), + None => continue, + } + } }; f(name.clone(), def) } diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index 143cc14c33..f6d1bec575 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -18,8 +18,10 @@ use hir_def::{ DynMap, keys::{self, Key}, }, + expr_store::Body, hir::generics::GenericParams, item_scope::ItemScope, + signatures::{EnumSignature, ImplSignature, TraitSignature}, src::{HasChildSource, HasSource}, }; @@ -49,7 +51,7 @@ impl ChildBySource for TraitId { data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); - let (_, source_map) = db.trait_signature_with_source_map(*self); + let (_, source_map) = TraitSignature::with_source_map(db, *self); source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( |(ast, &exp_id)| { res[keys::MACRO_CALL].insert(ast.value, exp_id); @@ -74,7 +76,7 @@ impl ChildBySource for ImplId { data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); - let (_, source_map) = db.impl_signature_with_source_map(*self); + let (_, source_map) = ImplSignature::with_source_map(db, *self); source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( |(ast, &exp_id)| { res[keys::MACRO_CALL].insert(ast.value, exp_id); @@ -204,7 +206,7 @@ impl ChildBySource for EnumId { self.enum_variants(db).variants.iter().for_each(|&(variant, _, _)| { res[keys::ENUM_VARIANT].insert(ast_id_map.get(variant.lookup(db).id.value), variant); }); - let (_, source_map) = db.enum_signature_with_source_map(*self); + let (_, source_map) = EnumSignature::with_source_map(db, *self); source_map .expansions() .filter(|(ast, _)| ast.file_id == file_id) @@ -214,7 +216,7 @@ impl ChildBySource for EnumId { impl ChildBySource for DefWithBodyId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let (body, sm) = db.body_with_source_map(*self); + let (body, sm) = Body::with_source_map(db, *self); if let &DefWithBodyId::VariantId(v) = self { VariantId::EnumVariantId(v).child_by_source_to(db, res, file_id) } @@ -239,8 +241,7 @@ impl ChildBySource for GenericDefId { return; } - let (generic_params, _, source_map) = - GenericParams::generic_params_and_store_and_source_map(db, *self); + let (generic_params, _, source_map) = GenericParams::with_source_map(db, *self); let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx); let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx); diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index d222c3dc7e..8c398728b0 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -88,13 +88,14 @@ use either::Either; use hir_def::{ AdtId, BlockId, BuiltinDeriveImplId, ConstId, ConstParamId, DefWithBodyId, EnumId, - EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, - ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeParamId, UnionId, UseId, VariantId, + EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FieldId, FunctionId, + GenericDefId, GenericParamId, ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, + StructId, TraitId, TypeAliasId, TypeParamId, UnionId, UseId, VariantId, dyn_map::{ DynMap, keys::{self, Key}, }, + expr_store::{Body, ExpressionStore}, hir::{BindingId, Expr, LabelId}, nameres::{block_def_map, crate_def_map}, }; @@ -334,8 +335,8 @@ impl SourceToDefCtx<'_, '_> { _ => None, }) .position(|it| it == *src.value)?; - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let source_map = self.db.body_with_source_map(container).1; + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (_, source_map) = ExpressionStore::with_source_map(self.db, container); let expr = source_map.node_expr(src.with_value(&ast::Expr::AsmExpr(asm)))?.as_expr()?; Some(InlineAsmOperand { owner: container, expr, index }) } @@ -343,13 +344,13 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn bind_pat_to_def( &mut self, src: InFile<&ast::IdentPat>, - ) -> Option<(DefWithBodyId, BindingId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (body, source_map) = self.db.body_with_source_map(container); + ) -> Option<(ExpressionStoreOwnerId, BindingId)> { + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (store, source_map) = ExpressionStore::with_source_map(self.db, container); let src = src.cloned().map(ast::Pat::from); let pat_id = source_map.node_pat(src.as_ref())?; // the pattern could resolve to a constant, verify that this is not the case - if let crate::Pat::Bind { id, .. } = body[pat_id.as_pat()?] { + if let crate::Pat::Bind { id, .. } = store[pat_id.as_pat()?] { Some((container, id)) } else { None @@ -359,17 +360,19 @@ impl SourceToDefCtx<'_, '_> { &mut self, src: InFile<&ast::SelfParam>, ) -> Option<(DefWithBodyId, BindingId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let body = self.db.body(container); + let container = self + .find_container(src.syntax_ref())? + .as_expression_store_owner()? + .as_def_with_body()?; + let body = Body::of(self.db, container); Some((container, body.self_param?)) } pub(super) fn label_to_def( &mut self, src: InFile<&ast::Label>, - ) -> Option<(DefWithBodyId, LabelId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let source_map = self.db.body_with_source_map(container).1; - + ) -> Option<(ExpressionStoreOwnerId, LabelId)> { + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (_, source_map) = ExpressionStore::with_source_map(self.db, container); let label_id = source_map.node_label(src)?; Some((container, label_id)) } @@ -377,13 +380,14 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn label_ref_to_def( &mut self, src: InFile<&ast::Lifetime>, - ) -> Option<(DefWithBodyId, LabelId)> { + ) -> Option<(ExpressionStoreOwnerId, LabelId)> { let break_or_continue = ast::Expr::cast(src.value.syntax().parent()?)?; - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (body, source_map) = self.db.body_with_source_map(container); + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (store, source_map) = ExpressionStore::with_source_map(self.db, container); let break_or_continue = source_map.node_expr(src.with_value(&break_or_continue))?.as_expr()?; - let (Expr::Break { label, .. } | Expr::Continue { label }) = body[break_or_continue] else { + let (Expr::Break { label, .. } | Expr::Continue { label }) = store[break_or_continue] + else { return None; }; Some((container, label?)) @@ -557,29 +561,6 @@ impl SourceToDefCtx<'_, '_> { }) } - // FIXME: Remove this when we do inference in signatures - fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> { - self.parent_ancestors_with_macros(src, |this, InFile { file_id, value }, _| { - let item = match ast::Item::cast(value.clone()) { - Some(it) => it, - None => { - let variant = ast::Variant::cast(value)?; - return this - .enum_variant_to_def(InFile::new(file_id, &variant)) - .map(Into::into); - } - }; - match &item { - ast::Item::Fn(it) => this.fn_to_def(InFile::new(file_id, it)).map(Into::into), - ast::Item::Const(it) => this.const_to_def(InFile::new(file_id, it)).map(Into::into), - ast::Item::Static(it) => { - this.static_to_def(InFile::new(file_id, it)).map(Into::into) - } - _ => None, - } - }) - } - /// Skips the attributed item that caused the macro invocation we are climbing up fn parent_ancestors_with_macros<T>( &mut self, @@ -756,4 +737,22 @@ impl ChildContainer { ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id), } } + + fn as_expression_store_owner(self) -> Option<ExpressionStoreOwnerId> { + match self { + ChildContainer::DefWithBodyId(it) => Some(it.into()), + ChildContainer::ModuleId(_) => None, + ChildContainer::TraitId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::TraitId(it))) + } + ChildContainer::EnumId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::AdtId(it.into()))) + } + ChildContainer::ImplId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::ImplId(it))) + } + ChildContainer::VariantId(_) => None, + ChildContainer::GenericDefId(it) => Some(it.into()), + } + } } diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 1d3cfc748e..bd77347e93 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -9,8 +9,8 @@ use std::iter::{self, once}; use either::Either; use hir_def::{ - AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, - LocalFieldId, ModuleDefId, StructId, TraitId, VariantId, + AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, + FunctionId, GenericDefId, LocalFieldId, ModuleDefId, StructId, TraitId, VariantId, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId, lower::ExprCollector, @@ -78,20 +78,20 @@ pub(crate) struct SourceAnalyzer<'db> { pub(crate) enum BodyOrSig<'db> { Body { def: DefWithBodyId, - body: Arc<Body>, - source_map: Arc<BodySourceMap>, + body: &'db Body, + source_map: &'db BodySourceMap, infer: Option<&'db InferenceResult>, }, // To be folded into body once it is considered one VariantFields { def: VariantId, - store: Arc<ExpressionStore>, - source_map: Arc<ExpressionStoreSourceMap>, + store: &'db ExpressionStore, + source_map: &'db ExpressionStoreSourceMap, }, Sig { def: GenericDefId, - store: Arc<ExpressionStore>, - source_map: Arc<ExpressionStoreSourceMap>, + store: &'db ExpressionStore, + source_map: &'db ExpressionStoreSourceMap, infer: Option<&'db InferenceResult>, #[expect(dead_code)] generics: Arc<GenericParams>, @@ -105,7 +105,7 @@ impl<'db> SourceAnalyzer<'db> { node: InFile<&SyntaxNode>, offset: Option<TextSize>, ) -> SourceAnalyzer<'db> { - Self::new_for_body_(db, def, node, offset, Some(InferenceResult::for_body(db, def))) + Self::new_for_body_(db, def, node, offset, Some(InferenceResult::of(db, def))) } pub(crate) fn new_for_body_no_infer( @@ -124,10 +124,10 @@ impl<'db> SourceAnalyzer<'db> { offset: Option<TextSize>, infer: Option<&'db InferenceResult>, ) -> SourceAnalyzer<'db> { - let (body, source_map) = db.body_with_source_map(def); - let scopes = db.expr_scopes(def.into()); + let (body, source_map) = Body::with_source_map(db, def); + let scopes = ExprScopes::of(db, def); let scope = match offset { - None => scope_for(db, &scopes, &source_map, node), + None => scope_for(db, scopes, source_map, node), Some(offset) => { debug_assert!( node.text_range().contains_inclusive(offset), @@ -135,7 +135,7 @@ impl<'db> SourceAnalyzer<'db> { offset, node.text_range() ); - scope_for_offset(db, &scopes, &source_map, node.file_id, offset) + scope_for_offset(db, scopes, source_map, node.file_id, offset) } }; let resolver = resolver_for_scope(db, def, scope); @@ -171,10 +171,10 @@ impl<'db> SourceAnalyzer<'db> { offset: Option<TextSize>, infer: bool, ) -> SourceAnalyzer<'db> { - let (generics, store, source_map) = db.generic_params_and_store_and_source_map(def); - let scopes = db.expr_scopes(def.into()); + let (generics, store, source_map) = GenericParams::with_source_map(db, def); + let scopes = ExprScopes::of(db, def); let scope = match offset { - None => scope_for(db, &scopes, &source_map, node), + None => scope_for(db, scopes, source_map, node), Some(offset) => { debug_assert!( node.text_range().contains_inclusive(offset), @@ -182,15 +182,11 @@ impl<'db> SourceAnalyzer<'db> { offset, node.text_range() ); - scope_for_offset(db, &scopes, &source_map, node.file_id, offset) + scope_for_offset(db, scopes, source_map, node.file_id, offset) } }; let resolver = resolver_for_scope(db, def, scope); - let infer = if infer && !Arc::ptr_eq(&store, &ExpressionStore::empty_singleton().0) { - Some(InferenceResult::for_signature(db, def)) - } else { - None - }; + let infer = if infer { Some(InferenceResult::of(db, def)) } else { None }; SourceAnalyzer { resolver, body_or_sig: Some(BodyOrSig::Sig { def, store, source_map, generics, infer }), @@ -208,11 +204,7 @@ impl<'db> SourceAnalyzer<'db> { let resolver = def.resolver(db); SourceAnalyzer { resolver, - body_or_sig: Some(BodyOrSig::VariantFields { - def, - store: fields.store.clone(), - source_map: source_map.clone(), - }), + body_or_sig: Some(BodyOrSig::VariantFields { def, store: &fields.store, source_map }), file_id, } } @@ -241,6 +233,18 @@ impl<'db> SourceAnalyzer<'db> { }) } + pub(crate) fn def( + &self, + ) -> Option<(ExpressionStoreOwnerId, &ExpressionStore, &ExpressionStoreSourceMap)> { + self.body_or_sig.as_ref().and_then(|it| match it { + BodyOrSig::VariantFields { .. } => None, + &BodyOrSig::Sig { def, store, source_map, .. } => Some((def.into(), store, source_map)), + BodyOrSig::Body { def, body, source_map, .. } => { + Some(((*def).into(), &body.store, source_map)) + } + }) + } + pub(crate) fn store(&self) -> Option<&ExpressionStore> { self.body_or_sig.as_ref().map(|it| match it { BodyOrSig::Sig { store, .. } => &**store, @@ -264,9 +268,9 @@ impl<'db> SourceAnalyzer<'db> { fn trait_environment(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> { self.param_and(self.body_or_sig.as_ref().map_or_else(ParamEnv::empty, |body_or_sig| { match *body_or_sig { - BodyOrSig::Body { def, .. } => db.trait_environment_for_body(def), + BodyOrSig::Body { def, .. } => db.trait_environment(def.into()), BodyOrSig::VariantFields { .. } => ParamEnv::empty(), - BodyOrSig::Sig { def, .. } => db.trait_environment(def), + BodyOrSig::Sig { def, .. } => db.trait_environment(def.into()), } })) } @@ -806,7 +810,7 @@ impl<'db> SourceAnalyzer<'db> { name_hygiene(db, InFile::new(self.file_id, ast_name.syntax())), ) { Some(ValueNs::LocalBinding(binding_id)) => { - Some(Local { binding_id, parent: self.resolver.body_owner()? }) + Some(Local { binding_id, parent: self.resolver.expression_store_owner()? }) } _ => None, } @@ -866,8 +870,8 @@ impl<'db> SourceAnalyzer<'db> { }, }; - let body_owner = self.resolver.body_owner(); - let res = resolve_hir_value_path(db, &self.resolver, body_owner, path, HygieneId::ROOT)?; + let store_owner = self.resolver.expression_store_owner(); + let res = resolve_hir_value_path(db, &self.resolver, store_owner, path, HygieneId::ROOT)?; match res { PathResolution::Def(def) => Some(def), _ => None, @@ -1435,7 +1439,7 @@ impl<'db> SourceAnalyzer<'db> { resolve_hir_value_path( db, &self.resolver, - self.resolver.body_owner(), + self.resolver.expression_store_owner(), &Path::from_known_path_with_no_generic(ModPath::from_segments( PathKind::Plain, Some(name.clone()), @@ -1451,9 +1455,9 @@ impl<'db> SourceAnalyzer<'db> { asm: InFile<&ast::AsmExpr>, line: usize, offset: TextSize, - ) -> Option<(DefWithBodyId, (ExprId, TextRange, usize))> { - let (def, _, body_source_map, _) = self.body_()?; - let (expr, args) = body_source_map.asm_template_args(asm)?; + ) -> Option<(ExpressionStoreOwnerId, (ExprId, TextRange, usize))> { + let (def, _, sm) = self.def()?; + let (expr, args) = sm.asm_template_args(asm)?; Some(def).zip( args.get(line)? .iter() @@ -1474,7 +1478,7 @@ impl<'db> SourceAnalyzer<'db> { resolve_hir_value_path( db, &self.resolver, - self.resolver.body_owner(), + self.resolver.expression_store_owner(), &Path::from_known_path_with_no_generic(ModPath::from_segments( PathKind::Plain, Some(name.clone()), @@ -1488,9 +1492,9 @@ impl<'db> SourceAnalyzer<'db> { pub(crate) fn as_asm_parts( &self, asm: InFile<&ast::AsmExpr>, - ) -> Option<(DefWithBodyId, (ExprId, &[Vec<(TextRange, usize)>]))> { - let (def, _, body_source_map, _) = self.body_()?; - Some(def).zip(body_source_map.asm_template_args(asm)) + ) -> Option<(ExpressionStoreOwnerId, (ExprId, &[Vec<(TextRange, usize)>]))> { + let (def, _, sm) = self.def()?; + Some(def).zip(sm.asm_template_args(asm)) } fn resolve_impl_method_or_trait_def( @@ -1508,11 +1512,11 @@ impl<'db> SourceAnalyzer<'db> { func: FunctionId, substs: GenericArgs<'db>, ) -> (Function, GenericArgs<'db>) { - let owner = match self.resolver.body_owner() { + let owner = match self.resolver.expression_store_owner() { Some(it) => it, None => return (func.into(), substs), }; - let env = self.param_and(db.trait_environment_for_body(owner)); + let env = self.param_and(db.trait_environment(owner)); let (func, args) = db.lookup_impl_method(env, func, substs); match func { Either::Left(func) => (func.into(), args), @@ -1528,11 +1532,11 @@ impl<'db> SourceAnalyzer<'db> { const_id: ConstId, subs: GenericArgs<'db>, ) -> (ConstId, GenericArgs<'db>) { - let owner = match self.resolver.body_owner() { + let owner = match self.resolver.expression_store_owner() { Some(it) => it, None => return (const_id, subs), }; - let env = self.param_and(db.trait_environment_for_body(owner)); + let env = self.param_and(db.trait_environment(owner)); let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); method_resolution::lookup_impl_const(&infcx, env.param_env, const_id, subs) @@ -1743,7 +1747,7 @@ fn resolve_hir_path_( } }; - let body_owner = resolver.body_owner(); + let body_owner = resolver.expression_store_owner(); let values = || resolve_hir_value_path(db, resolver, body_owner, path, hygiene); let items = || { @@ -1789,14 +1793,14 @@ fn resolve_hir_path_( fn resolve_hir_value_path( db: &dyn HirDatabase, resolver: &Resolver<'_>, - body_owner: Option<DefWithBodyId>, + store_owner: Option<ExpressionStoreOwnerId>, path: &Path, hygiene: HygieneId, ) -> Option<PathResolution> { resolver.resolve_path_in_value_ns_fully(db, path, hygiene).and_then(|val| { let res = match val { ValueNs::LocalBinding(binding_id) => { - let var = Local { parent: body_owner?, binding_id }; + let var = Local { parent: store_owner?, binding_id }; PathResolution::Local(var) } ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index c088f3aa0c..ff56544d82 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -8,9 +8,11 @@ use hir_def::{ AdtId, AssocItemId, AstIdLoc, Complete, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, db::DefDatabase, + expr_store::Body, item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob}, nameres::crate_def_map, per_ns::Item, + signatures::{EnumSignature, ImplSignature, TraitSignature}, src::{HasChildSource, HasSource}, visibility::{Visibility, VisibilityExplicitness}, }; @@ -185,7 +187,7 @@ impl<'a> SymbolCollector<'a> { } ModuleDefId::AdtId(AdtId::EnumId(id)) => { this.push_decl(id, name, false, None); - let enum_name = Symbol::intern(this.db.enum_signature(id).name.as_str()); + let enum_name = Symbol::intern(EnumSignature::of(this.db, id).name.as_str()); this.with_container_name(Some(enum_name), |this| { let variants = id.enum_variants(this.db); for (variant_id, variant_name, _) in &variants.variants { @@ -386,7 +388,7 @@ impl<'a> SymbolCollector<'a> { return; } let body_id = body_id.into(); - let body = self.db.body(body_id); + let body = Body::of(self.db, body_id); // Descend into the blocks and enqueue collection of all modules within. for (_, def_map) in body.blocks(self.db) { @@ -397,7 +399,7 @@ impl<'a> SymbolCollector<'a> { } fn collect_from_impl(&mut self, impl_id: ImplId) { - let impl_data = self.db.impl_signature(impl_id); + let impl_data = ImplSignature::of(self.db, impl_id); let impl_name = Some( hir_display_with_store(impl_data.self_ty, &impl_data.store) .display( @@ -419,7 +421,7 @@ impl<'a> SymbolCollector<'a> { } fn collect_from_trait(&mut self, trait_id: TraitId, trait_do_not_complete: Complete) { - let trait_data = self.db.trait_signature(trait_id); + let trait_data = TraitSignature::of(self.db, trait_id); self.with_container_name(Some(Symbol::intern(trait_data.name.as_str())), |s| { for &(ref name, assoc_item_id) in &trait_id.trait_items(self.db).items { s.push_assoc_item(assoc_item_id, name, Some(trait_do_not_complete)); diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index 8622aa1378..c7ef4e5d5d 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -53,7 +53,7 @@ pub(super) fn trivial<'a, 'lt, 'db, DB: HirDatabase>( ScopeDef::GenericParam(GenericParam::ConstParam(it)) => Some(Expr::ConstParam(*it)), ScopeDef::Local(it) => { if ctx.config.enable_borrowcheck { - let borrowck = db.borrowck(it.parent).ok()?; + let borrowck = db.borrowck(it.parent.as_def_with_body()?).ok()?; let invalid = borrowck.iter().any(|b| { b.partially_moved.iter().any(|moved| { diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 1749db1e61..3c3f71aea6 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -80,9 +80,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let module = scope.module(); let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(scope.krate())); let self_ty = if ctx.config.prefer_self_ty { - scope - .containing_function() - .and_then(|function| function.as_assoc_item(ctx.db())?.implementing_ty(ctx.db())) + scope.expression_store_owner().and_then(|def| { + match def { + hir::ExpressionStoreOwner::Body(def_with_body) => { + def_with_body.as_assoc_item(ctx.db()) + } + hir::ExpressionStoreOwner::Signature(def) => def.as_assoc_item(ctx.db()), + }? + .implementing_ty(ctx.db()) + }) } else { None }; diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 788f9b73fa..6ee4c97c87 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -14,11 +14,12 @@ use arrayvec::ArrayVec; use either::Either; use hir::{ Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType, - Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExternAssocItem, - ExternCrateDecl, Field, Function, GenericDef, GenericParam, GenericSubstitution, HasContainer, - HasVisibility, HirDisplay, Impl, InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, - ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, - TupleField, TypeAlias, Variant, VariantDef, Visibility, + Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExpressionStoreOwner, + ExternAssocItem, ExternCrateDecl, Field, Function, GenericDef, GenericParam, + GenericSubstitution, HasContainer, HasVisibility, HirDisplay, Impl, InlineAsmOperand, + ItemContainer, Label, Local, Macro, Module, ModuleDef, Name, PathResolution, Semantics, Static, + StaticLifetime, Struct, ToolModule, Trait, TupleField, TypeAlias, Variant, VariantDef, + Visibility, }; use span::Edition; use stdx::{format_to, impl_from}; @@ -1020,6 +1021,16 @@ impl From<GenericDef> for Definition { } } +impl TryFrom<ExpressionStoreOwner> for Definition { + type Error = (); + fn try_from(def: ExpressionStoreOwner) -> Result<Self, Self::Error> { + match def { + ExpressionStoreOwner::Body(def_with_body) => def_with_body.try_into(), + ExpressionStoreOwner::Signature(generic_def) => Ok(generic_def.into()), + } + } +} + impl TryFrom<Definition> for GenericDef { type Error = (); fn try_from(def: Definition) -> Result<Self, Self::Error> { diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index 3822eaae2c..2cf4627ac8 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -10,9 +10,9 @@ use std::{cell::LazyCell, cmp::Reverse}; use base_db::{RootQueryDb, SourceDatabase}; use either::Either; use hir::{ - Adt, AsAssocItem, DefWithBody, EditionedFileId, FileRange, FileRangeWrapper, HasAttrs, - HasContainer, HasSource, InFile, InFileWrapper, InRealFile, InlineAsmOperand, ItemContainer, - ModuleSource, PathResolution, Semantics, Visibility, + Adt, AsAssocItem, DefWithBody, EditionedFileId, ExpressionStoreOwner, FileRange, + FileRangeWrapper, HasAttrs, HasContainer, HasSource, InFile, InFileWrapper, InRealFile, + InlineAsmOperand, ItemContainer, ModuleSource, PathResolution, Semantics, Visibility, }; use memchr::memmem::Finder; use parser::SyntaxKind; @@ -310,10 +310,23 @@ impl Definition { if let Definition::Local(var) = self { let def = match var.parent(db) { - DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + ExpressionStoreOwner::Body(def) => match def { + DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::Signature(def) => match def { + hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Adt(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Trait(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::TypeAlias(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } + hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), + }, }; return match def { Some(def) => SearchScope::file_range( @@ -325,10 +338,23 @@ impl Definition { if let Definition::InlineAsmOperand(op) = self { let def = match op.parent(db) { - DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + ExpressionStoreOwner::Body(def) => match def { + DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::Signature(def) => match def { + hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Adt(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Trait(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::TypeAlias(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } + hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), + }, }; return match def { Some(def) => SearchScope::file_range( diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs index e5e4c899ec..3af529e8c5 100644 --- a/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/crates/ide/src/inlay_hints/implicit_drop.rs @@ -7,7 +7,7 @@ //! ``` use hir::{ DefWithBody, - db::{DefDatabase as _, HirDatabase as _}, + db::HirDatabase as _, mir::{MirSpan, TerminatorKind}, }; use ide_db::{FileRange, famous_defs::FamousDefs}; @@ -35,7 +35,7 @@ pub(super) fn hints( let def: DefWithBody = def.into(); let def = def.try_into().ok()?; - let (hir, source_map) = sema.db.body_with_source_map(def); + let (hir, source_map) = hir::Body::with_source_map(sema.db, def); let mir = sema.db.mir_body(def).ok()?; diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index ae19e77509..900a885a64 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -480,7 +480,7 @@ fn rename_to_self( } let fn_def = match local.parent(sema.db) { - hir::DefWithBody::Function(func) => func, + hir::ExpressionStoreOwner::Body(hir::DefWithBody::Function(func)) => func, _ => bail!("Cannot rename local to self outside of function"), }; @@ -743,7 +743,7 @@ fn rename_self_to_param( } let fn_def = match local.parent(sema.db) { - hir::DefWithBody::Function(func) => func, + hir::ExpressionStoreOwner::Body(hir::DefWithBody::Function(func)) => func, _ => bail!("Cannot rename local to self outside of function"), }; diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 3ee3797654..43e73175c8 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -16,8 +16,8 @@ use hir::{ next_solver::{DbInterner, GenericArgs}, }; use hir_def::{ - SyntheticSyntax, - expr_store::BodySourceMap, + DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, + expr_store::{Body, BodySourceMap, ExpressionStore}, hir::{ExprId, PatId}, }; use hir_ty::InferenceResult; @@ -406,7 +406,7 @@ impl flags::AnalysisStats { hir_def::AdtId::from(a), GenericArgs::empty(interner).store(), hir_ty::ParamEnvAndCrate { - param_env: db.trait_environment(a.into()), + param_env: db.trait_environment(GenericDefId::from(a).into()), krate: a.krate(db).into(), } .store(), @@ -778,21 +778,24 @@ impl flags::AnalysisStats { if self.parallel { let mut inference_sw = self.stop_watch(); - let bodies = bodies.iter().filter_map(|&body| body.try_into().ok()).collect::<Vec<_>>(); + let bodies = bodies + .iter() + .filter_map(|&body| body.try_into().ok()) + .collect::<Vec<DefWithBodyId>>(); bodies .par_iter() .map_with(db.clone(), |snap, &body| { - InferenceResult::for_body(snap, body); + InferenceResult::of(snap, body); }) .count(); let signatures = signatures .iter() .filter_map(|&signatures| signatures.try_into().ok()) - .collect::<Vec<_>>(); + .collect::<Vec<GenericDefId>>(); signatures .par_iter() .map_with(db.clone(), |snap, &signatures| { - InferenceResult::for_signature(snap, signatures); + InferenceResult::of(snap, signatures); }) .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); @@ -849,9 +852,9 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - let body = db.body(body_def_id); + let body = Body::of(db, body_def_id); let inference_result = - catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_def_id))); + catch_unwind(AssertUnwindSafe(|| InferenceResult::of(db, body_def_id))); let inference_result = match inference_result { Ok(inference_result) => inference_result, Err(p) => { @@ -879,7 +882,7 @@ impl flags::AnalysisStats { } }; // This query is LRU'd, so actually calling it will skew the timing results. - let sm = || db.body_with_source_map(body_def_id).1; + let sm = || &Body::with_source_map(db, body_def_id).1; // region:expressions let (previous_exprs, previous_unknown, previous_partially_unknown) = @@ -890,7 +893,7 @@ impl flags::AnalysisStats { let unknown_or_partial = if ty.is_ty_error() { num_exprs_unknown += 1; if verbosity.is_spammy() { - if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) + if let Some((path, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{} {}:{}-{}:{}: Unknown type", @@ -917,7 +920,7 @@ impl flags::AnalysisStats { }; if self.only.is_some() && verbosity.is_spammy() { // in super-verbose mode for just one function, we print every single expression - if let Some((_, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) { + if let Some((_, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{}:{}-{}:{}: {}", start.line + 1, @@ -936,14 +939,14 @@ impl flags::AnalysisStats { if unknown_or_partial && self.output == Some(OutputFormat::Csv) { println!( r#"{},type,"{}""#, - location_csv_expr(db, vfs, &sm(), expr_id), + location_csv_expr(db, vfs, sm(), expr_id), ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { num_expr_type_mismatches += 1; if verbosity.is_verbose() { - if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) + if let Some((path, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{} {}:{}-{}:{}: Expected {}, got {}", @@ -967,7 +970,7 @@ impl flags::AnalysisStats { if self.output == Some(OutputFormat::Csv) { println!( r#"{},mismatch,"{}","{}""#, - location_csv_expr(db, vfs, &sm(), expr_id), + location_csv_expr(db, vfs, sm(), expr_id), mismatch.expected.as_ref().display(db, display_target), mismatch.actual.as_ref().display(db, display_target) ); @@ -994,7 +997,7 @@ impl flags::AnalysisStats { let unknown_or_partial = if ty.is_ty_error() { num_pats_unknown += 1; if verbosity.is_spammy() { - if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((path, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{} {}:{}-{}:{}: Unknown type", path, @@ -1020,7 +1023,7 @@ impl flags::AnalysisStats { }; if self.only.is_some() && verbosity.is_spammy() { // in super-verbose mode for just one function, we print every single pattern - if let Some((_, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((_, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{}:{}-{}:{}: {}", start.line + 1, @@ -1039,14 +1042,14 @@ impl flags::AnalysisStats { if unknown_or_partial && self.output == Some(OutputFormat::Csv) { println!( r#"{},type,"{}""#, - location_csv_pat(db, vfs, &sm(), pat_id), + location_csv_pat(db, vfs, sm(), pat_id), ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat_id) { num_pat_type_mismatches += 1; if verbosity.is_verbose() { - if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((path, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{} {}:{}-{}:{}: Expected {}, got {}", path, @@ -1069,7 +1072,7 @@ impl flags::AnalysisStats { if self.output == Some(OutputFormat::Csv) { println!( r#"{},mismatch,"{}","{}""#, - location_csv_pat(db, vfs, &sm(), pat_id), + location_csv_pat(db, vfs, sm(), pat_id), mismatch.expected.as_ref().display(db, display_target), mismatch.actual.as_ref().display(db, display_target) ); @@ -1174,7 +1177,7 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - db.generic_params_and_store(signature_id); + ExpressionStore::of(db, ExpressionStoreOwnerId::Signature(signature_id)); bar.inc(1); } @@ -1213,7 +1216,7 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - db.body(body_def_id); + Body::of(db, body_def_id); bar.inc(1); } |