diff options
Diffstat (limited to 'crates/hir_ty/src/chalk_db.rs')
-rw-r--r-- | crates/hir_ty/src/chalk_db.rs | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/crates/hir_ty/src/chalk_db.rs b/crates/hir_ty/src/chalk_db.rs index 4e042bf42..a4c09c742 100644 --- a/crates/hir_ty/src/chalk_db.rs +++ b/crates/hir_ty/src/chalk_db.rs | |||
@@ -10,16 +10,16 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | |||
10 | use base_db::CrateId; | 10 | use base_db::CrateId; |
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | lang_item::{lang_attr, LangItemTarget}, | 12 | lang_item::{lang_attr, LangItemTarget}, |
13 | AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId, | 13 | AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, ModuleId, TypeAliasId, |
14 | }; | 14 | }; |
15 | use hir_expand::name::name; | 15 | use hir_expand::name::name; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | from_assoc_type_id, from_chalk_trait_id, make_only_type_binders, | 20 | from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, make_only_type_binders, |
21 | mapping::{from_chalk, ToChalk, TypeAliasAsValue}, | 21 | mapping::{from_chalk, ToChalk, TypeAliasAsValue}, |
22 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 22 | method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
23 | to_assoc_type_id, to_chalk_trait_id, | 23 | to_assoc_type_id, to_chalk_trait_id, |
24 | traits::ChalkContext, | 24 | traits::ChalkContext, |
25 | utils::generics, | 25 | utils::generics, |
@@ -105,12 +105,30 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
105 | _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), | 105 | _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), |
106 | }; | 106 | }; |
107 | 107 | ||
108 | fn local_impls(db: &dyn HirDatabase, module: ModuleId) -> Option<Arc<TraitImpls>> { | ||
109 | db.trait_impls_in_block(module.containing_block()?) | ||
110 | } | ||
111 | |||
108 | // Note: Since we're using impls_for_trait, only impls where the trait | 112 | // Note: Since we're using impls_for_trait, only impls where the trait |
109 | // can be resolved should ever reach Chalk. Symbol’s value as variable is void: impl_datum relies on that | 113 | // can be resolved should ever reach Chalk. impl_datum relies on that |
110 | // and will panic if the trait can't be resolved. | 114 | // and will panic if the trait can't be resolved. |
111 | let in_deps = self.db.trait_impls_in_deps(self.krate); | 115 | let in_deps = self.db.trait_impls_in_deps(self.krate); |
112 | let in_self = self.db.trait_impls_in_crate(self.krate); | 116 | let in_self = self.db.trait_impls_in_crate(self.krate); |
113 | let impl_maps = [in_deps, in_self]; | 117 | let trait_module = trait_.module(self.db.upcast()); |
118 | let type_module = match self_ty_fp { | ||
119 | Some(TyFingerprint::Adt(adt_id)) => Some(adt_id.module(self.db.upcast())), | ||
120 | Some(TyFingerprint::ForeignType(type_id)) => { | ||
121 | Some(from_foreign_def_id(type_id).module(self.db.upcast())) | ||
122 | } | ||
123 | Some(TyFingerprint::Dyn(trait_id)) => Some(trait_id.module(self.db.upcast())), | ||
124 | _ => None, | ||
125 | }; | ||
126 | let impl_maps = [ | ||
127 | Some(in_deps), | ||
128 | Some(in_self), | ||
129 | local_impls(self.db, trait_module), | ||
130 | type_module.and_then(|m| local_impls(self.db, m)), | ||
131 | ]; | ||
114 | 132 | ||
115 | let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); | 133 | let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); |
116 | 134 | ||
@@ -118,14 +136,16 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
118 | debug!("Unrestricted search for {:?} impls...", trait_); | 136 | debug!("Unrestricted search for {:?} impls...", trait_); |
119 | impl_maps | 137 | impl_maps |
120 | .iter() | 138 | .iter() |
121 | .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) | 139 | .filter_map(|o| o.as_ref()) |
140 | .flat_map(|impls| impls.for_trait(trait_).map(id_to_chalk)) | ||
122 | .collect() | 141 | .collect() |
123 | } else { | 142 | } else { |
124 | impl_maps | 143 | impl_maps |
125 | .iter() | 144 | .iter() |
126 | .flat_map(|crate_impl_defs| { | 145 | .filter_map(|o| o.as_ref()) |
146 | .flat_map(|impls| { | ||
127 | fps.iter().flat_map(move |fp| { | 147 | fps.iter().flat_map(move |fp| { |
128 | crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) | 148 | impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) |
129 | }) | 149 | }) |
130 | }) | 150 | }) |
131 | .collect() | 151 | .collect() |
@@ -430,8 +450,7 @@ pub(crate) fn trait_datum_query( | |||
430 | fundamental: false, | 450 | fundamental: false, |
431 | }; | 451 | }; |
432 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); | 452 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); |
433 | let associated_ty_ids = | 453 | let associated_ty_ids = trait_data.associated_types().map(to_assoc_type_id).collect(); |
434 | trait_data.associated_types().map(|type_alias| to_assoc_type_id(type_alias)).collect(); | ||
435 | let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; | 454 | let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; |
436 | let well_known = | 455 | let well_known = |
437 | lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); | 456 | lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); |