@@ -10,14 +10,16 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
10
10
use rustc_hir:: CRATE_HIR_ID ;
11
11
use rustc_index:: vec:: IndexVec ;
12
12
use 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 } ;
14
15
use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin } ;
15
16
use rustc_middle:: mir:: {
16
17
Body , ClosureOutlivesRequirement , ClosureOutlivesSubject , ClosureRegionRequirements ,
17
18
ConstraintCategory , Local , Location , ReturnConstraint ,
18
19
} ;
19
20
use rustc_middle:: traits:: ObligationCause ;
20
21
use rustc_middle:: traits:: ObligationCauseCode ;
22
+ use rustc_middle:: ty:: Region ;
21
23
use rustc_middle:: ty:: { self , subst:: SubstsRef , RegionVid , Ty , TyCtxt , TypeFoldable } ;
22
24
use rustc_span:: Span ;
23
25
@@ -46,6 +48,7 @@ pub mod values;
46
48
47
49
pub struct RegionInferenceContext < ' tcx > {
48
50
pub var_infos : VarInfos ,
51
+
49
52
/// Contains the definition for every region variable. Region
50
53
/// variables are identified by their index (`RegionVid`). The
51
54
/// definition contains information about where the region came
@@ -559,6 +562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
559
562
pub ( super ) fn solve (
560
563
& mut self ,
561
564
infcx : & InferCtxt < ' _ , ' tcx > ,
565
+ param_env : ty:: ParamEnv < ' tcx > ,
562
566
body : & Body < ' tcx > ,
563
567
polonius_output : Option < Rc < PoloniusOutput > > ,
564
568
) -> ( Option < ClosureRegionRequirements < ' tcx > > , RegionErrors < ' tcx > ) {
@@ -574,7 +578,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
574
578
// eagerly.
575
579
let mut outlives_requirements = infcx. tcx . is_typeck_child ( mir_def_id) . then ( Vec :: new) ;
576
580
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
+ ) ;
578
588
579
589
// In Polonius mode, the errors about missing universal region relations are in the output
580
590
// and need to be emitted or propagated. Otherwise, we need to check whether the
@@ -823,6 +833,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
823
833
fn check_type_tests (
824
834
& self ,
825
835
infcx : & InferCtxt < ' _ , ' tcx > ,
836
+ param_env : ty:: ParamEnv < ' tcx > ,
826
837
body : & Body < ' tcx > ,
827
838
mut propagated_outlives_requirements : Option < & mut Vec < ClosureOutlivesRequirement < ' tcx > > > ,
828
839
errors_buffer : & mut RegionErrors < ' tcx > ,
@@ -839,7 +850,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
839
850
840
851
let generic_ty = type_test. generic_kind . to_ty ( tcx) ;
841
852
if self . eval_verify_bound (
842
- tcx,
853
+ infcx,
854
+ param_env,
843
855
body,
844
856
generic_ty,
845
857
type_test. lower_bound ,
@@ -851,6 +863,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
851
863
if let Some ( propagated_outlives_requirements) = & mut propagated_outlives_requirements {
852
864
if self . try_promote_type_test (
853
865
infcx,
866
+ param_env,
854
867
body,
855
868
type_test,
856
869
propagated_outlives_requirements,
@@ -907,6 +920,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
907
920
fn try_promote_type_test (
908
921
& self ,
909
922
infcx : & InferCtxt < ' _ , ' tcx > ,
923
+ param_env : ty:: ParamEnv < ' tcx > ,
910
924
body : & Body < ' tcx > ,
911
925
type_test : & TypeTest < ' tcx > ,
912
926
propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement < ' tcx > > ,
@@ -938,7 +952,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
938
952
// where `ur` is a local bound -- we are sometimes in a
939
953
// position to prove things that our caller cannot. See
940
954
// #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
+ ) {
942
963
continue ;
943
964
}
944
965
@@ -1161,7 +1182,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1161
1182
/// `point`.
1162
1183
fn eval_verify_bound (
1163
1184
& self ,
1164
- tcx : TyCtxt < ' tcx > ,
1185
+ infcx : & InferCtxt < ' _ , ' tcx > ,
1186
+ param_env : ty:: ParamEnv < ' tcx > ,
1165
1187
body : & Body < ' tcx > ,
1166
1188
generic_ty : Ty < ' tcx > ,
1167
1189
lower_bound : RegionVid ,
@@ -1170,14 +1192,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1170
1192
debug ! ( "eval_verify_bound(lower_bound={:?}, verify_bound={:?})" , lower_bound, verify_bound) ;
1171
1193
1172
1194
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
+ }
1181
1202
1182
1203
VerifyBound :: IsEmpty => {
1183
1204
let lower_bound_scc = self . constraint_sccs . scc ( lower_bound) ;
@@ -1190,33 +1211,71 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1190
1211
}
1191
1212
1192
1213
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
+ )
1194
1222
} ) ,
1195
1223
1196
1224
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
+ )
1198
1233
} ) ,
1199
1234
}
1200
1235
}
1201
1236
1202
1237
fn eval_if_eq (
1203
1238
& self ,
1204
- tcx : TyCtxt < ' tcx > ,
1205
- body : & Body < ' tcx > ,
1239
+ infcx : & InferCtxt < ' _ , ' tcx > ,
1206
1240
generic_ty : Ty < ' tcx > ,
1207
1241
lower_bound : RegionVid ,
1208
1242
test_ty : Ty < ' tcx > ,
1209
- verify_bound : & VerifyBound < ' tcx > ,
1243
+ verify_bound : Region < ' tcx > ,
1210
1244
) -> 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) ;
1213
1247
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)
1215
1250
} else {
1216
1251
false
1217
1252
}
1218
1253
}
1219
1254
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
+
1220
1279
/// This is a conservative normalization procedure. It takes every
1221
1280
/// free region in `value` and replaces it with the
1222
1281
/// "representative" of its SCC (see `scc_representatives` field).
0 commit comments