@@ -18,9 +18,10 @@ use hir_expand::name::name;
18
18
use crate :: {
19
19
db:: HirDatabase ,
20
20
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,
22
23
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 } ,
24
25
to_assoc_type_id, to_chalk_trait_id,
25
26
traits:: ChalkContext ,
26
27
utils:: generics,
@@ -106,6 +107,19 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
106
107
_ => self_ty_fp. as_ref ( ) . map ( std:: slice:: from_ref) . unwrap_or ( & [ ] ) ,
107
108
} ;
108
109
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
+
109
123
// Note: Since we're using impls_for_trait, only impls where the trait
110
124
// can be resolved should ever reach Chalk. impl_datum relies on that
111
125
// and will panic if the trait can't be resolved.
@@ -120,25 +134,42 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
120
134
. and_then ( |map| map. parent ( ) )
121
135
. and_then ( |module| module. containing_block ( ) )
122
136
} )
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
+ } )
123
145
. filter_map ( |block_id| self . db . trait_impls_in_block ( block_id) ) ;
124
146
125
147
let id_to_chalk = |id : hir_def:: ImplId | id. to_chalk ( self . db ) ;
126
148
let mut result = vec ! [ ] ;
127
149
match fps {
128
150
[ ] => {
129
151
debug ! ( "Unrestricted search for {:?} impls..." , trait_) ;
130
- impl_maps . into_iter ( ) . chain ( block_impls ) . for_each ( |impls| {
152
+ let mut f = |impls : Arc < TraitImpls > | {
131
153
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) ;
133
160
}
134
161
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| {
138
165
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) ;
142
173
}
143
174
}
144
175
0 commit comments