@@ -151,6 +151,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
151
151
. args_or_use ( )
152
152
} )
153
153
. collect :: < Vec < Span > > ( ) ;
154
+
154
155
let reinits = maybe_reinitialized_locations. len ( ) ;
155
156
if reinits == 1 {
156
157
err. span_label ( reinit_spans[ 0 ] , "this reinitialization might get skipped" ) ;
@@ -282,69 +283,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
282
283
Some ( ref name) => format ! ( "`{}`" , name) ,
283
284
None => "value" . to_owned ( ) ,
284
285
} ;
285
-
286
- let tcx = self . infcx . tcx ;
287
- let generics = tcx. generics_of ( self . mir_def_id ( ) ) ;
288
-
289
286
if self . suggest_borrow_fn_like ( & mut err, ty, & move_site_vec, & note_msg) {
290
287
// Suppress the next note, since we don't want to put more `Fn`-like bounds onto something that already has them
291
288
} else if needs_note {
292
- if let Some ( hir_generics) = tcx
293
- . typeck_root_def_id ( self . mir_def_id ( ) . to_def_id ( ) )
294
- . as_local ( )
295
- . and_then ( |def_id| tcx. hir ( ) . get_generics ( def_id) )
296
- {
297
- // Try to find predicates on *generic params* that would allow copying `ty`
298
- let predicates: Result < Vec < _ > , _ > = tcx. infer_ctxt ( ) . enter ( |infcx| {
299
- let mut fulfill_cx =
300
- <dyn rustc_infer:: traits:: TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
301
-
302
- let copy_did = infcx. tcx . lang_items ( ) . copy_trait ( ) . unwrap ( ) ;
303
- let cause = ObligationCause :: new (
304
- span,
305
- self . mir_hir_id ( ) ,
306
- rustc_infer:: traits:: ObligationCauseCode :: MiscObligation ,
307
- ) ;
308
- fulfill_cx. register_bound (
309
- & infcx,
310
- self . param_env ,
311
- // Erase any region vids from the type, which may not be resolved
312
- infcx. tcx . erase_regions ( ty) ,
313
- copy_did,
314
- cause,
315
- ) ;
316
- // Select all, including ambiguous predicates
317
- let errors = fulfill_cx. select_all_or_error ( & infcx) ;
318
-
319
- // Only emit suggestion if all required predicates are on generic
320
- errors
321
- . into_iter ( )
322
- . map ( |err| match err. obligation . predicate . kind ( ) . skip_binder ( ) {
323
- PredicateKind :: Trait ( predicate) => {
324
- match predicate. self_ty ( ) . kind ( ) {
325
- ty:: Param ( param_ty) => Ok ( (
326
- generics. type_param ( param_ty, tcx) ,
327
- predicate. trait_ref . print_only_trait_path ( ) . to_string ( ) ,
328
- ) ) ,
329
- _ => Err ( ( ) ) ,
330
- }
331
- }
332
- _ => Err ( ( ) ) ,
333
- } )
334
- . collect ( )
335
- } ) ;
336
-
337
- if let Ok ( predicates) = predicates {
338
- suggest_constraining_type_params (
339
- tcx,
340
- hir_generics,
341
- & mut err,
342
- predicates. iter ( ) . map ( |( param, constraint) | {
343
- ( param. name . as_str ( ) , & * * constraint, None )
344
- } ) ,
345
- ) ;
346
- }
347
- }
289
+ self . suggest_adding_copy_bounds ( & mut err, ty, span) ;
348
290
349
291
let span = if let Some ( local) = place. as_local ( ) {
350
292
Some ( self . body . local_decls [ local] . source_info . span )
@@ -450,6 +392,69 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
450
392
true
451
393
}
452
394
395
+ fn suggest_adding_copy_bounds (
396
+ & self ,
397
+ err : & mut DiagnosticBuilder < ' tcx , ErrorGuaranteed > ,
398
+ ty : Ty < ' tcx > ,
399
+ span : Span ,
400
+ ) {
401
+ let tcx = self . infcx . tcx ;
402
+ let generics = tcx. generics_of ( self . mir_def_id ( ) ) ;
403
+
404
+ let Some ( hir_generics) = tcx
405
+ . typeck_root_def_id ( self . mir_def_id ( ) . to_def_id ( ) )
406
+ . as_local ( )
407
+ . and_then ( |def_id| tcx. hir ( ) . get_generics ( def_id) )
408
+ else { return ; } ;
409
+ // Try to find predicates on *generic params* that would allow copying `ty`
410
+ let predicates: Result < Vec < _ > , _ > = tcx. infer_ctxt ( ) . enter ( |infcx| {
411
+ let mut fulfill_cx = <dyn rustc_infer:: traits:: TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
412
+
413
+ let copy_did = infcx. tcx . lang_items ( ) . copy_trait ( ) . unwrap ( ) ;
414
+ let cause = ObligationCause :: new (
415
+ span,
416
+ self . mir_hir_id ( ) ,
417
+ rustc_infer:: traits:: ObligationCauseCode :: MiscObligation ,
418
+ ) ;
419
+ fulfill_cx. register_bound (
420
+ & infcx,
421
+ self . param_env ,
422
+ // Erase any region vids from the type, which may not be resolved
423
+ infcx. tcx . erase_regions ( ty) ,
424
+ copy_did,
425
+ cause,
426
+ ) ;
427
+ // Select all, including ambiguous predicates
428
+ let errors = fulfill_cx. select_all_or_error ( & infcx) ;
429
+
430
+ // Only emit suggestion if all required predicates are on generic
431
+ errors
432
+ . into_iter ( )
433
+ . map ( |err| match err. obligation . predicate . kind ( ) . skip_binder ( ) {
434
+ PredicateKind :: Trait ( predicate) => match predicate. self_ty ( ) . kind ( ) {
435
+ ty:: Param ( param_ty) => Ok ( (
436
+ generics. type_param ( param_ty, tcx) ,
437
+ predicate. trait_ref . print_only_trait_path ( ) . to_string ( ) ,
438
+ ) ) ,
439
+ _ => Err ( ( ) ) ,
440
+ } ,
441
+ _ => Err ( ( ) ) ,
442
+ } )
443
+ . collect ( )
444
+ } ) ;
445
+
446
+ if let Ok ( predicates) = predicates {
447
+ suggest_constraining_type_params (
448
+ tcx,
449
+ hir_generics,
450
+ err,
451
+ predicates
452
+ . iter ( )
453
+ . map ( |( param, constraint) | ( param. name . as_str ( ) , & * * constraint, None ) ) ,
454
+ ) ;
455
+ }
456
+ }
457
+
453
458
pub ( crate ) fn report_move_out_while_borrowed (
454
459
& mut self ,
455
460
location : Location ,
0 commit comments