@@ -29,11 +29,10 @@ use rustc::util::common;
29
29
use rustc_data_structures:: graph:: scc:: Sccs ;
30
30
use rustc_data_structures:: indexed_set:: IdxSet ;
31
31
use rustc_data_structures:: indexed_vec:: IndexVec ;
32
- use rustc_errors:: Diagnostic ;
32
+ use rustc_errors:: { DiagnosticBuilder , Diagnostic } ;
33
33
34
34
use std:: rc:: Rc ;
35
35
36
- mod annotation;
37
36
mod dump_mir;
38
37
mod error_reporting;
39
38
mod graphviz;
@@ -359,6 +358,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
359
358
self . universal_regions . to_region_vid ( r)
360
359
}
361
360
361
+ /// Add annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
362
+ crate fn annotate ( & self , tcx : TyCtxt < ' _ , ' _ , ' tcx > , err : & mut DiagnosticBuilder < ' _ > ) {
363
+ self . universal_regions . annotate ( tcx, err)
364
+ }
365
+
362
366
/// Returns true if the region `r` contains the point `p`.
363
367
///
364
368
/// Panics if called before `solve()` executes,
@@ -686,7 +690,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
686
690
test : _,
687
691
} = type_test;
688
692
689
-
690
693
let generic_ty = generic_kind. to_ty ( tcx) ;
691
694
let subject = match self . try_promote_type_test_subject ( infcx, generic_ty) {
692
695
Some ( s) => s,
@@ -698,20 +701,38 @@ impl<'tcx> RegionInferenceContext<'tcx> {
698
701
// `ClosureOutlivesRequirement`.
699
702
let r_scc = self . constraint_sccs . scc ( * lower_bound) ;
700
703
for ur in self . scc_values . universal_regions_outlived_by ( r_scc) {
704
+ // Check whether we can already prove that the "subject" outlives `ur`.
705
+ // If so, we don't have to propagate this requirement to our caller.
706
+ //
707
+ // To continue the example from the function, if we are trying to promote
708
+ // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
709
+ // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
710
+ // we check whether `T: '1` is something we *can* prove. If so, no need
711
+ // to propagate that requirement.
712
+ //
713
+ // This is needed because -- particularly in the case
714
+ // where `ur` is a local bound -- we are sometimes in a
715
+ // position to prove things that our caller cannot. See
716
+ // #53570 for an example.
717
+ if self . eval_region_test ( mir, ur, & type_test. test ) {
718
+ continue ;
719
+ }
720
+
721
+ debug ! ( "try_promote_type_test: ur={:?}" , ur) ;
722
+
701
723
let non_local_ub = self . universal_region_relations . non_local_upper_bound ( ur) ;
724
+ debug ! ( "try_promote_type_test: non_local_ub={:?}" , non_local_ub) ;
702
725
703
726
assert ! ( self . universal_regions. is_universal_region( non_local_ub) ) ;
704
- assert ! (
705
- !self
706
- . universal_regions
707
- . is_local_free_region( non_local_ub)
708
- ) ;
727
+ assert ! ( !self . universal_regions. is_local_free_region( non_local_ub) ) ;
709
728
710
- propagated_outlives_requirements . push ( ClosureOutlivesRequirement {
729
+ let requirement = ClosureOutlivesRequirement {
711
730
subject,
712
731
outlived_free_region : non_local_ub,
713
732
blame_span : locations. span ( mir) ,
714
- } ) ;
733
+ } ;
734
+ debug ! ( "try_promote_type_test: pushing {:#?}" , requirement) ;
735
+ propagated_outlives_requirements. push ( requirement) ;
715
736
}
716
737
true
717
738
}
@@ -917,8 +938,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
917
938
// now). Therefore, the sup-region outlives the sub-region if,
918
939
// for each universal region R1 in the sub-region, there
919
940
// exists some region R2 in the sup-region that outlives R1.
920
- let universal_outlives = self
921
- . scc_values
941
+ let universal_outlives = self . scc_values
922
942
. universal_regions_outlived_by ( sub_region_scc)
923
943
. all ( |r1| {
924
944
self . scc_values
@@ -1029,8 +1049,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1029
1049
// (because `fr` includes `end(o)`).
1030
1050
for shorter_fr in self . scc_values . universal_regions_outlived_by ( longer_fr_scc) {
1031
1051
// If it is known that `fr: o`, carry on.
1032
- if self
1033
- . universal_region_relations
1052
+ if self . universal_region_relations
1034
1053
. outlives ( longer_fr, shorter_fr)
1035
1054
{
1036
1055
continue ;
@@ -1046,8 +1065,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1046
1065
if let Some ( propagated_outlives_requirements) = propagated_outlives_requirements {
1047
1066
// Shrink `fr` until we find a non-local region (if we do).
1048
1067
// We'll call that `fr-` -- it's ever so slightly smaller than `fr`.
1049
- if let Some ( fr_minus) = self
1050
- . universal_region_relations
1068
+ if let Some ( fr_minus) = self . universal_region_relations
1051
1069
. non_local_lower_bound ( longer_fr)
1052
1070
{
1053
1071
debug ! ( "check_universal_region: fr_minus={:?}" , fr_minus) ;
@@ -1056,8 +1074,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1056
1074
// region. (We always will.) We'll call that
1057
1075
// `shorter_fr+` -- it's ever so slightly larger than
1058
1076
// `fr`.
1059
- let shorter_fr_plus = self
1060
- . universal_region_relations
1077
+ let shorter_fr_plus = self . universal_region_relations
1061
1078
. non_local_upper_bound ( shorter_fr) ;
1062
1079
debug ! (
1063
1080
"check_universal_region: shorter_fr_plus={:?}" ,
@@ -1117,8 +1134,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1117
1134
let error_region = match error_element {
1118
1135
RegionElement :: Location ( l) => self . find_sub_region_live_at ( longer_fr, l) ,
1119
1136
RegionElement :: RootUniversalRegion ( r) => r,
1120
- RegionElement :: SubUniversalRegion ( error_ui) => self
1121
- . definitions
1137
+ RegionElement :: SubUniversalRegion ( error_ui) => self . definitions
1122
1138
. iter_enumerated ( )
1123
1139
. filter_map ( |( r, definition) | match definition. origin {
1124
1140
NLLRegionVariableOrigin :: BoundRegion ( ui) if error_ui == ui => Some ( r) ,
@@ -1215,7 +1231,11 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
1215
1231
// into a vector. These are the regions that we will be
1216
1232
// relating to one another.
1217
1233
let closure_mapping = & UniversalRegions :: closure_mapping (
1218
- tcx, user_closure_ty, self . num_external_vids , tcx. closure_base_def_id ( closure_def_id) ) ;
1234
+ tcx,
1235
+ user_closure_ty,
1236
+ self . num_external_vids ,
1237
+ tcx. closure_base_def_id ( closure_def_id) ,
1238
+ ) ;
1219
1239
debug ! ( "apply_requirements: closure_mapping={:?}" , closure_mapping) ;
1220
1240
1221
1241
// Create the predicates.
0 commit comments