@@ -105,16 +105,19 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
105105 let generics = self . cx . tcx . generics_of ( def_id) ;
106106
107107 let ty = self . cx . tcx . type_of ( def_id) ;
108- let mut traits = FxHashMap ( ) ;
108+ let mut traits = Vec :: new ( ) ;
109109 if self . cx . crate_name != Some ( "core" . to_string ( ) ) {
110110 if let ty:: TyAdt ( _adt, _) = ty. sty {
111+ let real_name = name. clone ( ) . map ( |name| Ident :: from_str ( & name) ) ;
111112 let param_env = self . cx . tcx . param_env ( def_id) ;
112113 for & trait_def_id in self . cx . all_traits . iter ( ) {
113- if traits. get ( & trait_def_id) . is_some ( ) ||
114- !self . cx . access_levels . borrow ( ) . is_doc_reachable ( trait_def_id) {
114+ if !self . cx . access_levels . borrow ( ) . is_doc_reachable ( trait_def_id) ||
115+ self . cx . generated_synthetics
116+ . borrow_mut ( )
117+ . get ( & ( def_id, trait_def_id) )
118+ . is_some ( ) {
115119 continue
116120 }
117- let t_name = self . cx . tcx . item_name ( trait_def_id) . to_string ( ) ;
118121 self . cx . tcx . for_each_relevant_impl ( trait_def_id, ty, |impl_def_id| {
119122 self . cx . tcx . infer_ctxt ( ) . enter ( |infcx| {
120123 let generics = infcx. tcx . generics_of ( impl_def_id) ;
@@ -124,7 +127,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
124127 :: rustc:: ty:: TypeVariants :: TyParam ( _) => true ,
125128 _ => false ,
126129 } {
127- return ;
130+ return
128131 }
129132
130133 let substs = infcx. fresh_substs_for_item ( DUMMY_SP , def_id) ;
@@ -147,38 +150,63 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
147150 param_env,
148151 trait_ref. to_predicate ( ) ,
149152 ) ) ;
150- if may_apply {
151- if traits. get ( & trait_def_id) . is_none ( ) {
152- let trait_ = hir:: TraitRef {
153- path : get_path_for_type ( infcx. tcx , trait_def_id, hir:: def:: Def :: Trait ) ,
154- ref_id : ast:: DUMMY_NODE_ID ,
155- } ;
156- let provided_trait_methods = infcx. tcx . provided_trait_methods ( impl_def_id)
157- . into_iter ( )
158- . map ( |meth| meth. ident . to_string ( ) )
159- . collect ( ) ;
160- traits. insert ( trait_def_id, Item {
161- source : Span :: empty ( ) ,
162- name : None ,
163- attrs : Default :: default ( ) ,
164- visibility : None ,
165- def_id : self . next_def_id ( impl_def_id. krate ) ,
166- stability : None ,
167- deprecation : None ,
168- inner : ImplItem ( Impl {
169- unsafety : hir:: Unsafety :: Normal ,
170- generics : ( generics,
171- & tcx. predicates_of ( impl_def_id) ) . clean ( self . cx ) ,
172- provided_trait_methods,
173- trait_ : Some ( trait_. clean ( self . cx ) ) ,
174- for_ : ty. clean ( self . cx ) ,
175- items : infcx. tcx . associated_items ( impl_def_id) . collect :: < Vec < _ > > ( ) . clean ( self . cx ) ,
176- polarity : None ,
177- synthetic : true ,
178- } ) ,
179- } ) ;
180- }
153+ if !may_apply {
154+ return
181155 }
156+ self . cx . generated_synthetics . borrow_mut ( )
157+ . insert ( ( def_id, trait_def_id) ) ;
158+ let trait_ = hir:: TraitRef {
159+ path : get_path_for_type ( infcx. tcx , trait_def_id, hir:: def:: Def :: Trait ) ,
160+ ref_id : ast:: DUMMY_NODE_ID ,
161+ } ;
162+ let provided_trait_methods = infcx. tcx . provided_trait_methods ( impl_def_id)
163+ . into_iter ( )
164+ . map ( |meth| meth. ident . to_string ( ) )
165+ . collect ( ) ;
166+
167+ let path = get_path_for_type ( self . cx . tcx , def_id, def_ctor) ;
168+ let mut segments = path. segments . into_vec ( ) ;
169+ let last = segments. pop ( ) . unwrap ( ) ;
170+
171+ segments. push ( hir:: PathSegment :: new (
172+ real_name. unwrap_or ( last. ident ) ,
173+ self . generics_to_path_params ( generics. clone ( ) ) ,
174+ false ,
175+ ) ) ;
176+
177+ let new_path = hir:: Path {
178+ span : path. span ,
179+ def : path. def ,
180+ segments : HirVec :: from_vec ( segments) ,
181+ } ;
182+
183+ let ty = hir:: Ty {
184+ id : ast:: DUMMY_NODE_ID ,
185+ node : hir:: Ty_ :: TyPath ( hir:: QPath :: Resolved ( None , P ( new_path) ) ) ,
186+ span : DUMMY_SP ,
187+ hir_id : hir:: DUMMY_HIR_ID ,
188+ } ;
189+
190+ traits. push ( Item {
191+ source : Span :: empty ( ) ,
192+ name : None ,
193+ attrs : Default :: default ( ) ,
194+ visibility : None ,
195+ def_id : self . next_def_id ( impl_def_id. krate ) ,
196+ stability : None ,
197+ deprecation : None ,
198+ inner : ImplItem ( Impl {
199+ unsafety : hir:: Unsafety :: Normal ,
200+ generics : ( generics,
201+ & tcx. predicates_of ( impl_def_id) ) . clean ( self . cx ) ,
202+ provided_trait_methods,
203+ trait_ : Some ( trait_. clean ( self . cx ) ) ,
204+ for_ : ty. clean ( self . cx ) ,
205+ items : infcx. tcx . associated_items ( impl_def_id) . collect :: < Vec < _ > > ( ) . clean ( self . cx ) ,
206+ polarity : None ,
207+ synthetic : true ,
208+ } ) ,
209+ } ) ;
182210 debug ! ( "{:?} => {}" , trait_ref, may_apply) ;
183211 }
184212 } ) ;
@@ -209,7 +237,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
209237 def_ctor,
210238 tcx. require_lang_item ( lang_items:: SyncTraitLangItem ) ,
211239 ) . into_iter ( ) )
212- . chain ( traits. into_iter ( ) . map ( | ( _ , v ) | v ) )
240+ . chain ( traits. into_iter ( ) )
213241 . collect ( ) ;
214242
215243 debug ! (
0 commit comments