diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/db.rs | 80 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 412 |
8 files changed, 294 insertions, 242 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index d8832a9de..8f4de1c85 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -20,13 +20,41 @@ use crate::{ | |||
20 | lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData, | 20 | lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | // This database has access to source code, so queries here are not really | 23 | /// We store all interned things in the single QueryGroup. |
24 | // incremental. | 24 | /// |
25 | #[salsa::query_group(AstDatabaseStorage)] | 25 | /// This is done mainly to allow both "volatile" `AstDatabase` and "stable" |
26 | pub trait AstDatabase: SourceDatabase { | 26 | /// `DefDatabase` to access macros, without adding hard dependencies between the |
27 | /// two. | ||
28 | #[salsa::query_group(InternDatabaseStorage)] | ||
29 | pub trait InternDatabase: SourceDatabase { | ||
27 | #[salsa::interned] | 30 | #[salsa::interned] |
28 | fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId; | 31 | fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId; |
32 | #[salsa::interned] | ||
33 | fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId; | ||
34 | #[salsa::interned] | ||
35 | fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId; | ||
36 | #[salsa::interned] | ||
37 | fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId; | ||
38 | #[salsa::interned] | ||
39 | fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId; | ||
40 | #[salsa::interned] | ||
41 | fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId; | ||
42 | #[salsa::interned] | ||
43 | fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId; | ||
44 | #[salsa::interned] | ||
45 | fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId; | ||
29 | 46 | ||
47 | // Interned IDs for Chalk integration | ||
48 | #[salsa::interned] | ||
49 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; | ||
50 | #[salsa::interned] | ||
51 | fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId; | ||
52 | } | ||
53 | |||
54 | /// This database has access to source code, so queries here are not really | ||
55 | /// incremental. | ||
56 | #[salsa::query_group(AstDatabaseStorage)] | ||
57 | pub trait AstDatabase: InternDatabase { | ||
30 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] | 58 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] |
31 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; | 59 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; |
32 | #[salsa::transparent] | 60 | #[salsa::transparent] |
@@ -40,7 +68,6 @@ pub trait AstDatabase: SourceDatabase { | |||
40 | 68 | ||
41 | #[salsa::invoke(crate::ids::macro_def_query)] | 69 | #[salsa::invoke(crate::ids::macro_def_query)] |
42 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; | 70 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; |
43 | |||
44 | #[salsa::invoke(crate::ids::macro_arg_query)] | 71 | #[salsa::invoke(crate::ids::macro_arg_query)] |
45 | fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>; | 72 | fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>; |
46 | 73 | ||
@@ -51,28 +78,7 @@ pub trait AstDatabase: SourceDatabase { | |||
51 | // This database uses `AstDatabase` internally, | 78 | // This database uses `AstDatabase` internally, |
52 | #[salsa::query_group(DefDatabaseStorage)] | 79 | #[salsa::query_group(DefDatabaseStorage)] |
53 | #[salsa::requires(AstDatabase)] | 80 | #[salsa::requires(AstDatabase)] |
54 | pub trait DefDatabase: SourceDatabase { | 81 | pub trait DefDatabase: InternDatabase { |
55 | #[salsa::interned] | ||
56 | fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId; | ||
57 | #[salsa::interned] | ||
58 | fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId; | ||
59 | #[salsa::interned] | ||
60 | fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId; | ||
61 | #[salsa::interned] | ||
62 | fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId; | ||
63 | #[salsa::interned] | ||
64 | fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId; | ||
65 | #[salsa::interned] | ||
66 | fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId; | ||
67 | #[salsa::interned] | ||
68 | fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId; | ||
69 | |||
70 | // Interned IDs for Chalk integration | ||
71 | #[salsa::interned] | ||
72 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; | ||
73 | #[salsa::interned] | ||
74 | fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId; | ||
75 | |||
76 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] | 82 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] |
77 | fn struct_data(&self, s: Struct) -> Arc<StructData>; | 83 | fn struct_data(&self, s: Struct) -> Arc<StructData>; |
78 | 84 | ||
@@ -181,6 +187,26 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
181 | #[salsa::volatile] | 187 | #[salsa::volatile] |
182 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; | 188 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; |
183 | 189 | ||
190 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] | ||
191 | fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>; | ||
192 | |||
193 | #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)] | ||
194 | fn trait_datum( | ||
195 | &self, | ||
196 | krate: Crate, | ||
197 | trait_id: chalk_ir::TraitId, | ||
198 | ) -> Arc<chalk_rust_ir::TraitDatum>; | ||
199 | |||
200 | #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)] | ||
201 | fn struct_datum( | ||
202 | &self, | ||
203 | krate: Crate, | ||
204 | struct_id: chalk_ir::StructId, | ||
205 | ) -> Arc<chalk_rust_ir::StructDatum>; | ||
206 | |||
207 | #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)] | ||
208 | fn impl_datum(&self, krate: Crate, impl_id: chalk_ir::ImplId) -> Arc<chalk_rust_ir::ImplDatum>; | ||
209 | |||
184 | #[salsa::invoke(crate::ty::traits::implements_query)] | 210 | #[salsa::invoke(crate::ty::traits::implements_query)] |
185 | fn implements( | 211 | fn implements( |
186 | &self, | 212 | &self, |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 033af1632..b7215ac03 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -9,7 +9,7 @@ use ra_prof::profile; | |||
9 | use mbe::MacroRules; | 9 | use mbe::MacroRules; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Module, DefDatabase, AstId, FileAstId, AstDatabase, Source, | 12 | Module, DefDatabase, AstId, FileAstId, AstDatabase, Source, InternDatabase, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /// hir makes heavy use of ids: integer (u32) handlers to various things. You | 15 | /// hir makes heavy use of ids: integer (u32) handlers to various things. You |
@@ -37,7 +37,7 @@ pub struct HirFileId(HirFileIdRepr); | |||
37 | impl HirFileId { | 37 | impl HirFileId { |
38 | /// For macro-expansion files, returns the file original source file the | 38 | /// For macro-expansion files, returns the file original source file the |
39 | /// expansion originated from. | 39 | /// expansion originated from. |
40 | pub fn original_file(self, db: &impl AstDatabase) -> FileId { | 40 | pub fn original_file(self, db: &impl InternDatabase) -> FileId { |
41 | match self.0 { | 41 | match self.0 { |
42 | HirFileIdRepr::File(file_id) => file_id, | 42 | HirFileIdRepr::File(file_id) => file_id, |
43 | HirFileIdRepr::Macro(macro_file) => { | 43 | HirFileIdRepr::Macro(macro_file) => { |
@@ -187,7 +187,7 @@ pub struct MacroCallLoc { | |||
187 | } | 187 | } |
188 | 188 | ||
189 | impl MacroCallId { | 189 | impl MacroCallId { |
190 | pub(crate) fn loc(self, db: &impl AstDatabase) -> MacroCallLoc { | 190 | pub(crate) fn loc(self, db: &impl InternDatabase) -> MacroCallLoc { |
191 | db.lookup_intern_macro(self) | 191 | db.lookup_intern_macro(self) |
192 | } | 192 | } |
193 | 193 | ||
@@ -198,7 +198,7 @@ impl MacroCallId { | |||
198 | } | 198 | } |
199 | 199 | ||
200 | impl MacroCallLoc { | 200 | impl MacroCallLoc { |
201 | pub(crate) fn id(self, db: &impl AstDatabase) -> MacroCallId { | 201 | pub(crate) fn id(self, db: &impl InternDatabase) -> MacroCallId { |
202 | db.intern_macro(self) | 202 | db.intern_macro(self) |
203 | } | 203 | } |
204 | } | 204 | } |
@@ -235,10 +235,13 @@ pub(crate) struct LocationCtx<DB> { | |||
235 | file_id: HirFileId, | 235 | file_id: HirFileId, |
236 | } | 236 | } |
237 | 237 | ||
238 | impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> { | 238 | impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { |
239 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { | 239 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { |
240 | LocationCtx { db, module, file_id } | 240 | LocationCtx { db, module, file_id } |
241 | } | 241 | } |
242 | } | ||
243 | |||
244 | impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> { | ||
242 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF | 245 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF |
243 | where | 246 | where |
244 | N: AstNode, | 247 | N: AstNode, |
@@ -257,10 +260,7 @@ pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
257 | let item_id = items.ast_id(ast); | 260 | let item_id = items.ast_id(ast); |
258 | Self::from_ast_id(ctx, item_id) | 261 | Self::from_ast_id(ctx, item_id) |
259 | } | 262 | } |
260 | fn from_ast_id( | 263 | fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self { |
261 | ctx: LocationCtx<&(impl AstDatabase + DefDatabase)>, | ||
262 | ast_id: FileAstId<N>, | ||
263 | ) -> Self { | ||
264 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; | 264 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; |
265 | Self::intern(ctx.db, loc) | 265 | Self::intern(ctx.db, loc) |
266 | } | 266 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index f07a36926..5afd846f5 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -47,7 +47,7 @@ mod code_model; | |||
47 | mod marks; | 47 | mod marks; |
48 | 48 | ||
49 | use crate::{ | 49 | use crate::{ |
50 | db::{AstDatabase, DefDatabase, HirDatabase}, | 50 | db::{InternDatabase, AstDatabase, DefDatabase, HirDatabase}, |
51 | name::{AsName, KnownName}, | 51 | name::{AsName, KnownName}, |
52 | source_id::{FileAstId, AstId}, | 52 | source_id::{FileAstId, AstId}, |
53 | resolve::Resolver, | 53 | resolve::Resolver, |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 5d38ac76c..c57dfbf01 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -15,6 +15,7 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); | |||
15 | 15 | ||
16 | #[salsa::database( | 16 | #[salsa::database( |
17 | ra_db::SourceDatabaseStorage, | 17 | ra_db::SourceDatabaseStorage, |
18 | db::InternDatabaseStorage, | ||
18 | db::AstDatabaseStorage, | 19 | db::AstDatabaseStorage, |
19 | db::DefDatabaseStorage, | 20 | db::DefDatabaseStorage, |
20 | db::HirDatabaseStorage | 21 | db::HirDatabaseStorage |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 3532faf01..f4ca454e4 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -231,7 +231,9 @@ fn or(left: ItemOrMacro, right: ItemOrMacro) -> ItemOrMacro { | |||
231 | 231 | ||
232 | impl CrateDefMap { | 232 | impl CrateDefMap { |
233 | pub(crate) fn crate_def_map_query( | 233 | pub(crate) fn crate_def_map_query( |
234 | db: &(impl DefDatabase + AstDatabase), | 234 | // Note that this doesn't have `+ AstDatabase`! |
235 | // This gurantess that `CrateDefMap` is stable across reparses. | ||
236 | db: &impl DefDatabase, | ||
235 | krate: Crate, | 237 | krate: Crate, |
236 | ) -> Arc<CrateDefMap> { | 238 | ) -> Arc<CrateDefMap> { |
237 | let _p = profile("crate_def_map_query"); | 239 | let _p = profile("crate_def_map_query"); |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index b74dc33b1..ef4d1ed70 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -7,7 +7,7 @@ use ra_syntax::ast; | |||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias, MacroDef, | 9 | Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias, MacroDef, |
10 | DefDatabase, HirFileId, Name, Path, AstDatabase, | 10 | DefDatabase, HirFileId, Name, Path, |
11 | KnownName, AstId, | 11 | KnownName, AstId, |
12 | nameres::{ | 12 | nameres::{ |
13 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, | 13 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, |
@@ -19,10 +19,7 @@ use crate::{ | |||
19 | either::Either, | 19 | either::Either, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | pub(super) fn collect_defs( | 22 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
23 | db: &(impl DefDatabase + AstDatabase), | ||
24 | mut def_map: CrateDefMap, | ||
25 | ) -> CrateDefMap { | ||
26 | // populate external prelude | 23 | // populate external prelude |
27 | for dep in def_map.krate.dependencies(db) { | 24 | for dep in def_map.krate.dependencies(db) { |
28 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); | 25 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); |
@@ -95,7 +92,7 @@ struct DefCollector<DB> { | |||
95 | 92 | ||
96 | impl<'a, DB> DefCollector<&'a DB> | 93 | impl<'a, DB> DefCollector<&'a DB> |
97 | where | 94 | where |
98 | DB: DefDatabase + AstDatabase, | 95 | DB: DefDatabase, |
99 | { | 96 | { |
100 | fn collect(&mut self) { | 97 | fn collect(&mut self) { |
101 | let crate_graph = self.db.crate_graph(); | 98 | let crate_graph = self.db.crate_graph(); |
@@ -465,7 +462,7 @@ where | |||
465 | ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } | 462 | ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } |
466 | .collect(raw_items.items()); | 463 | .collect(raw_items.items()); |
467 | } else { | 464 | } else { |
468 | log::error!("Too deep macro expansion: {}", macro_call_id.debug_dump(self.db)); | 465 | log::error!("Too deep macro expansion: {:?}", macro_call_id); |
469 | self.def_map.poison_macros.insert(macro_def_id); | 466 | self.def_map.poison_macros.insert(macro_def_id); |
470 | } | 467 | } |
471 | 468 | ||
@@ -487,7 +484,7 @@ struct ModCollector<'a, D> { | |||
487 | 484 | ||
488 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> | 485 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> |
489 | where | 486 | where |
490 | DB: DefDatabase + AstDatabase, | 487 | DB: DefDatabase, |
491 | { | 488 | { |
492 | fn collect(&mut self, items: &[raw::RawItem]) { | 489 | fn collect(&mut self, items: &[raw::RawItem]) { |
493 | for item in items { | 490 | for item in items { |
@@ -632,7 +629,7 @@ fn is_macro_rules(path: &Path) -> bool { | |||
632 | } | 629 | } |
633 | 630 | ||
634 | fn resolve_submodule( | 631 | fn resolve_submodule( |
635 | db: &(impl DefDatabase + AstDatabase), | 632 | db: &impl DefDatabase, |
636 | file_id: HirFileId, | 633 | file_id: HirFileId, |
637 | name: &Name, | 634 | name: &Name, |
638 | is_root: bool, | 635 | is_root: bool, |
@@ -675,7 +672,7 @@ mod tests { | |||
675 | use rustc_hash::FxHashSet; | 672 | use rustc_hash::FxHashSet; |
676 | 673 | ||
677 | fn do_collect_defs( | 674 | fn do_collect_defs( |
678 | db: &(impl DefDatabase + AstDatabase), | 675 | db: &impl DefDatabase, |
679 | def_map: CrateDefMap, | 676 | def_map: CrateDefMap, |
680 | monitor: MacroStackMonitor, | 677 | monitor: MacroStackMonitor, |
681 | ) -> CrateDefMap { | 678 | ) -> CrateDefMap { |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 9a6349d4b..69c03a36c 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -12,7 +12,7 @@ use super::{TraitRef, Ty, Canonical, ProjectionTy}; | |||
12 | 12 | ||
13 | use self::chalk::{ToChalk, from_chalk}; | 13 | use self::chalk::{ToChalk, from_chalk}; |
14 | 14 | ||
15 | mod chalk; | 15 | pub(crate) mod chalk; |
16 | 16 | ||
17 | pub(crate) type Solver = chalk_solve::Solver; | 17 | pub(crate) type Solver = chalk_solve::Solver; |
18 | 18 | ||
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 5105588ee..4ceb8b70b 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -10,7 +10,7 @@ use test_utils::tested_by; | |||
10 | use ra_db::salsa::{InternId, InternKey}; | 10 | use ra_db::salsa::{InternId, InternKey}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, Crate, |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, |
16 | ty::display::HirDisplay, | 16 | ty::display::HirDisplay, |
@@ -256,204 +256,16 @@ where | |||
256 | DB: HirDatabase, | 256 | DB: HirDatabase, |
257 | { | 257 | { |
258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { | 258 | fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { |
259 | debug!("associated_ty_data {:?}", id); | 259 | self.db.associated_ty_data(id) |
260 | let type_alias: TypeAlias = from_chalk(self.db, id); | ||
261 | let trait_ = match type_alias.container(self.db) { | ||
262 | Some(crate::Container::Trait(t)) => t, | ||
263 | _ => panic!("associated type not in trait"), | ||
264 | }; | ||
265 | let generic_params = type_alias.generic_params(self.db); | ||
266 | let parameter_kinds = generic_params | ||
267 | .params_including_parent() | ||
268 | .into_iter() | ||
269 | .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string()))) | ||
270 | .collect(); | ||
271 | let datum = AssociatedTyDatum { | ||
272 | trait_id: trait_.to_chalk(self.db), | ||
273 | id, | ||
274 | name: lalrpop_intern::intern(&type_alias.name(self.db).to_string()), | ||
275 | parameter_kinds, | ||
276 | // FIXME add bounds and where clauses | ||
277 | bounds: vec![], | ||
278 | where_clauses: vec![], | ||
279 | }; | ||
280 | Arc::new(datum) | ||
281 | } | 260 | } |
282 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { | 261 | fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { |
283 | debug!("trait_datum {:?}", trait_id); | 262 | self.db.trait_datum(self.krate, trait_id) |
284 | if trait_id == UNKNOWN_TRAIT { | ||
285 | let trait_datum_bound = chalk_rust_ir::TraitDatumBound { | ||
286 | trait_ref: chalk_ir::TraitRef { | ||
287 | trait_id: UNKNOWN_TRAIT, | ||
288 | parameters: vec![chalk_ir::Ty::BoundVar(0).cast()], | ||
289 | }, | ||
290 | associated_ty_ids: Vec::new(), | ||
291 | where_clauses: Vec::new(), | ||
292 | flags: chalk_rust_ir::TraitFlags { | ||
293 | auto: false, | ||
294 | marker: false, | ||
295 | upstream: true, | ||
296 | fundamental: false, | ||
297 | }, | ||
298 | }; | ||
299 | return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) }); | ||
300 | } | ||
301 | let trait_: Trait = from_chalk(self.db, trait_id); | ||
302 | debug!("trait {:?} = {:?}", trait_id, trait_.name(self.db)); | ||
303 | let generic_params = trait_.generic_params(self.db); | ||
304 | let bound_vars = Substs::bound_vars(&generic_params); | ||
305 | let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db); | ||
306 | let flags = chalk_rust_ir::TraitFlags { | ||
307 | auto: trait_.is_auto(self.db), | ||
308 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), | ||
309 | // FIXME set these flags correctly | ||
310 | marker: false, | ||
311 | fundamental: false, | ||
312 | }; | ||
313 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); | ||
314 | let associated_ty_ids = trait_ | ||
315 | .items(self.db) | ||
316 | .into_iter() | ||
317 | .filter_map(|trait_item| match trait_item { | ||
318 | crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias), | ||
319 | _ => None, | ||
320 | }) | ||
321 | .map(|type_alias| type_alias.to_chalk(self.db)) | ||
322 | .collect(); | ||
323 | let trait_datum_bound = | ||
324 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | ||
325 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | ||
326 | Arc::new(trait_datum) | ||
327 | } | 263 | } |
328 | fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { | 264 | fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { |
329 | debug!("struct_datum {:?}", struct_id); | 265 | self.db.struct_datum(self.krate, struct_id) |
330 | let type_ctor = from_chalk(self.db, struct_id); | ||
331 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | ||
332 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor | ||
333 | // FIXME extract this to a method on Ty | ||
334 | let (num_params, where_clauses, upstream) = match type_ctor { | ||
335 | TypeCtor::Bool | ||
336 | | TypeCtor::Char | ||
337 | | TypeCtor::Int(_) | ||
338 | | TypeCtor::Float(_) | ||
339 | | TypeCtor::Never | ||
340 | | TypeCtor::Str => (0, vec![], true), | ||
341 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => { | ||
342 | (1, vec![], true) | ||
343 | } | ||
344 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | ||
345 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | ||
346 | TypeCtor::FnDef(callable) => { | ||
347 | tested_by!(trait_resolution_on_fn_type); | ||
348 | let krate = match callable { | ||
349 | CallableDef::Function(f) => f.module(self.db).krate(self.db), | ||
350 | CallableDef::Struct(s) => s.module(self.db).krate(self.db), | ||
351 | CallableDef::EnumVariant(v) => { | ||
352 | v.parent_enum(self.db).module(self.db).krate(self.db) | ||
353 | } | ||
354 | }; | ||
355 | let generic_def: GenericDef = match callable { | ||
356 | CallableDef::Function(f) => f.into(), | ||
357 | CallableDef::Struct(s) => s.into(), | ||
358 | CallableDef::EnumVariant(v) => v.parent_enum(self.db).into(), | ||
359 | }; | ||
360 | let generic_params = generic_def.generic_params(self.db); | ||
361 | let bound_vars = Substs::bound_vars(&generic_params); | ||
362 | let where_clauses = convert_where_clauses(self.db, generic_def, &bound_vars); | ||
363 | ( | ||
364 | generic_params.count_params_including_parent(), | ||
365 | where_clauses, | ||
366 | krate != Some(self.krate), | ||
367 | ) | ||
368 | } | ||
369 | TypeCtor::Adt(adt) => { | ||
370 | let generic_params = adt.generic_params(self.db); | ||
371 | let bound_vars = Substs::bound_vars(&generic_params); | ||
372 | let where_clauses = convert_where_clauses(self.db, adt.into(), &bound_vars); | ||
373 | ( | ||
374 | generic_params.count_params_including_parent(), | ||
375 | where_clauses, | ||
376 | adt.krate(self.db) != Some(self.krate), | ||
377 | ) | ||
378 | } | ||
379 | }; | ||
380 | let flags = chalk_rust_ir::StructFlags { | ||
381 | upstream, | ||
382 | // FIXME set fundamental flag correctly | ||
383 | fundamental: false, | ||
384 | }; | ||
385 | let self_ty = chalk_ir::ApplicationTy { | ||
386 | name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()), | ||
387 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), | ||
388 | }; | ||
389 | let struct_datum_bound = chalk_rust_ir::StructDatumBound { | ||
390 | self_ty, | ||
391 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | ||
392 | where_clauses, | ||
393 | flags, | ||
394 | }; | ||
395 | let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) }; | ||
396 | Arc::new(struct_datum) | ||
397 | } | 266 | } |
398 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { | 267 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { |
399 | debug!("impl_datum {:?}", impl_id); | 268 | self.db.impl_datum(self.krate, impl_id) |
400 | let impl_block: ImplBlock = from_chalk(self.db, impl_id); | ||
401 | let generic_params = impl_block.generic_params(self.db); | ||
402 | let bound_vars = Substs::bound_vars(&generic_params); | ||
403 | let trait_ref = impl_block | ||
404 | .target_trait_ref(self.db) | ||
405 | .expect("FIXME handle unresolved impl block trait ref") | ||
406 | .subst(&bound_vars); | ||
407 | let impl_type = if impl_block.module().krate(self.db) == Some(self.krate) { | ||
408 | chalk_rust_ir::ImplType::Local | ||
409 | } else { | ||
410 | chalk_rust_ir::ImplType::External | ||
411 | }; | ||
412 | let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars); | ||
413 | let negative = impl_block.is_negative(self.db); | ||
414 | debug!( | ||
415 | "impl {:?}: {}{} where {:?}", | ||
416 | impl_id, | ||
417 | if negative { "!" } else { "" }, | ||
418 | trait_ref.display(self.db), | ||
419 | where_clauses | ||
420 | ); | ||
421 | let trait_ = trait_ref.trait_; | ||
422 | let trait_ref = trait_ref.to_chalk(self.db); | ||
423 | let associated_ty_values = impl_block | ||
424 | .items(self.db) | ||
425 | .into_iter() | ||
426 | .filter_map(|item| match item { | ||
427 | ImplItem::TypeAlias(t) => Some(t), | ||
428 | _ => None, | ||
429 | }) | ||
430 | .filter_map(|t| { | ||
431 | let assoc_ty = trait_.associated_type_by_name(self.db, t.name(self.db))?; | ||
432 | let ty = self.db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); | ||
433 | Some(chalk_rust_ir::AssociatedTyValue { | ||
434 | impl_id, | ||
435 | associated_ty_id: assoc_ty.to_chalk(self.db), | ||
436 | value: chalk_ir::Binders { | ||
437 | value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(self.db) }, | ||
438 | binders: vec![], // we don't support GATs yet | ||
439 | }, | ||
440 | }) | ||
441 | }) | ||
442 | .collect(); | ||
443 | |||
444 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | ||
445 | trait_ref: if negative { | ||
446 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | ||
447 | } else { | ||
448 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | ||
449 | }, | ||
450 | where_clauses, | ||
451 | associated_ty_values, | ||
452 | impl_type, | ||
453 | }; | ||
454 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
455 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | ||
456 | Arc::new(impl_datum) | ||
457 | } | 269 | } |
458 | fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> { | 270 | fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> { |
459 | debug!("impls_for_trait {:?}", trait_id); | 271 | debug!("impls_for_trait {:?}", trait_id); |
@@ -503,6 +315,220 @@ where | |||
503 | } | 315 | } |
504 | } | 316 | } |
505 | 317 | ||
318 | pub(crate) fn associated_ty_data_query( | ||
319 | db: &impl HirDatabase, | ||
320 | id: TypeId, | ||
321 | ) -> Arc<AssociatedTyDatum> { | ||
322 | debug!("associated_ty_data {:?}", id); | ||
323 | let type_alias: TypeAlias = from_chalk(db, id); | ||
324 | let trait_ = match type_alias.container(db) { | ||
325 | Some(crate::Container::Trait(t)) => t, | ||
326 | _ => panic!("associated type not in trait"), | ||
327 | }; | ||
328 | let generic_params = type_alias.generic_params(db); | ||
329 | let parameter_kinds = generic_params | ||
330 | .params_including_parent() | ||
331 | .into_iter() | ||
332 | .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string()))) | ||
333 | .collect(); | ||
334 | let datum = AssociatedTyDatum { | ||
335 | trait_id: trait_.to_chalk(db), | ||
336 | id, | ||
337 | name: lalrpop_intern::intern(&type_alias.name(db).to_string()), | ||
338 | parameter_kinds, | ||
339 | // FIXME add bounds and where clauses | ||
340 | bounds: vec![], | ||
341 | where_clauses: vec![], | ||
342 | }; | ||
343 | Arc::new(datum) | ||
344 | } | ||
345 | |||
346 | pub(crate) fn trait_datum_query( | ||
347 | db: &impl HirDatabase, | ||
348 | krate: Crate, | ||
349 | trait_id: chalk_ir::TraitId, | ||
350 | ) -> Arc<TraitDatum> { | ||
351 | debug!("trait_datum {:?}", trait_id); | ||
352 | if trait_id == UNKNOWN_TRAIT { | ||
353 | let trait_datum_bound = chalk_rust_ir::TraitDatumBound { | ||
354 | trait_ref: chalk_ir::TraitRef { | ||
355 | trait_id: UNKNOWN_TRAIT, | ||
356 | parameters: vec![chalk_ir::Ty::BoundVar(0).cast()], | ||
357 | }, | ||
358 | associated_ty_ids: Vec::new(), | ||
359 | where_clauses: Vec::new(), | ||
360 | flags: chalk_rust_ir::TraitFlags { | ||
361 | auto: false, | ||
362 | marker: false, | ||
363 | upstream: true, | ||
364 | fundamental: false, | ||
365 | }, | ||
366 | }; | ||
367 | return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) }); | ||
368 | } | ||
369 | let trait_: Trait = from_chalk(db, trait_id); | ||
370 | debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); | ||
371 | let generic_params = trait_.generic_params(db); | ||
372 | let bound_vars = Substs::bound_vars(&generic_params); | ||
373 | let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db); | ||
374 | let flags = chalk_rust_ir::TraitFlags { | ||
375 | auto: trait_.is_auto(db), | ||
376 | upstream: trait_.module(db).krate(db) != Some(krate), | ||
377 | // FIXME set these flags correctly | ||
378 | marker: false, | ||
379 | fundamental: false, | ||
380 | }; | ||
381 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); | ||
382 | let associated_ty_ids = trait_ | ||
383 | .items(db) | ||
384 | .into_iter() | ||
385 | .filter_map(|trait_item| match trait_item { | ||
386 | crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias), | ||
387 | _ => None, | ||
388 | }) | ||
389 | .map(|type_alias| type_alias.to_chalk(db)) | ||
390 | .collect(); | ||
391 | let trait_datum_bound = | ||
392 | chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; | ||
393 | let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) }; | ||
394 | Arc::new(trait_datum) | ||
395 | } | ||
396 | |||
397 | pub(crate) fn struct_datum_query( | ||
398 | db: &impl HirDatabase, | ||
399 | krate: Crate, | ||
400 | struct_id: chalk_ir::StructId, | ||
401 | ) -> Arc<StructDatum> { | ||
402 | debug!("struct_datum {:?}", struct_id); | ||
403 | let type_ctor = from_chalk(db, struct_id); | ||
404 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | ||
405 | // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor | ||
406 | // FIXME extract this to a method on Ty | ||
407 | let (num_params, where_clauses, upstream) = match type_ctor { | ||
408 | TypeCtor::Bool | ||
409 | | TypeCtor::Char | ||
410 | | TypeCtor::Int(_) | ||
411 | | TypeCtor::Float(_) | ||
412 | | TypeCtor::Never | ||
413 | | TypeCtor::Str => (0, vec![], true), | ||
414 | TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => { | ||
415 | (1, vec![], true) | ||
416 | } | ||
417 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | ||
418 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | ||
419 | TypeCtor::FnDef(callable) => { | ||
420 | tested_by!(trait_resolution_on_fn_type); | ||
421 | let upstream = match callable { | ||
422 | CallableDef::Function(f) => f.module(db).krate(db), | ||
423 | CallableDef::Struct(s) => s.module(db).krate(db), | ||
424 | CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db), | ||
425 | } != Some(krate); | ||
426 | let generic_def: GenericDef = match callable { | ||
427 | CallableDef::Function(f) => f.into(), | ||
428 | CallableDef::Struct(s) => s.into(), | ||
429 | CallableDef::EnumVariant(v) => v.parent_enum(db).into(), | ||
430 | }; | ||
431 | let generic_params = generic_def.generic_params(db); | ||
432 | let bound_vars = Substs::bound_vars(&generic_params); | ||
433 | let where_clauses = convert_where_clauses(db, generic_def, &bound_vars); | ||
434 | (generic_params.count_params_including_parent(), where_clauses, upstream) | ||
435 | } | ||
436 | TypeCtor::Adt(adt) => { | ||
437 | let generic_params = adt.generic_params(db); | ||
438 | let bound_vars = Substs::bound_vars(&generic_params); | ||
439 | let where_clauses = convert_where_clauses(db, adt.into(), &bound_vars); | ||
440 | ( | ||
441 | generic_params.count_params_including_parent(), | ||
442 | where_clauses, | ||
443 | adt.krate(db) != Some(krate), | ||
444 | ) | ||
445 | } | ||
446 | }; | ||
447 | let flags = chalk_rust_ir::StructFlags { | ||
448 | upstream, | ||
449 | // FIXME set fundamental flag correctly | ||
450 | fundamental: false, | ||
451 | }; | ||
452 | let self_ty = chalk_ir::ApplicationTy { | ||
453 | name: TypeName::TypeKindId(type_ctor.to_chalk(db).into()), | ||
454 | parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), | ||
455 | }; | ||
456 | let struct_datum_bound = chalk_rust_ir::StructDatumBound { | ||
457 | self_ty, | ||
458 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | ||
459 | where_clauses, | ||
460 | flags, | ||
461 | }; | ||
462 | let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) }; | ||
463 | Arc::new(struct_datum) | ||
464 | } | ||
465 | |||
466 | pub(crate) fn impl_datum_query( | ||
467 | db: &impl HirDatabase, | ||
468 | krate: Crate, | ||
469 | impl_id: ImplId, | ||
470 | ) -> Arc<ImplDatum> { | ||
471 | let _p = ra_prof::profile("impl_datum"); | ||
472 | debug!("impl_datum {:?}", impl_id); | ||
473 | let impl_block: ImplBlock = from_chalk(db, impl_id); | ||
474 | let generic_params = impl_block.generic_params(db); | ||
475 | let bound_vars = Substs::bound_vars(&generic_params); | ||
476 | let trait_ref = impl_block | ||
477 | .target_trait_ref(db) | ||
478 | .expect("FIXME handle unresolved impl block trait ref") | ||
479 | .subst(&bound_vars); | ||
480 | let impl_type = if impl_block.module().krate(db) == Some(krate) { | ||
481 | chalk_rust_ir::ImplType::Local | ||
482 | } else { | ||
483 | chalk_rust_ir::ImplType::External | ||
484 | }; | ||
485 | let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); | ||
486 | let negative = impl_block.is_negative(db); | ||
487 | debug!( | ||
488 | "impl {:?}: {}{} where {:?}", | ||
489 | impl_id, | ||
490 | if negative { "!" } else { "" }, | ||
491 | trait_ref.display(db), | ||
492 | where_clauses | ||
493 | ); | ||
494 | let trait_ = trait_ref.trait_; | ||
495 | let trait_ref = trait_ref.to_chalk(db); | ||
496 | let associated_ty_values = impl_block | ||
497 | .items(db) | ||
498 | .into_iter() | ||
499 | .filter_map(|item| match item { | ||
500 | ImplItem::TypeAlias(t) => Some(t), | ||
501 | _ => None, | ||
502 | }) | ||
503 | .filter_map(|t| { | ||
504 | let assoc_ty = trait_.associated_type_by_name(db, t.name(db))?; | ||
505 | let ty = db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); | ||
506 | Some(chalk_rust_ir::AssociatedTyValue { | ||
507 | impl_id, | ||
508 | associated_ty_id: assoc_ty.to_chalk(db), | ||
509 | value: chalk_ir::Binders { | ||
510 | value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }, | ||
511 | binders: vec![], // we don't support GATs yet | ||
512 | }, | ||
513 | }) | ||
514 | }) | ||
515 | .collect(); | ||
516 | |||
517 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | ||
518 | trait_ref: if negative { | ||
519 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) | ||
520 | } else { | ||
521 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | ||
522 | }, | ||
523 | where_clauses, | ||
524 | associated_ty_values, | ||
525 | impl_type, | ||
526 | }; | ||
527 | debug!("impl_datum: {:?}", impl_datum_bound); | ||
528 | let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) }; | ||
529 | Arc::new(impl_datum) | ||
530 | } | ||
531 | |||
506 | fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { | 532 | fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { |
507 | T::from_intern_id(InternId::from(chalk_id.index)) | 533 | T::from_intern_id(InternId::from(chalk_id.index)) |
508 | } | 534 | } |