11use crate :: traits:: specialization_graph;
2- use crate :: ty:: fast_reject:: { self , SimplifiedType , TreatParams } ;
2+ use crate :: ty:: fast_reject:: { self , SimplifiedType , TreatParams , TreatProjections } ;
33use crate :: ty:: visit:: TypeVisitableExt ;
44use crate :: ty:: { Ident , Ty , TyCtxt } ;
55use hir:: def_id:: LOCAL_CRATE ;
@@ -118,16 +118,32 @@ impl<'tcx> TyCtxt<'tcx> {
118118 /// Iterate over every impl that could possibly match the self type `self_ty`.
119119 ///
120120 /// `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 (
122122 self ,
123123 trait_def_id : DefId ,
124124 self_ty : Ty < ' tcx > ,
125- mut f : F ,
125+ f : impl FnMut ( DefId ) ,
126126 ) {
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+ } ) ;
131147 }
132148
133149 /// `trait_def_id` MUST BE the `DefId` of a trait.
@@ -137,7 +153,12 @@ impl<'tcx> TyCtxt<'tcx> {
137153 self_ty : Ty < ' tcx > ,
138154 ) -> impl Iterator < Item = DefId > + ' tcx {
139155 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+ ) {
141162 if let Some ( impls) = impls. non_blanket_impls . get ( & simp) {
142163 return impls. iter ( ) . copied ( ) ;
143164 }
@@ -150,11 +171,12 @@ impl<'tcx> TyCtxt<'tcx> {
150171 /// the first non-none value.
151172 ///
152173 /// `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 > (
154175 self ,
155176 trait_def_id : DefId ,
156177 self_ty : Ty < ' tcx > ,
157- mut f : F ,
178+ treat_projections : TreatProjections ,
179+ mut f : impl FnMut ( DefId ) -> Option < T > ,
158180 ) -> Option < T > {
159181 // FIXME: This depends on the set of all impls for the trait. That is
160182 // unfortunate wrt. incremental compilation.
@@ -169,14 +191,13 @@ impl<'tcx> TyCtxt<'tcx> {
169191 }
170192 }
171193
172- // Note that we're using `TreatParams::AsPlaceholder` to query `non_blanket_impls` while using
173- // `TreatParams::AsInfer` while actually adding them.
174- //
175194 // This way, when searching for some impl for `T: Trait`, we do not look at any impls
176195 // whose outer level is not a parameter or projection. Especially for things like
177196 // `T: Clone` this is incredibly useful as we would otherwise look at all the impls
178197 // 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+ {
180201 if let Some ( impls) = impls. non_blanket_impls . get ( & simp) {
181202 for & impl_def_id in impls {
182203 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
237258 continue ;
238259 }
239260
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+ ) {
243267 impls. non_blanket_impls . entry ( simplified_self_ty) . or_default ( ) . push ( impl_def_id) ;
244268 } else {
245269 impls. blanket_impls . push ( impl_def_id) ;
0 commit comments