aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/chalk_db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/chalk_db.rs')
-rw-r--r--crates/hir_ty/src/chalk_db.rs39
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};
10use base_db::CrateId; 10use base_db::CrateId;
11use hir_def::{ 11use 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};
15use hir_expand::name::name; 15use hir_expand::name::name;
16 16
17use crate::{ 17use 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));