@@ -373,10 +373,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
373
373
body. id( ) ,
374
374
call_site_scope
375
375
) ;
376
- let call_site_region = self . tcx . mk_region ( ty:: ReScope ( call_site_scope) ) ;
377
376
378
377
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 ) ;
380
379
381
380
self . constrain_opaque_types (
382
381
& self . fcx . opaque_types . borrow ( ) ,
@@ -434,10 +433,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
434
433
// that the lifetime of any regions that appear in a
435
434
// variable's type enclose at least the variable's scope.
436
435
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) ) ;
438
436
439
437
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 ) ;
441
439
442
440
let typ = self . resolve_node_type ( hir_id) ;
443
441
let body_id = self . body_id ;
@@ -520,14 +518,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
520
518
// scope of that expression. This also guarantees basic WF.
521
519
let expr_ty = self . resolve_node_type ( expr. hir_id ) ;
522
520
// the region corresponding to this expression
523
- let expr_region = self . tcx . mk_region ( ty :: ReScope ( region:: Scope {
521
+ let expr_scope = region:: Scope {
524
522
id : expr. hir_id . local_id ,
525
523
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 (
528
527
infer:: ExprTypeIsNotInScope ( expr_ty, expr. span ) ,
529
528
expr_ty,
530
- expr_region ,
529
+ expr_scope ,
531
530
) ;
532
531
533
532
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> {
546
545
} ;
547
546
548
547
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 ) ;
550
549
// Arguments (sub-expressions) are checked via `constrain_call`, below.
551
550
}
552
551
@@ -572,7 +571,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
572
571
hir:: ExprKind :: Path ( _) => {
573
572
let substs = self . tables . borrow ( ) . node_substs ( expr. hir_id ) ;
574
573
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 ) ;
576
575
}
577
576
578
577
hir:: ExprKind :: Call ( ref callee, ref args) => {
@@ -619,7 +618,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
619
618
let lhs_ty = self . resolve_expr_type_adjusted ( & lhs) ;
620
619
let rhs_ty = self . resolve_expr_type_adjusted ( & rhs) ;
621
620
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 ) ;
623
622
}
624
623
intravisit:: walk_expr ( self , expr) ;
625
624
}
@@ -674,7 +673,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
674
673
// FIXME(https://github.com/rust-lang/rfcs/issues/811)
675
674
// nested method calls requires that this rule change
676
675
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 ) ;
678
677
intravisit:: walk_expr ( self , expr) ;
679
678
}
680
679
@@ -705,16 +704,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
705
704
}
706
705
707
706
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 ( ) ;
709
708
debug ! (
710
709
"visit_expr ExprKind::Ret ret_expr.id {} call_site_scope: {:?}" ,
711
710
ret_expr. id, call_site_scope
712
711
) ;
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 (
715
713
infer:: CallReturn ( ret_expr. span ) ,
716
714
ret_expr. hir_id ,
717
- call_site_region ,
715
+ call_site_scope ,
718
716
) ;
719
717
intravisit:: walk_expr ( self , expr) ;
720
718
}
@@ -813,26 +811,25 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
813
811
id : call_expr. hir_id . local_id ,
814
812
data : region:: ScopeData :: Node ,
815
813
} ;
816
- let callee_region = self . tcx . mk_region ( ty:: ReScope ( callee_scope) ) ;
817
814
818
- debug ! ( "callee_region ={:?}" , callee_region ) ;
815
+ debug ! ( "callee_scope ={:?}" , callee_scope ) ;
819
816
820
817
for arg_expr in arg_exprs {
821
818
debug ! ( "Argument: {:?}" , arg_expr) ;
822
819
823
820
// ensure that any regions appearing in the argument type are
824
821
// 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 (
826
823
infer:: CallArg ( arg_expr. span ) ,
827
824
arg_expr. hir_id ,
828
- callee_region ,
825
+ callee_scope ,
829
826
) ;
830
827
}
831
828
832
829
// as loop above, but for receiver
833
830
if let Some ( r) = receiver {
834
831
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 ) ;
836
833
}
837
834
}
838
835
@@ -867,10 +864,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
867
864
// expression.
868
865
self . check_safety_of_rvalue_destructor_if_necessary ( & cmt, expr. span ) ;
869
866
870
- let expr_region = self . tcx . mk_region ( ty :: ReScope ( region:: Scope {
867
+ let expr_scope = region:: Scope {
871
868
id : expr. hir_id . local_id ,
872
869
data : region:: ScopeData :: Node ,
873
- } ) ) ;
870
+ } ;
871
+ let expr_region = self . tcx . mk_region ( ty:: ReScope ( expr_scope) ) ;
874
872
for adjustment in adjustments {
875
873
debug ! (
876
874
"constrain_adjustments: adjustment={:?}, cmt={:?}" ,
@@ -905,8 +903,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
905
903
) ;
906
904
907
905
// 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 ) ;
910
908
}
911
909
912
910
if let adjustment:: Adjust :: Borrow ( ref autoref) = adjustment. kind {
@@ -916,10 +914,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
916
914
// the current node.
917
915
//
918
916
// 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 (
920
918
infer:: AutoBorrow ( expr. span ) ,
921
919
expr. hir_id ,
922
- expr_region ,
920
+ expr_scope ,
923
921
) ;
924
922
}
925
923
@@ -999,13 +997,16 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
999
997
}
1000
998
}
1001
999
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 (
1005
1006
& mut self ,
1006
1007
origin : infer:: SubregionOrigin < ' tcx > ,
1007
1008
hir_id : hir:: HirId ,
1008
- minimum_lifetime : ty :: Region < ' tcx > ,
1009
+ scope : region :: Scope ,
1009
1010
) {
1010
1011
// Try to resolve the type. If we encounter an error, then typeck
1011
1012
// is going to fail anyway, so just stop here and let typeck
@@ -1021,10 +1022,26 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
1021
1022
let ty = self . resolve_type ( ty) ;
1022
1023
debug ! (
1023
1024
"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
1026
1027
) ;
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)
1028
1045
}
1029
1046
1030
1047
/// Adds constraints to inference such that `T: 'a` holds (or
@@ -1408,25 +1425,26 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
1408
1425
origin : infer:: ParameterOrigin ,
1409
1426
substs : & Substs < ' tcx > ,
1410
1427
expr_span : Span ,
1411
- expr_region : ty :: Region < ' tcx > ,
1428
+ expr_scope : region :: Scope ,
1412
1429
) {
1413
1430
debug ! (
1414
1431
"substs_wf_in_scope(substs={:?}, \
1415
- expr_region ={:?}, \
1432
+ expr_scope ={:?}, \
1416
1433
origin={:?}, \
1417
1434
expr_span={:?})",
1418
- substs, expr_region , origin, expr_span
1435
+ substs, expr_scope , origin, expr_span
1419
1436
) ;
1420
1437
1421
1438
let origin = infer:: ParameterInScope ( origin, expr_span) ;
1422
1439
1440
+ let expr_region = self . tcx . mk_region ( ty:: ReScope ( expr_scope) ) ;
1423
1441
for region in substs. regions ( ) {
1424
1442
self . sub_regions ( origin. clone ( ) , expr_region, region) ;
1425
1443
}
1426
1444
1427
1445
for ty in substs. types ( ) {
1428
1446
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 ) ;
1430
1448
}
1431
1449
}
1432
1450
}
0 commit comments