@@ -12,9 +12,7 @@ use rustc_middle::mir::{
1212 FakeReadCause , LocalDecl , LocalInfo , LocalKind , Location , Operand , Place , PlaceRef ,
1313 ProjectionElem , Rvalue , Statement , StatementKind , Terminator , TerminatorKind , VarBindingForm ,
1414} ;
15- use rustc_middle:: ty:: {
16- self , suggest_constraining_type_param, suggest_constraining_type_params, PredicateKind , Ty ,
17- } ;
15+ use rustc_middle:: ty:: { self , suggest_constraining_type_params, PredicateKind , Ty } ;
1816use rustc_mir_dataflow:: move_paths:: { InitKind , MoveOutIndex , MovePathIndex } ;
1917use rustc_span:: symbol:: sym;
2018use rustc_span:: { BytePos , MultiSpan , Span } ;
@@ -285,86 +283,63 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
285283 Some ( ref name) => format ! ( "`{}`" , name) ,
286284 None => "value" . to_owned ( ) ,
287285 } ;
288- if let ty:: Param ( param_ty) = ty. kind ( ) {
289- let tcx = self . infcx . tcx ;
290- let generics = tcx. generics_of ( self . mir_def_id ( ) ) ;
291- let param = generics. type_param ( & param_ty, tcx) ;
292- if let Some ( 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- suggest_constraining_type_param (
298- tcx,
299- generics,
300- & mut err,
301- param. name . as_str ( ) ,
302- "Copy" ,
303- None ,
286+
287+ // Try to find predicates on *generic params* that would allow copying `ty`
288+ let tcx = self . infcx . tcx ;
289+ let generics = tcx. generics_of ( self . mir_def_id ( ) ) ;
290+ if let Some ( hir_generics) = tcx
291+ . typeck_root_def_id ( self . mir_def_id ( ) . to_def_id ( ) )
292+ . as_local ( )
293+ . and_then ( |def_id| tcx. hir ( ) . get_generics ( def_id) )
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 ,
304304 ) ;
305- }
306- } else {
307- // Try to find predicates on *generic params* that would allow copying `ty`
308-
309- let tcx = self . infcx . tcx ;
310- let generics = tcx. generics_of ( self . mir_def_id ( ) ) ;
311- if let Some ( hir_generics) = tcx
312- . typeck_root_def_id ( self . mir_def_id ( ) . to_def_id ( ) )
313- . as_local ( )
314- . and_then ( |def_id| tcx. hir ( ) . get_generics ( def_id) )
315- {
316- let predicates: Result < Vec < _ > , _ > = tcx. infer_ctxt ( ) . enter ( |infcx| {
317- let mut fulfill_cx =
318- <dyn rustc_infer:: traits:: TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
319-
320- let copy_did = infcx. tcx . lang_items ( ) . copy_trait ( ) . unwrap ( ) ;
321- let cause = ObligationCause :: new (
322- span,
323- self . mir_hir_id ( ) ,
324- rustc_infer:: traits:: ObligationCauseCode :: MiscObligation ,
325- ) ;
326- fulfill_cx. register_bound (
327- & infcx,
328- self . param_env ,
329- // Erase any region vids from the type, which may not be resolved
330- infcx. tcx . erase_regions ( ty) ,
331- copy_did,
332- cause,
333- ) ;
334- // Select all, including ambiguous predicates
335- let errors = fulfill_cx. select_all_or_error ( & infcx) ;
336-
337- // Only emit suggestion if all required predicates are on generic
338- errors
339- . into_iter ( )
340- . map ( |err| match err. obligation . predicate . kind ( ) . skip_binder ( ) {
341- PredicateKind :: Trait ( predicate) => {
342- match predicate. self_ty ( ) . kind ( ) {
343- ty:: Param ( param_ty) => Ok ( (
344- generics. type_param ( param_ty, tcx) ,
345- predicate
346- . trait_ref
347- . print_only_trait_path ( )
348- . to_string ( ) ,
349- ) ) ,
350- _ => Err ( ( ) ) ,
351- }
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 ( ( ) ) ,
352327 }
353- _ => Err ( ( ) ) ,
354- } )
355- . collect ( )
356- } ) ;
328+ }
329+ _ => Err ( ( ) ) ,
330+ } )
331+ . collect ( )
332+ } ) ;
357333
358- if let Ok ( predicates) = predicates {
359- suggest_constraining_type_params (
360- tcx,
361- hir_generics,
362- & mut err,
363- predicates. iter ( ) . map ( |( param, constraint) | {
364- ( param. name . as_str ( ) , & * * constraint, None )
365- } ) ,
366- ) ;
367- }
334+ if let Ok ( predicates) = predicates {
335+ suggest_constraining_type_params (
336+ tcx,
337+ hir_generics,
338+ & mut err,
339+ predicates. iter ( ) . map ( |( param, constraint) | {
340+ ( param. name . as_str ( ) , & * * constraint, None )
341+ } ) ,
342+ ) ;
368343 }
369344 }
370345
0 commit comments