@@ -292,44 +292,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
292
292
. as_local ( )
293
293
. and_then ( |def_id| tcx. hir ( ) . get_generics ( def_id) )
294
294
{
295
- let predicates: Result < Vec < _ > , _ > = tcx. infer_ctxt ( ) . enter ( |infcx| {
296
- let mut fulfill_cx =
297
- <dyn rustc_infer:: traits:: TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
298
-
299
- let copy_did = infcx. tcx . lang_items ( ) . copy_trait ( ) . unwrap ( ) ;
300
- let cause = ObligationCause :: new (
301
- span,
302
- self . mir_hir_id ( ) ,
303
- rustc_infer:: traits:: ObligationCauseCode :: MiscObligation ,
304
- ) ;
305
- fulfill_cx. register_bound (
306
- & infcx,
307
- self . param_env ,
308
- // Erase any region vids from the type, which may not be resolved
309
- infcx. tcx . erase_regions ( ty) ,
310
- copy_did,
311
- cause,
312
- ) ;
313
- // Select all, including ambiguous predicates
314
- let errors = fulfill_cx. select_all_or_error ( & infcx) ;
315
-
316
- // Only emit suggestion if all required predicates are on generic
317
- errors
318
- . into_iter ( )
319
- . map ( |err| match err. obligation . predicate . kind ( ) . skip_binder ( ) {
320
- PredicateKind :: Trait ( predicate) => {
321
- match predicate. self_ty ( ) . kind ( ) {
322
- ty:: Param ( param_ty) => Ok ( (
323
- generics. type_param ( param_ty, tcx) ,
324
- predicate. trait_ref . print_only_trait_path ( ) . to_string ( ) ,
325
- ) ) ,
326
- _ => Err ( ( ) ) ,
327
- }
328
- }
329
- _ => Err ( ( ) ) ,
330
- } )
331
- . collect ( )
332
- } ) ;
295
+ let copy_did = tcx. lang_items ( ) . copy_trait ( ) . unwrap ( ) ;
296
+ let predicates =
297
+ self . try_find_missing_generic_bounds ( ty, copy_did, generics, span) ;
333
298
334
299
if let Ok ( predicates) = predicates {
335
300
suggest_constraining_type_params (
@@ -2256,6 +2221,53 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
2256
2221
}
2257
2222
}
2258
2223
}
2224
+
2225
+ /// Tries to find bounds on `generics` that satisfy `ty: required_trait_did` bound.
2226
+ fn try_find_missing_generic_bounds (
2227
+ & self ,
2228
+ ty : Ty < ' tcx > ,
2229
+ required_trait_did : DefId ,
2230
+ generics : & ' tcx ty:: Generics ,
2231
+ obligation_cause_span : Span ,
2232
+ ) -> Result < Vec < ( & ' tcx ty:: GenericParamDef , String ) > , ( ) > {
2233
+ let tcx = self . infcx . tcx ;
2234
+ let predicates: Result < Vec < _ > , _ > = tcx. infer_ctxt ( ) . enter ( |infcx| {
2235
+ let mut fulfill_cx = <dyn rustc_infer:: traits:: TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
2236
+
2237
+ let cause = ObligationCause :: new (
2238
+ obligation_cause_span,
2239
+ self . mir_hir_id ( ) ,
2240
+ rustc_infer:: traits:: ObligationCauseCode :: MiscObligation ,
2241
+ ) ;
2242
+ fulfill_cx. register_bound (
2243
+ & infcx,
2244
+ self . param_env ,
2245
+ // Erase any region vids from the type, which may not be resolved
2246
+ infcx. tcx . erase_regions ( ty) ,
2247
+ required_trait_did,
2248
+ cause,
2249
+ ) ;
2250
+ // Select all, including ambiguous predicates
2251
+ let errors = fulfill_cx. select_all_or_error ( & infcx) ;
2252
+
2253
+ // Only emit suggestion if all required predicates are on generic
2254
+ errors
2255
+ . into_iter ( )
2256
+ . map ( |err| match err. obligation . predicate . kind ( ) . skip_binder ( ) {
2257
+ PredicateKind :: Trait ( predicate) => match predicate. self_ty ( ) . kind ( ) {
2258
+ ty:: Param ( param_ty) => Ok ( (
2259
+ generics. type_param ( param_ty, tcx) ,
2260
+ predicate. trait_ref . print_only_trait_path ( ) . to_string ( ) ,
2261
+ ) ) ,
2262
+ _ => Err ( ( ) ) ,
2263
+ } ,
2264
+ _ => Err ( ( ) ) ,
2265
+ } )
2266
+ . collect ( )
2267
+ } ) ;
2268
+
2269
+ predicates
2270
+ }
2259
2271
}
2260
2272
2261
2273
#[ derive( Debug ) ]
0 commit comments