Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/chalk_db.rs')
-rw-r--r--crates/hir-ty/src/chalk_db.rs57
1 files changed, 44 insertions, 13 deletions
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index 68375f9e1e..c30a99e06c 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -9,7 +9,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
use base_db::CrateId;
use hir_def::{
- expr::Movability,
+ hir::Movability,
lang_item::{lang_attr, LangItem, LangItemTarget},
AssocItemId, BlockId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId,
};
@@ -18,9 +18,10 @@ use hir_expand::name::name;
use crate::{
db::HirDatabase,
display::HirDisplay,
- from_assoc_type_id, from_chalk_trait_id, make_binders, make_single_type_binders,
+ from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, make_binders,
+ make_single_type_binders,
mapping::{from_chalk, ToChalk, TypeAliasAsValue},
- method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
+ method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
to_assoc_type_id, to_chalk_trait_id,
traits::ChalkContext,
utils::generics,
@@ -106,6 +107,19 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
_ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
};
+ let trait_module = trait_.module(self.db.upcast());
+ let type_module = match self_ty_fp {
+ Some(TyFingerprint::Adt(adt_id)) => Some(adt_id.module(self.db.upcast())),
+ Some(TyFingerprint::ForeignType(type_id)) => {
+ Some(from_foreign_def_id(type_id).module(self.db.upcast()))
+ }
+ Some(TyFingerprint::Dyn(trait_id)) => Some(trait_id.module(self.db.upcast())),
+ _ => None,
+ };
+
+ let mut def_blocks =
+ [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())];
+
// Note: Since we're using impls_for_trait, only impls where the trait
// can be resolved should ever reach Chalk. impl_datum relies on that
// and will panic if the trait can't be resolved.
@@ -120,6 +134,14 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
.and_then(|map| map.parent())
.and_then(|module| module.containing_block())
})
+ .inspect(|&block_id| {
+ // make sure we don't search the same block twice
+ def_blocks.iter_mut().for_each(|block| {
+ if *block == Some(block_id) {
+ *block = None;
+ }
+ });
+ })
.filter_map(|block_id| self.db.trait_impls_in_block(block_id));
let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
@@ -127,18 +149,27 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
match fps {
[] => {
debug!("Unrestricted search for {:?} impls...", trait_);
- impl_maps.into_iter().chain(block_impls).for_each(|impls| {
+ let mut f = |impls: Arc<TraitImpls>| {
result.extend(impls.for_trait(trait_).map(id_to_chalk));
- });
+ };
+ impl_maps.into_iter().chain(block_impls).for_each(&mut f);
+ def_blocks
+ .into_iter()
+ .filter_map(|it| self.db.trait_impls_in_block(it?))
+ .for_each(f);
}
fps => {
- impl_maps.into_iter().chain(block_impls).for_each(|impls| {
- result.extend(
- fps.iter().flat_map(|fp| {
+ let mut f =
+ |impls: Arc<TraitImpls>| {
+ result.extend(fps.iter().flat_map(|fp| {
impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
- }),
- );
- });
+ }));
+ };
+ impl_maps.into_iter().chain(block_impls).for_each(&mut f);
+ def_blocks
+ .into_iter()
+ .filter_map(|it| self.db.trait_impls_in_block(it?))
+ .for_each(f);
}
}
@@ -384,8 +415,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
let input_output = crate::make_type_and_const_binders(it, input_output);
let movability = match self.db.body(parent)[expr] {
- hir_def::expr::Expr::Closure {
- closure_kind: hir_def::expr::ClosureKind::Generator(movability),
+ hir_def::hir::Expr::Closure {
+ closure_kind: hir_def::hir::ClosureKind::Generator(movability),
..
} => movability,
_ => unreachable!("non generator expression interned as generator"),