@@ -10,14 +10,16 @@ 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 ,
1718 ConstraintCategory , Local , Location , ReturnConstraint ,
1819} ;
1920use rustc_middle:: traits:: ObligationCause ;
2021use rustc_middle:: traits:: ObligationCauseCode ;
22+ use rustc_middle:: ty:: Region ;
2123use rustc_middle:: ty:: { self , subst:: SubstsRef , RegionVid , Ty , TyCtxt , TypeFoldable } ;
2224use rustc_span:: Span ;
2325
@@ -46,6 +48,7 @@ pub mod values;
4648
4749pub struct RegionInferenceContext < ' tcx > {
4850 pub var_infos : VarInfos ,
51+
4952 /// Contains the definition for every region variable. Region
5053 /// variables are identified by their index (`RegionVid`). The
5154 /// definition contains information about where the region came
@@ -559,6 +562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
559562 pub ( super ) fn solve (
560563 & mut self ,
561564 infcx : & InferCtxt < ' _ , ' tcx > ,
565+ param_env : ty:: ParamEnv < ' tcx > ,
562566 body : & Body < ' tcx > ,
563567 polonius_output : Option < Rc < PoloniusOutput > > ,
564568 ) -> ( Option < ClosureRegionRequirements < ' tcx > > , RegionErrors < ' tcx > ) {
@@ -574,7 +578,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
574578 // eagerly.
575579 let mut outlives_requirements = infcx. tcx . is_typeck_child ( mir_def_id) . then ( Vec :: new) ;
576580
577- self . check_type_tests ( infcx, body, outlives_requirements. as_mut ( ) , & mut errors_buffer) ;
581+ self . check_type_tests (
582+ infcx,
583+ param_env,
584+ body,
585+ outlives_requirements. as_mut ( ) ,
586+ & mut errors_buffer,
587+ ) ;
578588
579589 // In Polonius mode, the errors about missing universal region relations are in the output
580590 // and need to be emitted or propagated. Otherwise, we need to check whether the
@@ -823,6 +833,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
823833 fn check_type_tests (
824834 & self ,
825835 infcx : & InferCtxt < ' _ , ' tcx > ,
836+ param_env : ty:: ParamEnv < ' tcx > ,
826837 body : & Body < ' tcx > ,
827838 mut propagated_outlives_requirements : Option < & mut Vec < ClosureOutlivesRequirement < ' tcx > > > ,
828839 errors_buffer : & mut RegionErrors < ' tcx > ,
@@ -839,7 +850,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
839850
840851 let generic_ty = type_test. generic_kind . to_ty ( tcx) ;
841852 if self . eval_verify_bound (
842- tcx,
853+ infcx,
854+ param_env,
843855 body,
844856 generic_ty,
845857 type_test. lower_bound ,
@@ -851,6 +863,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
851863 if let Some ( propagated_outlives_requirements) = & mut propagated_outlives_requirements {
852864 if self . try_promote_type_test (
853865 infcx,
866+ param_env,
854867 body,
855868 type_test,
856869 propagated_outlives_requirements,
@@ -907,6 +920,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
907920 fn try_promote_type_test (
908921 & self ,
909922 infcx : & InferCtxt < ' _ , ' tcx > ,
923+ param_env : ty:: ParamEnv < ' tcx > ,
910924 body : & Body < ' tcx > ,
911925 type_test : & TypeTest < ' tcx > ,
912926 propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement < ' tcx > > ,
@@ -938,7 +952,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
938952 // where `ur` is a local bound -- we are sometimes in a
939953 // position to prove things that our caller cannot. See
940954 // #53570 for an example.
941- if self . eval_verify_bound ( tcx, body, generic_ty, ur, & type_test. verify_bound ) {
955+ if self . eval_verify_bound (
956+ infcx,
957+ param_env,
958+ body,
959+ generic_ty,
960+ ur,
961+ & type_test. verify_bound ,
962+ ) {
942963 continue ;
943964 }
944965
@@ -1161,7 +1182,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11611182 /// `point`.
11621183 fn eval_verify_bound (
11631184 & self ,
1164- tcx : TyCtxt < ' tcx > ,
1185+ infcx : & InferCtxt < ' _ , ' tcx > ,
1186+ param_env : ty:: ParamEnv < ' tcx > ,
11651187 body : & Body < ' tcx > ,
11661188 generic_ty : Ty < ' tcx > ,
11671189 lower_bound : RegionVid ,
@@ -1170,14 +1192,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11701192 debug ! ( "eval_verify_bound(lower_bound={:?}, verify_bound={:?})" , lower_bound, verify_bound) ;
11711193
11721194 match verify_bound {
1173- VerifyBound :: IfEq ( test_ty, verify_bound1) => self . eval_if_eq (
1174- tcx,
1175- body,
1176- generic_ty,
1177- lower_bound,
1178- * test_ty,
1179- & VerifyBound :: OutlivedBy ( * verify_bound1) ,
1180- ) ,
1195+ VerifyBound :: IfEq ( test_ty, verify_bound1) => {
1196+ self . eval_if_eq ( infcx, generic_ty, lower_bound, * test_ty, * verify_bound1)
1197+ }
1198+
1199+ VerifyBound :: IfEqBound ( verify_if_eq_b) => {
1200+ self . eval_if_eq_bound ( infcx, param_env, generic_ty, lower_bound, * verify_if_eq_b)
1201+ }
11811202
11821203 VerifyBound :: IsEmpty => {
11831204 let lower_bound_scc = self . constraint_sccs . scc ( lower_bound) ;
@@ -1190,33 +1211,71 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11901211 }
11911212
11921213 VerifyBound :: AnyBound ( verify_bounds) => verify_bounds. iter ( ) . any ( |verify_bound| {
1193- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1214+ self . eval_verify_bound (
1215+ infcx,
1216+ param_env,
1217+ body,
1218+ generic_ty,
1219+ lower_bound,
1220+ verify_bound,
1221+ )
11941222 } ) ,
11951223
11961224 VerifyBound :: AllBounds ( verify_bounds) => verify_bounds. iter ( ) . all ( |verify_bound| {
1197- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1225+ self . eval_verify_bound (
1226+ infcx,
1227+ param_env,
1228+ body,
1229+ generic_ty,
1230+ lower_bound,
1231+ verify_bound,
1232+ )
11981233 } ) ,
11991234 }
12001235 }
12011236
12021237 fn eval_if_eq (
12031238 & self ,
1204- tcx : TyCtxt < ' tcx > ,
1205- body : & Body < ' tcx > ,
1239+ infcx : & InferCtxt < ' _ , ' tcx > ,
12061240 generic_ty : Ty < ' tcx > ,
12071241 lower_bound : RegionVid ,
12081242 test_ty : Ty < ' tcx > ,
1209- verify_bound : & VerifyBound < ' tcx > ,
1243+ verify_bound : Region < ' tcx > ,
12101244 ) -> bool {
1211- let generic_ty_normalized = self . normalize_to_scc_representatives ( tcx, generic_ty) ;
1212- let test_ty_normalized = self . normalize_to_scc_representatives ( tcx, test_ty) ;
1245+ let generic_ty_normalized = self . normalize_to_scc_representatives ( infcx . tcx , generic_ty) ;
1246+ let test_ty_normalized = self . normalize_to_scc_representatives ( infcx . tcx , test_ty) ;
12131247 if generic_ty_normalized == test_ty_normalized {
1214- self . eval_verify_bound ( tcx, body, generic_ty, lower_bound, verify_bound)
1248+ let verify_bound_vid = self . to_region_vid ( verify_bound) ;
1249+ self . eval_outlives ( verify_bound_vid, lower_bound)
12151250 } else {
12161251 false
12171252 }
12181253 }
12191254
1255+ fn eval_if_eq_bound (
1256+ & self ,
1257+ infcx : & InferCtxt < ' _ , ' tcx > ,
1258+ param_env : ty:: ParamEnv < ' tcx > ,
1259+ generic_ty : Ty < ' tcx > ,
1260+ lower_bound : RegionVid ,
1261+ verify_if_eq_b : ty:: Binder < ' tcx , VerifyIfEq < ' tcx > > ,
1262+ ) -> bool {
1263+ let generic_ty = self . normalize_to_scc_representatives ( infcx. tcx , generic_ty) ;
1264+ let verify_if_eq_b = self . normalize_to_scc_representatives ( infcx. tcx , verify_if_eq_b) ;
1265+ match test_type_match:: extract_verify_if_eq_bound (
1266+ infcx. tcx ,
1267+ param_env,
1268+ & verify_if_eq_b,
1269+ generic_ty,
1270+ ) {
1271+ Some ( r) => {
1272+ let r_vid = self . to_region_vid ( r) ;
1273+ self . eval_outlives ( r_vid, lower_bound)
1274+ }
1275+ None => false ,
1276+ }
1277+ }
1278+
12201279 /// This is a conservative normalization procedure. It takes every
12211280 /// free region in `value` and replaces it with the
12221281 /// "representative" of its SCC (see `scc_representatives` field).
0 commit comments