@@ -666,14 +666,23 @@ fn check_expr_fn_block(rcx: &mut Rcx,
666
666
} ) ;
667
667
}
668
668
ty:: ty_unboxed_closure( _, region) => {
669
+ debug ! ( "regionck: constraining region of unboxed closure" ) ;
669
670
freevars:: with_freevars ( tcx, expr. id , |freevars| {
670
- // No free variables means that there is no environment and
671
- // hence the closure has static lifetime. Otherwise, the
672
- // closure must not outlive the variables it closes over
673
- // by-reference.
674
- if !freevars. is_empty ( ) {
675
- constrain_free_variables ( rcx, region, expr, freevars) ;
676
- }
671
+ if freevars. is_empty ( ) {
672
+ // No free variables means that there is no
673
+ // environment and hence the closure has static
674
+ // lifetime. Otherwise, the closure must not outlive
675
+ // the variables it closes over by-reference.
676
+ rcx. fcx . mk_subr ( false ,
677
+ infer:: MiscRegion ( expr. span ) ,
678
+ ty:: ReStatic ,
679
+ region) ;
680
+ } else {
681
+ constrain_free_variables ( rcx,
682
+ region,
683
+ expr,
684
+ freevars) ;
685
+ }
677
686
} )
678
687
}
679
688
_ => ( )
@@ -709,36 +718,79 @@ fn check_expr_fn_block(rcx: &mut Rcx,
709
718
let infcx = rcx. fcx . infcx ( ) ;
710
719
debug ! ( "constrain_free_variables({}, {})" ,
711
720
region. repr( tcx) , expr. repr( tcx) ) ;
721
+ let capture_mode = freevars:: get_capture_mode ( tcx, expr. id ) ;
722
+ let mut all_static = capture_mode == freevars:: CaptureByValue ;
712
723
for freevar in freevars. iter ( ) {
713
724
debug ! ( "freevar def is {:?}" , freevar. def) ;
714
725
715
726
// Identify the variable being closed over and its node-id.
716
727
let def = freevar. def ;
717
728
let def_id = def. def_id ( ) ;
718
729
assert ! ( def_id. krate == ast:: LOCAL_CRATE ) ;
719
- let upvar_id = ty:: UpvarId { var_id : def_id. node ,
720
- closure_expr_id : expr. id } ;
721
-
722
- // Create a region variable to represent this borrow. This borrow
723
- // must outlive the region on the closure.
724
- let origin = infer:: UpvarRegion ( upvar_id, expr. span ) ;
725
- let freevar_region = infcx. next_region_var ( origin) ;
726
- rcx. fcx . mk_subr ( true , infer:: FreeVariable ( freevar. span , def_id. node ) ,
727
- region, freevar_region) ;
728
-
729
- // Create a UpvarBorrow entry. Note that we begin with a
730
- // const borrow_kind, but change it to either mut or
731
- // immutable as dictated by the uses.
732
- let upvar_borrow = ty:: UpvarBorrow { kind : ty:: ImmBorrow ,
733
- region : freevar_region } ;
734
- rcx. fcx . inh . upvar_borrow_map . borrow_mut ( ) . insert ( upvar_id,
735
- upvar_borrow) ;
736
-
737
- // Guarantee that the closure does not outlive the variable itself.
738
- let en_region = region_of_def ( rcx. fcx , def) ;
739
- debug ! ( "en_region = {}" , en_region. repr( tcx) ) ;
740
- rcx. fcx . mk_subr ( true , infer:: FreeVariable ( freevar. span , def_id. node ) ,
741
- region, en_region) ;
730
+ let upvar_id = ty:: UpvarId {
731
+ var_id : def_id. node ,
732
+ closure_expr_id : expr. id ,
733
+ } ;
734
+
735
+ if capture_mode == freevars:: CaptureByRef {
736
+ // Create a region variable to represent this borrow. This
737
+ // borrow must outlive the region on the closure.
738
+ let origin = infer:: UpvarRegion ( upvar_id, expr. span ) ;
739
+ let freevar_region = infcx. next_region_var ( origin) ;
740
+ rcx. fcx . mk_subr ( true ,
741
+ infer:: FreeVariable ( freevar. span ,
742
+ def_id. node ) ,
743
+ region,
744
+ freevar_region) ;
745
+
746
+ // Create a UpvarBorrow entry. Note that we begin with a
747
+ // const borrow_kind, but change it to either mut or
748
+ // immutable as dictated by the uses.
749
+ let upvar_borrow = ty:: UpvarBorrow {
750
+ kind : ty:: ImmBorrow ,
751
+ region : freevar_region,
752
+ } ;
753
+ rcx. fcx
754
+ . inh
755
+ . upvar_borrow_map
756
+ . borrow_mut ( )
757
+ . insert ( upvar_id, upvar_borrow) ;
758
+
759
+ // Guarantee that the closure does not outlive the variable
760
+ // itself.
761
+ let en_region = region_of_def ( rcx. fcx , def) ;
762
+ debug ! ( "en_region = {}" , en_region. repr( tcx) ) ;
763
+ rcx. fcx . mk_subr ( true ,
764
+ infer:: FreeVariable ( freevar. span ,
765
+ def_id. node ) ,
766
+ region,
767
+ en_region) ;
768
+ }
769
+
770
+ // FIXME(pcwalton): As a hack, if the type of the variable being
771
+ // closed over has no regions and this is a by-value capture,
772
+ // record a `'static` bound.
773
+ let local_type = rcx. fcx . local_ty ( freevar. span , def_id. node ) ;
774
+ let local_type =
775
+ rcx. fcx . infcx ( ) . resolve_type_vars_if_possible ( local_type) ;
776
+ if all_static && !ty:: type_is_static ( rcx. tcx ( ) , local_type) {
777
+ debug ! ( "regionck: not static: {}" ,
778
+ rcx. fcx
779
+ . local_ty( freevar. span, def_id. node)
780
+ . repr( rcx. tcx( ) ) ) ;
781
+ all_static = false
782
+ }
783
+ }
784
+
785
+ // FIXME(pcwalton): As a hack, if the type of the variable being
786
+ // closed over has no regions and this is a by-value capture,
787
+ // record a `'static` bound.
788
+ if all_static {
789
+ debug ! ( "regionck: all static!" ) ;
790
+ rcx. fcx . mk_subr ( false ,
791
+ infer:: MiscRegion ( expr. span ) ,
792
+ ty:: ReStatic ,
793
+ region) ;
742
794
}
743
795
}
744
796
@@ -1022,9 +1074,14 @@ fn constrain_regions_in_type_of_node(
1022
1074
rcx. fcx . inh . adjustments . borrow ( ) . find ( & id) ,
1023
1075
|method_call| rcx. resolve_method_type ( method_call) ) ;
1024
1076
debug ! ( "constrain_regions_in_type_of_node(\
1025
- ty={}, ty0={}, id={}, minimum_lifetime={:?})",
1077
+ ty={},\
1078
+ ty0={},\
1079
+ id={},\
1080
+ minimum_lifetime={:?},\
1081
+ origin={:?})",
1026
1082
ty_to_string( tcx, ty) , ty_to_string( tcx, ty0) ,
1027
- id, minimum_lifetime) ;
1083
+ id, minimum_lifetime,
1084
+ origin) ;
1028
1085
constrain_regions_in_type ( rcx, minimum_lifetime, origin, ty) ;
1029
1086
}
1030
1087
0 commit comments