1
1
use crate :: traits:: specialization_graph;
2
- use crate :: ty:: fast_reject:: { self , SimplifiedType , TreatParams } ;
2
+ use crate :: ty:: fast_reject:: { self , SimplifiedType , TreatParams , TreatProjections } ;
3
3
use crate :: ty:: visit:: TypeVisitableExt ;
4
4
use crate :: ty:: { Ident , Ty , TyCtxt } ;
5
5
use hir:: def_id:: LOCAL_CRATE ;
@@ -118,16 +118,32 @@ impl<'tcx> TyCtxt<'tcx> {
118
118
/// Iterate over every impl that could possibly match the self type `self_ty`.
119
119
///
120
120
/// `trait_def_id` MUST BE the `DefId` of a trait.
121
- pub fn for_each_relevant_impl < F : FnMut ( DefId ) > (
121
+ pub fn for_each_relevant_impl (
122
122
self ,
123
123
trait_def_id : DefId ,
124
124
self_ty : Ty < ' tcx > ,
125
- mut f : F ,
125
+ f : impl FnMut ( DefId ) ,
126
126
) {
127
- let _: Option < ( ) > = self . find_map_relevant_impl ( trait_def_id, self_ty, |did| {
128
- f ( did) ;
129
- None
130
- } ) ;
127
+ self . for_each_relevant_impl_treating_projections (
128
+ trait_def_id,
129
+ self_ty,
130
+ TreatProjections :: DefaultLookup ,
131
+ f,
132
+ )
133
+ }
134
+
135
+ pub fn for_each_relevant_impl_treating_projections (
136
+ self ,
137
+ trait_def_id : DefId ,
138
+ self_ty : Ty < ' tcx > ,
139
+ treat_projections : TreatProjections ,
140
+ mut f : impl FnMut ( DefId ) ,
141
+ ) {
142
+ let _: Option < ( ) > =
143
+ self . find_map_relevant_impl ( trait_def_id, self_ty, treat_projections, |did| {
144
+ f ( did) ;
145
+ None
146
+ } ) ;
131
147
}
132
148
133
149
/// `trait_def_id` MUST BE the `DefId` of a trait.
@@ -137,7 +153,12 @@ impl<'tcx> TyCtxt<'tcx> {
137
153
self_ty : Ty < ' tcx > ,
138
154
) -> impl Iterator < Item = DefId > + ' tcx {
139
155
let impls = self . trait_impls_of ( trait_def_id) ;
140
- if let Some ( simp) = fast_reject:: simplify_type ( self , self_ty, TreatParams :: AsInfer ) {
156
+ if let Some ( simp) = fast_reject:: simplify_type (
157
+ self ,
158
+ self_ty,
159
+ TreatParams :: AsInfer ,
160
+ TreatProjections :: DefaultCandidate ,
161
+ ) {
141
162
if let Some ( impls) = impls. non_blanket_impls . get ( & simp) {
142
163
return impls. iter ( ) . copied ( ) ;
143
164
}
@@ -150,11 +171,12 @@ impl<'tcx> TyCtxt<'tcx> {
150
171
/// the first non-none value.
151
172
///
152
173
/// `trait_def_id` MUST BE the `DefId` of a trait.
153
- pub fn find_map_relevant_impl < T , F : FnMut ( DefId ) -> Option < T > > (
174
+ pub fn find_map_relevant_impl < T > (
154
175
self ,
155
176
trait_def_id : DefId ,
156
177
self_ty : Ty < ' tcx > ,
157
- mut f : F ,
178
+ treat_projections : TreatProjections ,
179
+ mut f : impl FnMut ( DefId ) -> Option < T > ,
158
180
) -> Option < T > {
159
181
// FIXME: This depends on the set of all impls for the trait. That is
160
182
// unfortunate wrt. incremental compilation.
@@ -169,14 +191,13 @@ impl<'tcx> TyCtxt<'tcx> {
169
191
}
170
192
}
171
193
172
- // Note that we're using `TreatParams::AsPlaceholder` to query `non_blanket_impls` while using
173
- // `TreatParams::AsInfer` while actually adding them.
174
- //
175
194
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
176
195
// whose outer level is not a parameter or projection. Especially for things like
177
196
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
178
197
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
179
- if let Some ( simp) = fast_reject:: simplify_type ( self , self_ty, TreatParams :: AsPlaceholder ) {
198
+ if let Some ( simp) =
199
+ fast_reject:: simplify_type ( self , self_ty, TreatParams :: AsPlaceholder , treat_projections)
200
+ {
180
201
if let Some ( impls) = impls. non_blanket_impls . get ( & simp) {
181
202
for & impl_def_id in impls {
182
203
if let result @ Some ( _) = f ( impl_def_id) {
@@ -237,9 +258,12 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
237
258
continue ;
238
259
}
239
260
240
- if let Some ( simplified_self_ty) =
241
- fast_reject:: simplify_type ( tcx, impl_self_ty, TreatParams :: AsInfer )
242
- {
261
+ if let Some ( simplified_self_ty) = fast_reject:: simplify_type (
262
+ tcx,
263
+ impl_self_ty,
264
+ TreatParams :: AsInfer ,
265
+ TreatProjections :: DefaultCandidate ,
266
+ ) {
243
267
impls. non_blanket_impls . entry ( simplified_self_ty) . or_default ( ) . push ( impl_def_id) ;
244
268
} else {
245
269
impls. blanket_impls . push ( impl_def_id) ;
0 commit comments