@@ -10,7 +10,8 @@ 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 ,
@@ -46,6 +47,7 @@ pub mod values;
46
47
47
48
pub struct RegionInferenceContext < ' tcx > {
48
49
pub var_infos : VarInfos ,
50
+
49
51
/// Contains the definition for every region variable. Region
50
52
/// variables are identified by their index (`RegionVid`). The
51
53
/// definition contains information about where the region came
@@ -559,6 +561,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
559
561
pub ( super ) fn solve (
560
562
& mut self ,
561
563
infcx : & InferCtxt < ' _ , ' tcx > ,
564
+ param_env : ty:: ParamEnv < ' tcx > ,
562
565
body : & Body < ' tcx > ,
563
566
polonius_output : Option < Rc < PoloniusOutput > > ,
564
567
) -> ( Option < ClosureRegionRequirements < ' tcx > > , RegionErrors < ' tcx > ) {
@@ -574,7 +577,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
574
577
// eagerly.
575
578
let mut outlives_requirements = infcx. tcx . is_typeck_child ( mir_def_id) . then ( Vec :: new) ;
576
579
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
+ ) ;
578
587
579
588
// In Polonius mode, the errors about missing universal region relations are in the output
580
589
// and need to be emitted or propagated. Otherwise, we need to check whether the
@@ -823,6 +832,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
823
832
fn check_type_tests (
824
833
& self ,
825
834
infcx : & InferCtxt < ' _ , ' tcx > ,
835
+ param_env : ty:: ParamEnv < ' tcx > ,
826
836
body : & Body < ' tcx > ,
827
837
mut propagated_outlives_requirements : Option < & mut Vec < ClosureOutlivesRequirement < ' tcx > > > ,
828
838
errors_buffer : & mut RegionErrors < ' tcx > ,
@@ -839,7 +849,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
839
849
840
850
let generic_ty = type_test. generic_kind . to_ty ( tcx) ;
841
851
if self . eval_verify_bound (
842
- tcx,
852
+ infcx,
853
+ param_env,
843
854
body,
844
855
generic_ty,
845
856
type_test. lower_bound ,
@@ -851,6 +862,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
851
862
if let Some ( propagated_outlives_requirements) = & mut propagated_outlives_requirements {
852
863
if self . try_promote_type_test (
853
864
infcx,
865
+ param_env,
854
866
body,
855
867
type_test,
856
868
propagated_outlives_requirements,
@@ -907,6 +919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
907
919
fn try_promote_type_test (
908
920
& self ,
909
921
infcx : & InferCtxt < ' _ , ' tcx > ,
922
+ param_env : ty:: ParamEnv < ' tcx > ,
910
923
body : & Body < ' tcx > ,
911
924
type_test : & TypeTest < ' tcx > ,
912
925
propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement < ' tcx > > ,
@@ -938,7 +951,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
938
951
// where `ur` is a local bound -- we are sometimes in a
939
952
// position to prove things that our caller cannot. See
940
953
// #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
+ ) {
942
962
continue ;
943
963
}
944
964
@@ -1161,7 +1181,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1161
1181
/// `point`.
1162
1182
fn eval_verify_bound (
1163
1183
& self ,
1164
- tcx : TyCtxt < ' tcx > ,
1184
+ infcx : & InferCtxt < ' _ , ' tcx > ,
1185
+ param_env : ty:: ParamEnv < ' tcx > ,
1165
1186
body : & Body < ' tcx > ,
1166
1187
generic_ty : Ty < ' tcx > ,
1167
1188
lower_bound : RegionVid ,
@@ -1170,8 +1191,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1170
1191
debug ! ( "eval_verify_bound(lower_bound={:?}, verify_bound={:?})" , lower_bound, verify_bound) ;
1171
1192
1172
1193
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 )
1175
1196
}
1176
1197
1177
1198
VerifyBound :: IsEmpty => {
@@ -1185,30 +1206,50 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1185
1206
}
1186
1207
1187
1208
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
+ )
1189
1217
} ) ,
1190
1218
1191
1219
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
+ )
1193
1228
} ) ,
1194
1229
}
1195
1230
}
1196
1231
1197
1232
fn eval_if_eq (
1198
1233
& self ,
1199
- tcx : TyCtxt < ' tcx > ,
1200
- body : & Body < ' tcx > ,
1234
+ infcx : & InferCtxt < ' _ , ' tcx > ,
1235
+ param_env : ty :: ParamEnv < ' tcx > ,
1201
1236
generic_ty : Ty < ' tcx > ,
1202
1237
lower_bound : RegionVid ,
1203
- test_ty : Ty < ' tcx > ,
1204
- verify_bound : & VerifyBound < ' tcx > ,
1238
+ verify_if_eq_b : ty:: Binder < ' tcx , VerifyIfEq < ' tcx > > ,
1205
1239
) -> 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 ,
1212
1253
}
1213
1254
}
1214
1255
@@ -1278,6 +1319,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1278
1319
let sub_region_scc = self . constraint_sccs . scc ( sub_region) ;
1279
1320
let sup_region_scc = self . constraint_sccs . scc ( sup_region) ;
1280
1321
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
+
1281
1334
// Both the `sub_region` and `sup_region` consist of the union
1282
1335
// of some number of universal regions (along with the union
1283
1336
// of various points in the CFG; ignore those points for
@@ -1292,6 +1345,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1292
1345
} ) ;
1293
1346
1294
1347
if !universal_outlives {
1348
+ debug ! (
1349
+ "eval_outlives: returning false because sub region contains a universal region not present in super"
1350
+ ) ;
1295
1351
return false ;
1296
1352
}
1297
1353
@@ -1300,10 +1356,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1300
1356
1301
1357
if self . universal_regions . is_universal_region ( sup_region) {
1302
1358
// Micro-opt: universal regions contain all points.
1359
+ debug ! (
1360
+ "eval_outlives: returning true because super is universal and hence contains all points"
1361
+ ) ;
1303
1362
return true ;
1304
1363
}
1305
1364
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
1307
1368
}
1308
1369
1309
1370
/// Once regions have been propagated, this method is used to see
0 commit comments