@@ -42,7 +42,9 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
4242use rustc_infer:: infer:: UpvarRegion ;
4343use rustc_middle:: hir:: place:: { Place , PlaceBase , PlaceWithHirId , Projection , ProjectionKind } ;
4444use rustc_middle:: mir:: FakeReadCause ;
45- use rustc_middle:: ty:: { self , ClosureSizeProfileData , Ty , TyCtxt , TypeckResults , UpvarSubsts } ;
45+ use rustc_middle:: ty:: {
46+ self , ClosureSizeProfileData , Ty , TyCtxt , TypeckResults , UpvarCapture , UpvarSubsts ,
47+ } ;
4648use rustc_session:: lint;
4749use rustc_span:: sym;
4850use rustc_span:: { MultiSpan , Span , Symbol } ;
@@ -299,13 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
299301 captured_place. place, upvar_ty, capture, captured_place. mutability,
300302 ) ;
301303
302- match capture {
303- ty:: UpvarCapture :: ByValue ( _) => upvar_ty,
304- ty:: UpvarCapture :: ByRef ( borrow) => self . tcx . mk_ref (
305- borrow. region ,
306- ty:: TypeAndMut { ty : upvar_ty, mutbl : borrow. kind . to_mutbl_lossy ( ) } ,
307- ) ,
308- }
304+ apply_capture_kind_on_capture_ty ( self . tcx , upvar_ty, capture)
309305 } )
310306 . collect ( )
311307 }
@@ -582,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
582578 min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
583579 var_hir_id : hir:: HirId ,
584580 check_trait : Option < DefId > ,
581+ closure_clause : hir:: CaptureBy ,
585582 ) -> bool {
586583 let root_var_min_capture_list = if let Some ( root_var_min_capture_list) =
587584 min_captures. and_then ( |m| m. get ( & var_hir_id) )
@@ -593,6 +590,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
593590
594591 let ty = self . infcx . resolve_vars_if_possible ( self . node_ty ( var_hir_id) ) ;
595592
593+ let ty = match closure_clause {
594+ hir:: CaptureBy :: Value => ty, // For move closure the capture kind should be by value
595+ hir:: CaptureBy :: Ref => {
596+ // For non move closure the capture kind is the max capture kind of all captures
597+ // according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue
598+ let mut max_capture_info = root_var_min_capture_list. first ( ) . unwrap ( ) . info ;
599+ for capture in root_var_min_capture_list. iter ( ) {
600+ max_capture_info = determine_capture_info ( max_capture_info, capture. info ) ;
601+ }
602+
603+ apply_capture_kind_on_capture_ty ( self . tcx , ty, max_capture_info. capture_kind )
604+ }
605+ } ;
606+
596607 let obligation_should_hold = check_trait
597608 . map ( |check_trait| {
598609 self . infcx
@@ -606,10 +617,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
606617 } )
607618 . unwrap_or ( false ) ;
608619
609- // Check whether catpured fields also implement the trait
610-
620+ // Check whether captured fields also implement the trait
611621 for capture in root_var_min_capture_list. iter ( ) {
612- let ty = capture. place . ty ( ) ;
622+ let ty = apply_capture_kind_on_capture_ty (
623+ self . tcx ,
624+ capture. place . ty ( ) ,
625+ capture. info . capture_kind ,
626+ ) ;
613627
614628 let obligation_holds_for_capture = check_trait
615629 . map ( |check_trait| {
@@ -645,6 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645659 & self ,
646660 min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
647661 var_hir_id : hir:: HirId ,
662+ closure_clause : hir:: CaptureBy ,
648663 ) -> Option < FxHashSet < & str > > {
649664 let tcx = self . infcx . tcx ;
650665
@@ -655,6 +670,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
655670 min_captures,
656671 var_hir_id,
657672 tcx. lang_items ( ) . clone_trait ( ) ,
673+ closure_clause,
658674 ) {
659675 auto_trait_reasons. insert ( "`Clone`" ) ;
660676 }
@@ -663,6 +679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663679 min_captures,
664680 var_hir_id,
665681 tcx. lang_items ( ) . sync_trait ( ) ,
682+ closure_clause,
666683 ) {
667684 auto_trait_reasons. insert ( "`Sync`" ) ;
668685 }
@@ -671,6 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
671688 min_captures,
672689 var_hir_id,
673690 tcx. get_diagnostic_item ( sym:: send_trait) ,
691+ closure_clause,
674692 ) {
675693 auto_trait_reasons. insert ( "`Send`" ) ;
676694 }
@@ -679,6 +697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679697 min_captures,
680698 var_hir_id,
681699 tcx. lang_items ( ) . unpin_trait ( ) ,
700+ closure_clause,
682701 ) {
683702 auto_trait_reasons. insert ( "`Unpin`" ) ;
684703 }
@@ -687,6 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
687706 min_captures,
688707 var_hir_id,
689708 tcx. get_diagnostic_item ( sym:: unwind_safe_trait) ,
709+ closure_clause,
690710 ) {
691711 auto_trait_reasons. insert ( "`UnwindSafe`" ) ;
692712 }
@@ -695,6 +715,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695715 min_captures,
696716 var_hir_id,
697717 tcx. get_diagnostic_item ( sym:: ref_unwind_safe_trait) ,
718+ closure_clause,
698719 ) {
699720 auto_trait_reasons. insert ( "`RefUnwindSafe`" ) ;
700721 }
@@ -814,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
814835 for ( & var_hir_id, _) in upvars. iter ( ) {
815836 let mut need_migration = false ;
816837 if let Some ( trait_migration_cause) =
817- self . compute_2229_migrations_for_trait ( min_captures, var_hir_id)
838+ self . compute_2229_migrations_for_trait ( min_captures, var_hir_id, closure_clause )
818839 {
819840 need_migration = true ;
820841 auto_trait_reasons. extend ( trait_migration_cause) ;
@@ -1286,6 +1307,19 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
12861307 place
12871308}
12881309
1310+ /// Returns a Ty that applies the specified capture kind on the provided capture Ty
1311+ fn apply_capture_kind_on_capture_ty (
1312+ tcx : TyCtxt < ' tcx > ,
1313+ ty : Ty < ' tcx > ,
1314+ capture_kind : UpvarCapture < ' tcx > ,
1315+ ) -> Ty < ' tcx > {
1316+ match capture_kind {
1317+ ty:: UpvarCapture :: ByValue ( _) => ty,
1318+ ty:: UpvarCapture :: ByRef ( borrow) => tcx
1319+ . mk_ref ( borrow. region , ty:: TypeAndMut { ty : ty, mutbl : borrow. kind . to_mutbl_lossy ( ) } ) ,
1320+ }
1321+ }
1322+
12891323struct InferBorrowKind < ' a , ' tcx > {
12901324 fcx : & ' a FnCtxt < ' a , ' tcx > ,
12911325
0 commit comments