@@ -42,7 +42,9 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
42
42
use rustc_infer:: infer:: UpvarRegion ;
43
43
use rustc_middle:: hir:: place:: { Place , PlaceBase , PlaceWithHirId , Projection , ProjectionKind } ;
44
44
use 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
+ } ;
46
48
use rustc_session:: lint;
47
49
use rustc_span:: sym;
48
50
use rustc_span:: { MultiSpan , Span , Symbol } ;
@@ -299,13 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
299
301
captured_place. place, upvar_ty, capture, captured_place. mutability,
300
302
) ;
301
303
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)
309
305
} )
310
306
. collect ( )
311
307
}
@@ -582,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
582
578
min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
583
579
var_hir_id : hir:: HirId ,
584
580
check_trait : Option < DefId > ,
581
+ closure_clause : hir:: CaptureBy ,
585
582
) -> bool {
586
583
let root_var_min_capture_list = if let Some ( root_var_min_capture_list) =
587
584
min_captures. and_then ( |m| m. get ( & var_hir_id) )
@@ -593,6 +590,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
593
590
594
591
let ty = self . infcx . resolve_vars_if_possible ( self . node_ty ( var_hir_id) ) ;
595
592
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
+
596
607
let obligation_should_hold = check_trait
597
608
. map ( |check_trait| {
598
609
self . infcx
@@ -606,10 +617,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
606
617
} )
607
618
. unwrap_or ( false ) ;
608
619
609
- // Check whether catpured fields also implement the trait
610
-
620
+ // Check whether captured fields also implement the trait
611
621
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
+ ) ;
613
627
614
628
let obligation_holds_for_capture = check_trait
615
629
. map ( |check_trait| {
@@ -645,6 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645
659
& self ,
646
660
min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
647
661
var_hir_id : hir:: HirId ,
662
+ closure_clause : hir:: CaptureBy ,
648
663
) -> Option < FxHashSet < & str > > {
649
664
let tcx = self . infcx . tcx ;
650
665
@@ -655,6 +670,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
655
670
min_captures,
656
671
var_hir_id,
657
672
tcx. lang_items ( ) . clone_trait ( ) ,
673
+ closure_clause,
658
674
) {
659
675
auto_trait_reasons. insert ( "`Clone`" ) ;
660
676
}
@@ -663,6 +679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663
679
min_captures,
664
680
var_hir_id,
665
681
tcx. lang_items ( ) . sync_trait ( ) ,
682
+ closure_clause,
666
683
) {
667
684
auto_trait_reasons. insert ( "`Sync`" ) ;
668
685
}
@@ -671,6 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
671
688
min_captures,
672
689
var_hir_id,
673
690
tcx. get_diagnostic_item ( sym:: send_trait) ,
691
+ closure_clause,
674
692
) {
675
693
auto_trait_reasons. insert ( "`Send`" ) ;
676
694
}
@@ -679,6 +697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679
697
min_captures,
680
698
var_hir_id,
681
699
tcx. lang_items ( ) . unpin_trait ( ) ,
700
+ closure_clause,
682
701
) {
683
702
auto_trait_reasons. insert ( "`Unpin`" ) ;
684
703
}
@@ -687,6 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
687
706
min_captures,
688
707
var_hir_id,
689
708
tcx. get_diagnostic_item ( sym:: unwind_safe_trait) ,
709
+ closure_clause,
690
710
) {
691
711
auto_trait_reasons. insert ( "`UnwindSafe`" ) ;
692
712
}
@@ -695,6 +715,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695
715
min_captures,
696
716
var_hir_id,
697
717
tcx. get_diagnostic_item ( sym:: ref_unwind_safe_trait) ,
718
+ closure_clause,
698
719
) {
699
720
auto_trait_reasons. insert ( "`RefUnwindSafe`" ) ;
700
721
}
@@ -814,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
814
835
for ( & var_hir_id, _) in upvars. iter ( ) {
815
836
let mut need_migration = false ;
816
837
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 )
818
839
{
819
840
need_migration = true ;
820
841
auto_trait_reasons. extend ( trait_migration_cause) ;
@@ -1286,6 +1307,19 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
1286
1307
place
1287
1308
}
1288
1309
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
+
1289
1323
struct InferBorrowKind < ' a , ' tcx > {
1290
1324
fcx : & ' a FnCtxt < ' a , ' tcx > ,
1291
1325
0 commit comments