@@ -10,7 +10,8 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
1010use rustc_hir:: CRATE_HIR_ID ;
1111use rustc_index:: vec:: IndexVec ;
1212use rustc_infer:: infer:: canonical:: QueryOutlivesConstraint ;
13- use rustc_infer:: infer:: region_constraints:: { GenericKind , VarInfos , VerifyBound } ;
13+ use rustc_infer:: infer:: outlives:: test_type_match;
14+ use rustc_infer:: infer:: region_constraints:: { GenericKind , VarInfos , VerifyBound , VerifyIfEq } ;
1415use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin } ;
1516use rustc_middle:: mir:: {
1617 Body , ClosureOutlivesRequirement , ClosureOutlivesSubject , ClosureRegionRequirements ,
@@ -46,6 +47,7 @@ pub mod values;
4647
4748pub struct RegionInferenceContext < ' tcx > {
4849 pub var_infos : VarInfos ,
50+
4951 /// Contains the definition for every region variable. Region
5052 /// variables are identified by their index (`RegionVid`). The
5153 /// definition contains information about where the region came
@@ -559,6 +561,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
559561 pub ( super ) fn solve (
560562 & mut self ,
561563 infcx : & InferCtxt < ' _ , ' tcx > ,
564+ param_env : ty:: ParamEnv < ' tcx > ,
562565 body : & Body < ' tcx > ,
563566 polonius_output : Option < Rc < PoloniusOutput > > ,
564567 ) -> ( Option < ClosureRegionRequirements < ' tcx > > , RegionErrors < ' tcx > ) {
@@ -574,7 +577,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
574577 // eagerly.
575578 let mut outlives_requirements = infcx. tcx . is_typeck_child ( mir_def_id) . then ( Vec :: new) ;
576579
577- self . check_type_tests ( infcx, body, outlives_requirements. as_mut ( ) , & mut errors_buffer) ;
580+ self . check_type_tests (
581+ infcx,
582+ param_env,
583+ body,
584+ outlives_requirements. as_mut ( ) ,
585+ & mut errors_buffer,
586+ ) ;
578587
579588 // In Polonius mode, the errors about missing universal region relations are in the output
580589 // and need to be emitted or propagated. Otherwise, we need to check whether the
@@ -823,6 +832,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
823832 fn check_type_tests (
824833 & self ,
825834 infcx : & InferCtxt < ' _ , ' tcx > ,
835+ param_env : ty:: ParamEnv < ' tcx > ,
826836 body : & Body < ' tcx > ,
827837 mut propagated_outlives_requirements : Option < & mut Vec < ClosureOutlivesRequirement < ' tcx > > > ,
828838 errors_buffer : & mut RegionErrors < ' tcx > ,
@@ -839,7 +849,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
839849
840850 let generic_ty = type_test. generic_kind . to_ty ( tcx) ;
841851 if self . eval_verify_bound (
842- tcx,
852+ infcx,
853+ param_env,
843854 body,
844855 generic_ty,
845856 type_test. lower_bound ,
@@ -851,6 +862,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
851862 if let Some ( propagated_outlives_requirements) = & mut propagated_outlives_requirements {
852863 if self . try_promote_type_test (
853864 infcx,
865+ param_env,
854866 body,
855867 type_test,
856868 propagated_outlives_requirements,
@@ -907,6 +919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
907919 fn try_promote_type_test (
908920 & self ,
909921 infcx : & InferCtxt < ' _ , ' tcx > ,
922+ param_env : ty:: ParamEnv < ' tcx > ,
910923 body : & Body < ' tcx > ,
911924 type_test : & TypeTest < ' tcx > ,
912925 propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement < ' tcx > > ,
@@ -938,7 +951,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
938951 // where `ur` is a local bound -- we are sometimes in a
939952 // position to prove things that our caller cannot. See
940953 // #53570 for an example.
941- if self . eval_verify_bound ( tcx, body, generic_ty, ur, & type_test. verify_bound ) {
954+ if self . eval_verify_bound (
955+ infcx,
956+ param_env,
957+ body,
958+ generic_ty,
959+ ur,
960+ & type_test. verify_bound ,
961+ ) {
942962 continue ;
943963 }
944964
@@ -1161,7 +1181,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11611181 /// `point`.
11621182 fn eval_verify_bound (
11631183 & self ,
1164- tcx : TyCtxt < ' tcx > ,
1184+ infcx : & InferCtxt < ' _ , ' tcx > ,
1185+ param_env : ty:: ParamEnv < ' tcx > ,
11651186 body : & Body < ' tcx > ,
11661187 generic_ty : Ty < ' tcx > ,
11671188 lower_bound : RegionVid ,
@@ -1170,8 +1191,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11701191 debug ! ( "eval_verify_bound(lower_bound={:?}, verify_bound={:?})" , lower_bound, verify_bound) ;
11711192
11721193 match verify_bound {
1173- VerifyBound :: IfEq ( test_ty , verify_bound1 ) => {
1174- self . eval_if_eq ( tcx , body , generic_ty, lower_bound, * test_ty , verify_bound1 )
1194+ VerifyBound :: IfEq ( verify_if_eq_b ) => {
1195+ self . eval_if_eq ( infcx , param_env , generic_ty, lower_bound, * verify_if_eq_b )
11751196 }
11761197
11771198 VerifyBound :: IsEmpty => {
@@ -1185,30 +1206,50 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11851206 }
11861207
11871208 VerifyBound :: AnyBound ( verify_bounds) => verify_bounds. iter ( ) . any ( |verify_bound| {
1188- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1209+ self . eval_verify_bound (
1210+ infcx,
1211+ param_env,
1212+ body,
1213+ generic_ty,
1214+ lower_bound,
1215+ verify_bound,
1216+ )
11891217 } ) ,
11901218
11911219 VerifyBound :: AllBounds ( verify_bounds) => verify_bounds. iter ( ) . all ( |verify_bound| {
1192- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1220+ self . eval_verify_bound (
1221+ infcx,
1222+ param_env,
1223+ body,
1224+ generic_ty,
1225+ lower_bound,
1226+ verify_bound,
1227+ )
11931228 } ) ,
11941229 }
11951230 }
11961231
11971232 fn eval_if_eq (
11981233 & self ,
1199- tcx : TyCtxt < ' tcx > ,
1200- body : & Body < ' tcx > ,
1234+ infcx : & InferCtxt < ' _ , ' tcx > ,
1235+ param_env : ty :: ParamEnv < ' tcx > ,
12011236 generic_ty : Ty < ' tcx > ,
12021237 lower_bound : RegionVid ,
1203- test_ty : Ty < ' tcx > ,
1204- verify_bound : & VerifyBound < ' tcx > ,
1238+ verify_if_eq_b : ty:: Binder < ' tcx , VerifyIfEq < ' tcx > > ,
12051239 ) -> bool {
1206- let generic_ty_normalized = self . normalize_to_scc_representatives ( tcx, generic_ty) ;
1207- let test_ty_normalized = self . normalize_to_scc_representatives ( tcx, test_ty) ;
1208- if generic_ty_normalized == test_ty_normalized {
1209- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1210- } else {
1211- false
1240+ let generic_ty = self . normalize_to_scc_representatives ( infcx. tcx , generic_ty) ;
1241+ let verify_if_eq_b = self . normalize_to_scc_representatives ( infcx. tcx , verify_if_eq_b) ;
1242+ match test_type_match:: extract_verify_if_eq (
1243+ infcx. tcx ,
1244+ param_env,
1245+ & verify_if_eq_b,
1246+ generic_ty,
1247+ ) {
1248+ Some ( r) => {
1249+ let r_vid = self . to_region_vid ( r) ;
1250+ self . eval_outlives ( r_vid, lower_bound)
1251+ }
1252+ None => false ,
12121253 }
12131254 }
12141255
@@ -1278,6 +1319,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12781319 let sub_region_scc = self . constraint_sccs . scc ( sub_region) ;
12791320 let sup_region_scc = self . constraint_sccs . scc ( sup_region) ;
12801321
1322+ // If we are checking that `'sup: 'sub`, and `'sub` contains
1323+ // some placeholder that `'sup` cannot name, then this is only
1324+ // true if `'sup` outlives static.
1325+ if !self . universe_compatible ( sub_region_scc, sup_region_scc) {
1326+ debug ! (
1327+ "eval_outlives: sub universe `{sub_region_scc:?}` is not nameable \
1328+ by super `{sup_region_scc:?}`, promoting to static",
1329+ ) ;
1330+
1331+ return self . eval_outlives ( sup_region, self . universal_regions . fr_static ) ;
1332+ }
1333+
12811334 // Both the `sub_region` and `sup_region` consist of the union
12821335 // of some number of universal regions (along with the union
12831336 // of various points in the CFG; ignore those points for
@@ -1292,6 +1345,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12921345 } ) ;
12931346
12941347 if !universal_outlives {
1348+ debug ! (
1349+ "eval_outlives: returning false because sub region contains a universal region not present in super"
1350+ ) ;
12951351 return false ;
12961352 }
12971353
@@ -1300,10 +1356,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13001356
13011357 if self . universal_regions . is_universal_region ( sup_region) {
13021358 // Micro-opt: universal regions contain all points.
1359+ debug ! (
1360+ "eval_outlives: returning true because super is universal and hence contains all points"
1361+ ) ;
13031362 return true ;
13041363 }
13051364
1306- self . scc_values . contains_points ( sup_region_scc, sub_region_scc)
1365+ let result = self . scc_values . contains_points ( sup_region_scc, sub_region_scc) ;
1366+ debug ! ( "returning {} because of comparison between points in sup/sub" , result) ;
1367+ result
13071368 }
13081369
13091370 /// Once regions have been propagated, this method is used to see
0 commit comments