@@ -373,10 +373,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
373373 body. id( ) ,
374374 call_site_scope
375375 ) ;
376- let call_site_region = self . tcx . mk_region ( ty:: ReScope ( call_site_scope) ) ;
377376
378377 let body_hir_id = self . tcx . hir . node_to_hir_id ( body_id. node_id ) ;
379- self . type_of_node_must_outlive ( infer:: CallReturn ( span) , body_hir_id, call_site_region ) ;
378+ self . type_of_node_must_be_valid_for_scope ( infer:: CallReturn ( span) , body_hir_id, call_site_scope ) ;
380379
381380 self . constrain_opaque_types (
382381 & self . fcx . opaque_types . borrow ( ) ,
@@ -434,10 +433,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
434433 // that the lifetime of any regions that appear in a
435434 // variable's type enclose at least the variable's scope.
436435 let var_scope = self . region_scope_tree . var_scope ( hir_id. local_id ) ;
437- let var_region = self . tcx . mk_region ( ty:: ReScope ( var_scope) ) ;
438436
439437 let origin = infer:: BindingTypeIsNotValidAtDecl ( span) ;
440- self . type_of_node_must_outlive ( origin, hir_id, var_region ) ;
438+ self . type_of_node_must_be_valid_for_scope ( origin, hir_id, var_scope ) ;
441439
442440 let typ = self . resolve_node_type ( hir_id) ;
443441 let body_id = self . body_id ;
@@ -520,14 +518,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
520518 // scope of that expression. This also guarantees basic WF.
521519 let expr_ty = self . resolve_node_type ( expr. hir_id ) ;
522520 // the region corresponding to this expression
523- let expr_region = self . tcx . mk_region ( ty :: ReScope ( region:: Scope {
521+ let expr_scope = region:: Scope {
524522 id : expr. hir_id . local_id ,
525523 data : region:: ScopeData :: Node ,
526- } ) ) ;
527- self . type_must_outlive (
524+ } ;
525+ let expr_region = self . tcx . mk_region ( ty:: ReScope ( expr_scope) ) ;
526+ self . type_must_be_valid_for_scope (
528527 infer:: ExprTypeIsNotInScope ( expr_ty, expr. span ) ,
529528 expr_ty,
530- expr_region ,
529+ expr_scope ,
531530 ) ;
532531
533532 let is_method_call = self . tables . borrow ( ) . is_method_call ( expr) ;
@@ -546,7 +545,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
546545 } ;
547546
548547 let substs = self . tables . borrow ( ) . node_substs ( expr. hir_id ) ;
549- self . substs_wf_in_scope ( origin, substs, expr. span , expr_region ) ;
548+ self . substs_wf_in_scope ( origin, substs, expr. span , expr_scope ) ;
550549 // Arguments (sub-expressions) are checked via `constrain_call`, below.
551550 }
552551
@@ -572,7 +571,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
572571 hir:: ExprKind :: Path ( _) => {
573572 let substs = self . tables . borrow ( ) . node_substs ( expr. hir_id ) ;
574573 let origin = infer:: ParameterOrigin :: Path ;
575- self . substs_wf_in_scope ( origin, substs, expr. span , expr_region ) ;
574+ self . substs_wf_in_scope ( origin, substs, expr. span , expr_scope ) ;
576575 }
577576
578577 hir:: ExprKind :: Call ( ref callee, ref args) => {
@@ -619,7 +618,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
619618 let lhs_ty = self . resolve_expr_type_adjusted ( & lhs) ;
620619 let rhs_ty = self . resolve_expr_type_adjusted ( & rhs) ;
621620 for & ty in & [ lhs_ty, rhs_ty] {
622- self . type_must_outlive ( infer:: Operand ( expr. span ) , ty, expr_region ) ;
621+ self . type_must_be_valid_for_scope ( infer:: Operand ( expr. span ) , ty, expr_scope ) ;
623622 }
624623 intravisit:: walk_expr ( self , expr) ;
625624 }
@@ -674,7 +673,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
674673 // FIXME(https://github.com/rust-lang/rfcs/issues/811)
675674 // nested method calls requires that this rule change
676675 let ty0 = self . resolve_node_type ( expr. hir_id ) ;
677- self . type_must_outlive ( infer:: AddrOf ( expr. span ) , ty0, expr_region ) ;
676+ self . type_must_be_valid_for_scope ( infer:: AddrOf ( expr. span ) , ty0, expr_scope ) ;
678677 intravisit:: walk_expr ( self , expr) ;
679678 }
680679
@@ -705,16 +704,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
705704 }
706705
707706 hir:: ExprKind :: Ret ( Some ( ref ret_expr) ) => {
708- let call_site_scope = self . call_site_scope ;
707+ let call_site_scope = self . call_site_scope . unwrap ( ) ;
709708 debug ! (
710709 "visit_expr ExprKind::Ret ret_expr.id {} call_site_scope: {:?}" ,
711710 ret_expr. id, call_site_scope
712711 ) ;
713- let call_site_region = self . tcx . mk_region ( ty:: ReScope ( call_site_scope. unwrap ( ) ) ) ;
714- self . type_of_node_must_outlive (
712+ self . type_of_node_must_be_valid_for_scope (
715713 infer:: CallReturn ( ret_expr. span ) ,
716714 ret_expr. hir_id ,
717- call_site_region ,
715+ call_site_scope ,
718716 ) ;
719717 intravisit:: walk_expr ( self , expr) ;
720718 }
@@ -813,26 +811,25 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
813811 id : call_expr. hir_id . local_id ,
814812 data : region:: ScopeData :: Node ,
815813 } ;
816- let callee_region = self . tcx . mk_region ( ty:: ReScope ( callee_scope) ) ;
817814
818- debug ! ( "callee_region ={:?}" , callee_region ) ;
815+ debug ! ( "callee_scope ={:?}" , callee_scope ) ;
819816
820817 for arg_expr in arg_exprs {
821818 debug ! ( "Argument: {:?}" , arg_expr) ;
822819
823820 // ensure that any regions appearing in the argument type are
824821 // valid for at least the lifetime of the function:
825- self . type_of_node_must_outlive (
822+ self . type_of_node_must_be_valid_for_scope (
826823 infer:: CallArg ( arg_expr. span ) ,
827824 arg_expr. hir_id ,
828- callee_region ,
825+ callee_scope ,
829826 ) ;
830827 }
831828
832829 // as loop above, but for receiver
833830 if let Some ( r) = receiver {
834831 debug ! ( "receiver: {:?}" , r) ;
835- self . type_of_node_must_outlive ( infer:: CallRcvr ( r. span ) , r. hir_id , callee_region ) ;
832+ self . type_of_node_must_be_valid_for_scope ( infer:: CallRcvr ( r. span ) , r. hir_id , callee_scope ) ;
836833 }
837834 }
838835
@@ -867,10 +864,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
867864 // expression.
868865 self . check_safety_of_rvalue_destructor_if_necessary ( & cmt, expr. span ) ;
869866
870- let expr_region = self . tcx . mk_region ( ty :: ReScope ( region:: Scope {
867+ let expr_scope = region:: Scope {
871868 id : expr. hir_id . local_id ,
872869 data : region:: ScopeData :: Node ,
873- } ) ) ;
870+ } ;
871+ let expr_region = self . tcx . mk_region ( ty:: ReScope ( expr_scope) ) ;
874872 for adjustment in adjustments {
875873 debug ! (
876874 "constrain_adjustments: adjustment={:?}, cmt={:?}" ,
@@ -905,8 +903,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
905903 ) ;
906904
907905 // Specialized version of constrain_call.
908- self . type_must_outlive ( infer:: CallRcvr ( expr. span ) , input, expr_region ) ;
909- self . type_must_outlive ( infer:: CallReturn ( expr. span ) , output, expr_region ) ;
906+ self . type_must_be_valid_for_scope ( infer:: CallRcvr ( expr. span ) , input, expr_scope ) ;
907+ self . type_must_be_valid_for_scope ( infer:: CallReturn ( expr. span ) , output, expr_scope ) ;
910908 }
911909
912910 if let adjustment:: Adjust :: Borrow ( ref autoref) = adjustment. kind {
@@ -916,10 +914,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
916914 // the current node.
917915 //
918916 // FIXME(#6268) remove to support nested method calls
919- self . type_of_node_must_outlive (
917+ self . type_of_node_must_be_valid_for_scope (
920918 infer:: AutoBorrow ( expr. span ) ,
921919 expr. hir_id ,
922- expr_region ,
920+ expr_scope ,
923921 ) ;
924922 }
925923
@@ -999,13 +997,16 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
999997 }
1000998 }
1001999
1002- /// Guarantees that any lifetimes which appear in the type of the node `id` (after applying
1003- /// adjustments) are valid for at least `minimum_lifetime`
1004- fn type_of_node_must_outlive (
1000+ /// Requires that all regions in the (fully adjusted) type of the
1001+ /// node `hir_id` are **valid** during the scope. This means that
1002+ /// they have to outlive `scope`. This implies `T: scope` but is
1003+ /// actually stronger than that in the case of projections. This
1004+ /// helps overcome some weakenesses in our inference (see #55756).
1005+ fn type_of_node_must_be_valid_for_scope (
10051006 & mut self ,
10061007 origin : infer:: SubregionOrigin < ' tcx > ,
10071008 hir_id : hir:: HirId ,
1008- minimum_lifetime : ty :: Region < ' tcx > ,
1009+ scope : region :: Scope ,
10091010 ) {
10101011 // Try to resolve the type. If we encounter an error, then typeck
10111012 // is going to fail anyway, so just stop here and let typeck
@@ -1021,10 +1022,26 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
10211022 let ty = self . resolve_type ( ty) ;
10221023 debug ! (
10231024 "constrain_regions_in_type_of_node(\
1024- ty={}, ty0={}, id={:?}, minimum_lifetime ={:?})",
1025- ty, ty0, hir_id, minimum_lifetime
1025+ ty={}, ty0={}, id={:?}, scope ={:?})",
1026+ ty, ty0, hir_id, scope
10261027 ) ;
1027- self . type_must_outlive ( origin, ty, minimum_lifetime) ;
1028+
1029+ self . type_must_be_valid_for_scope ( origin, ty, scope)
1030+ }
1031+
1032+ /// Requires that all regions in the type `T` are **valid** during
1033+ /// the scope. This means that they have to outlive `scope`. This
1034+ /// implies `T: scope` but is actually stronger than that in the
1035+ /// case of projections. This helps overcome some weakenesses in
1036+ /// our inference (see #55756).
1037+ pub fn type_must_be_valid_for_scope (
1038+ & self ,
1039+ origin : infer:: SubregionOrigin < ' tcx > ,
1040+ ty : Ty < ' tcx > ,
1041+ scope : region:: Scope ,
1042+ ) {
1043+ let region = self . tcx . mk_region ( ty:: ReScope ( scope) ) ;
1044+ self . type_must_outlive ( origin, ty, region)
10281045 }
10291046
10301047 /// Adds constraints to inference such that `T: 'a` holds (or
@@ -1408,25 +1425,26 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
14081425 origin : infer:: ParameterOrigin ,
14091426 substs : & Substs < ' tcx > ,
14101427 expr_span : Span ,
1411- expr_region : ty :: Region < ' tcx > ,
1428+ expr_scope : region :: Scope ,
14121429 ) {
14131430 debug ! (
14141431 "substs_wf_in_scope(substs={:?}, \
1415- expr_region ={:?}, \
1432+ expr_scope ={:?}, \
14161433 origin={:?}, \
14171434 expr_span={:?})",
1418- substs, expr_region , origin, expr_span
1435+ substs, expr_scope , origin, expr_span
14191436 ) ;
14201437
14211438 let origin = infer:: ParameterInScope ( origin, expr_span) ;
14221439
1440+ let expr_region = self . tcx . mk_region ( ty:: ReScope ( expr_scope) ) ;
14231441 for region in substs. regions ( ) {
14241442 self . sub_regions ( origin. clone ( ) , expr_region, region) ;
14251443 }
14261444
14271445 for ty in substs. types ( ) {
14281446 let ty = self . resolve_type ( ty) ;
1429- self . type_must_outlive ( origin. clone ( ) , ty, expr_region ) ;
1447+ self . type_must_be_valid_for_scope ( origin. clone ( ) , ty, expr_scope ) ;
14301448 }
14311449 }
14321450}
0 commit comments