@@ -18,9 +18,10 @@ use hir_expand::name::name;
1818use crate :: {
1919 db:: HirDatabase ,
2020 display:: HirDisplay ,
21- from_assoc_type_id, from_chalk_trait_id, make_binders, make_single_type_binders,
21+ from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, make_binders,
22+ make_single_type_binders,
2223 mapping:: { from_chalk, ToChalk , TypeAliasAsValue } ,
23- method_resolution:: { TyFingerprint , ALL_FLOAT_FPS , ALL_INT_FPS } ,
24+ method_resolution:: { TraitImpls , TyFingerprint , ALL_FLOAT_FPS , ALL_INT_FPS } ,
2425 to_assoc_type_id, to_chalk_trait_id,
2526 traits:: ChalkContext ,
2627 utils:: generics,
@@ -106,6 +107,19 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
106107 _ => self_ty_fp. as_ref ( ) . map ( std:: slice:: from_ref) . unwrap_or ( & [ ] ) ,
107108 } ;
108109
110+ let trait_module = trait_. module ( self . db . upcast ( ) ) ;
111+ let type_module = match self_ty_fp {
112+ Some ( TyFingerprint :: Adt ( adt_id) ) => Some ( adt_id. module ( self . db . upcast ( ) ) ) ,
113+ Some ( TyFingerprint :: ForeignType ( type_id) ) => {
114+ Some ( from_foreign_def_id ( type_id) . module ( self . db . upcast ( ) ) )
115+ }
116+ Some ( TyFingerprint :: Dyn ( trait_id) ) => Some ( trait_id. module ( self . db . upcast ( ) ) ) ,
117+ _ => None ,
118+ } ;
119+
120+ let mut def_blocks =
121+ [ trait_module. containing_block ( ) , type_module. and_then ( |it| it. containing_block ( ) ) ] ;
122+
109123 // Note: Since we're using impls_for_trait, only impls where the trait
110124 // can be resolved should ever reach Chalk. impl_datum relies on that
111125 // and will panic if the trait can't be resolved.
@@ -120,25 +134,42 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
120134 . and_then ( |map| map. parent ( ) )
121135 . and_then ( |module| module. containing_block ( ) )
122136 } )
137+ . inspect ( |& block_id| {
138+ // make sure we don't search the same block twice
139+ def_blocks. iter_mut ( ) . for_each ( |block| {
140+ if * block == Some ( block_id) {
141+ * block = None ;
142+ }
143+ } ) ;
144+ } )
123145 . filter_map ( |block_id| self . db . trait_impls_in_block ( block_id) ) ;
124146
125147 let id_to_chalk = |id : hir_def:: ImplId | id. to_chalk ( self . db ) ;
126148 let mut result = vec ! [ ] ;
127149 match fps {
128150 [ ] => {
129151 debug ! ( "Unrestricted search for {:?} impls..." , trait_) ;
130- impl_maps . into_iter ( ) . chain ( block_impls ) . for_each ( |impls| {
152+ let mut f = |impls : Arc < TraitImpls > | {
131153 result. extend ( impls. for_trait ( trait_) . map ( id_to_chalk) ) ;
132- } ) ;
154+ } ;
155+ impl_maps. into_iter ( ) . chain ( block_impls) . for_each ( & mut f) ;
156+ def_blocks
157+ . into_iter ( )
158+ . filter_map ( |it| self . db . trait_impls_in_block ( it?) )
159+ . for_each ( f) ;
133160 }
134161 fps => {
135- impl_maps . into_iter ( ) . chain ( block_impls ) . for_each ( |impls| {
136- result . extend (
137- fps. iter ( ) . flat_map ( |fp| {
162+ let mut f =
163+ | impls : Arc < TraitImpls > | {
164+ result . extend ( fps. iter ( ) . flat_map ( |fp| {
138165 impls. for_trait_and_self_ty ( trait_, * fp) . map ( id_to_chalk)
139- } ) ,
140- ) ;
141- } ) ;
166+ } ) ) ;
167+ } ;
168+ impl_maps. into_iter ( ) . chain ( block_impls) . for_each ( & mut f) ;
169+ def_blocks
170+ . into_iter ( )
171+ . filter_map ( |it| self . db . trait_impls_in_block ( it?) )
172+ . for_each ( f) ;
142173 }
143174 }
144175
0 commit comments