@@ -105,16 +105,19 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
105
105
let generics = self . cx . tcx . generics_of ( def_id) ;
106
106
107
107
let ty = self . cx . tcx . type_of ( def_id) ;
108
- let mut traits = FxHashMap ( ) ;
108
+ let mut traits = Vec :: new ( ) ;
109
109
if self . cx . crate_name != Some ( "core" . to_string ( ) ) {
110
110
if let ty:: TyAdt ( _adt, _) = ty. sty {
111
+ let real_name = name. clone ( ) . map ( |name| Ident :: from_str ( & name) ) ;
111
112
let param_env = self . cx . tcx . param_env ( def_id) ;
112
113
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 ( ) {
115
119
continue
116
120
}
117
- let t_name = self . cx . tcx . item_name ( trait_def_id) . to_string ( ) ;
118
121
self . cx . tcx . for_each_relevant_impl ( trait_def_id, ty, |impl_def_id| {
119
122
self . cx . tcx . infer_ctxt ( ) . enter ( |infcx| {
120
123
let generics = infcx. tcx . generics_of ( impl_def_id) ;
@@ -124,7 +127,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
124
127
:: rustc:: ty:: TypeVariants :: TyParam ( _) => true ,
125
128
_ => false ,
126
129
} {
127
- return ;
130
+ return
128
131
}
129
132
130
133
let substs = infcx. fresh_substs_for_item ( DUMMY_SP , def_id) ;
@@ -147,38 +150,63 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
147
150
param_env,
148
151
trait_ref. to_predicate ( ) ,
149
152
) ) ;
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
181
155
}
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
+ } ) ;
182
210
debug ! ( "{:?} => {}" , trait_ref, may_apply) ;
183
211
}
184
212
} ) ;
@@ -209,7 +237,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
209
237
def_ctor,
210
238
tcx. require_lang_item ( lang_items:: SyncTraitLangItem ) ,
211
239
) . into_iter ( ) )
212
- . chain ( traits. into_iter ( ) . map ( | ( _ , v ) | v ) )
240
+ . chain ( traits. into_iter ( ) )
213
241
. collect ( ) ;
214
242
215
243
debug ! (
0 commit comments