Skip to content

Commit bd85a7d

Browse files
committed
Auto merge of #119101 - compiler-errors:outlives, r=<try>
Normalize region obligation in lexical region resolution with next-gen solver Draft because this is not yet done -- no tests or anything... but this is the general approach I've found to work. r? `@ghost`
2 parents c9c9f52 + f5a13e3 commit bd85a7d

File tree

32 files changed

+287
-204
lines changed

32 files changed

+287
-204
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -674,13 +674,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
674674
// eagerly.
675675
let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
676676

677-
self.check_type_tests(
678-
infcx,
679-
param_env,
680-
body,
681-
outlives_requirements.as_mut(),
682-
&mut errors_buffer,
683-
);
677+
self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer);
684678

685679
debug!(?errors_buffer);
686680
debug!(?outlives_requirements);
@@ -938,7 +932,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
938932
fn check_type_tests(
939933
&self,
940934
infcx: &InferCtxt<'tcx>,
941-
param_env: ty::ParamEnv<'tcx>,
942935
body: &Body<'tcx>,
943936
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
944937
errors_buffer: &mut RegionErrors<'tcx>,
@@ -956,7 +949,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
956949
let generic_ty = type_test.generic_kind.to_ty(tcx);
957950
if self.eval_verify_bound(
958951
infcx,
959-
param_env,
960952
generic_ty,
961953
type_test.lower_bound,
962954
&type_test.verify_bound,
@@ -967,7 +959,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
967959
if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
968960
if self.try_promote_type_test(
969961
infcx,
970-
param_env,
971962
body,
972963
type_test,
973964
propagated_outlives_requirements,
@@ -1025,7 +1016,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
10251016
fn try_promote_type_test(
10261017
&self,
10271018
infcx: &InferCtxt<'tcx>,
1028-
param_env: ty::ParamEnv<'tcx>,
10291019
body: &Body<'tcx>,
10301020
type_test: &TypeTest<'tcx>,
10311021
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
@@ -1087,7 +1077,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
10871077
// where `ur` is a local bound -- we are sometimes in a
10881078
// position to prove things that our caller cannot. See
10891079
// #53570 for an example.
1090-
if self.eval_verify_bound(infcx, param_env, generic_ty, ur, &type_test.verify_bound) {
1080+
if self.eval_verify_bound(infcx, generic_ty, ur, &type_test.verify_bound) {
10911081
continue;
10921082
}
10931083

@@ -1270,7 +1260,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12701260
fn eval_verify_bound(
12711261
&self,
12721262
infcx: &InferCtxt<'tcx>,
1273-
param_env: ty::ParamEnv<'tcx>,
12741263
generic_ty: Ty<'tcx>,
12751264
lower_bound: RegionVid,
12761265
verify_bound: &VerifyBound<'tcx>,
@@ -1279,7 +1268,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12791268

12801269
match verify_bound {
12811270
VerifyBound::IfEq(verify_if_eq_b) => {
1282-
self.eval_if_eq(infcx, param_env, generic_ty, lower_bound, *verify_if_eq_b)
1271+
self.eval_if_eq(infcx, generic_ty, lower_bound, *verify_if_eq_b)
12831272
}
12841273

12851274
VerifyBound::IsEmpty => {
@@ -1293,31 +1282,25 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12931282
}
12941283

12951284
VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| {
1296-
self.eval_verify_bound(infcx, param_env, generic_ty, lower_bound, verify_bound)
1285+
self.eval_verify_bound(infcx, generic_ty, lower_bound, verify_bound)
12971286
}),
12981287

12991288
VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| {
1300-
self.eval_verify_bound(infcx, param_env, generic_ty, lower_bound, verify_bound)
1289+
self.eval_verify_bound(infcx, generic_ty, lower_bound, verify_bound)
13011290
}),
13021291
}
13031292
}
13041293

13051294
fn eval_if_eq(
13061295
&self,
13071296
infcx: &InferCtxt<'tcx>,
1308-
param_env: ty::ParamEnv<'tcx>,
13091297
generic_ty: Ty<'tcx>,
13101298
lower_bound: RegionVid,
13111299
verify_if_eq_b: ty::Binder<'tcx, VerifyIfEq<'tcx>>,
13121300
) -> bool {
13131301
let generic_ty = self.normalize_to_scc_representatives(infcx.tcx, generic_ty);
13141302
let verify_if_eq_b = self.normalize_to_scc_representatives(infcx.tcx, verify_if_eq_b);
1315-
match test_type_match::extract_verify_if_eq(
1316-
infcx.tcx,
1317-
param_env,
1318-
&verify_if_eq_b,
1319-
generic_ty,
1320-
) {
1303+
match test_type_match::extract_verify_if_eq(infcx.tcx, &verify_if_eq_b, generic_ty) {
13211304
Some(r) => {
13221305
let r_vid = self.to_region_vid(r);
13231306
self.eval_outlives(r_vid, lower_bound)

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
199199

200200
// Insert the facts we know from the predicates. Why? Why not.
201201
let param_env = self.param_env;
202-
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
202+
// FIXME(-Znext-solver): This param-env is not normalized!
203+
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env.caller_bounds()));
203204

204205
// - outlives is reflexive, so `'r: 'r` for every region `'r`
205206
// - `'static: 'r` for every region `'r`

compiler/rustc_hir_analysis/src/check/check.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir as hir;
1010
use rustc_hir::def::{CtorKind, DefKind};
1111
use rustc_hir::def_id::LocalModDefId;
1212
use rustc_hir::Node;
13+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1314
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1415
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
1516
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
@@ -353,8 +354,8 @@ fn check_opaque_meets_bounds<'tcx>(
353354
hir::OpaqueTyOrigin::TyAlias { .. } => {
354355
let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, def_id)?;
355356
let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
356-
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
357-
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
357+
let assumptions = RegionCheckingAssumptions::with_bounds(param_env, implied_bounds);
358+
ocx.resolve_regions_and_report_errors(defining_use_anchor, &assumptions)?;
358359
}
359360
}
360361
// Check that any hidden types found during wf checking match the hidden types that `type_of` sees.

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir as hir;
77
use rustc_hir::def::{DefKind, Res};
88
use rustc_hir::intravisit;
99
use rustc_hir::{GenericParamKind, ImplItemKind};
10-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
10+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1111
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1212
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1313
use rustc_infer::traits::util;
@@ -20,6 +20,7 @@ use rustc_middle::ty::{
2020
};
2121
use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
2222
use rustc_span::{Span, DUMMY_SP};
23+
use rustc_trait_selection::regions::InferCtxtRegionExt;
2324
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
2425
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
2526
use rustc_trait_selection::traits::{
@@ -376,11 +377,11 @@ fn compare_method_predicate_entailment<'tcx>(
376377

377378
// Finally, resolve all regions. This catches wily misuses of
378379
// lifetime parameters.
379-
let outlives_env = OutlivesEnvironment::with_bounds(
380+
let assumptions = RegionCheckingAssumptions::with_bounds(
380381
param_env,
381382
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
382383
);
383-
let errors = infcx.resolve_regions(&outlives_env);
384+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
384385
if !errors.is_empty() {
385386
return Err(infcx
386387
.tainted_by_errors()
@@ -700,11 +701,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
700701

701702
// Finally, resolve all regions. This catches wily misuses of
702703
// lifetime parameters.
703-
let outlives_env = OutlivesEnvironment::with_bounds(
704+
let assumptions = RegionCheckingAssumptions::with_bounds(
704705
param_env,
705706
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
706707
);
707-
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
708+
ocx.resolve_regions_and_report_errors(impl_m_def_id, &assumptions)?;
708709

709710
let mut remapped_types = FxHashMap::default();
710711
for (def_id, (ty, args)) in collected_types {
@@ -1872,8 +1873,8 @@ fn compare_const_predicate_entailment<'tcx>(
18721873
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
18731874
}
18741875

1875-
let outlives_env = OutlivesEnvironment::new(param_env);
1876-
ocx.resolve_regions_and_report_errors(impl_ct_def_id, &outlives_env)
1876+
let assumptions = RegionCheckingAssumptions::new(param_env);
1877+
ocx.resolve_regions_and_report_errors(impl_ct_def_id, &assumptions)
18771878
}
18781879

18791880
pub(super) fn compare_impl_ty<'tcx>(
@@ -1968,8 +1969,8 @@ fn compare_type_predicate_entailment<'tcx>(
19681969

19691970
// Finally, resolve all regions. This catches wily misuses of
19701971
// lifetime parameters.
1971-
let outlives_env = OutlivesEnvironment::new(param_env);
1972-
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
1972+
let assumptions = RegionCheckingAssumptions::new(param_env);
1973+
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &assumptions)
19731974
}
19741975

19751976
/// Validate that `ProjectionCandidate`s created for this associated type will
@@ -2074,8 +2075,8 @@ pub(super) fn check_type_bounds<'tcx>(
20742075
// Finally, resolve all regions. This catches wily misuses of
20752076
// lifetime parameters.
20762077
let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types);
2077-
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
2078-
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
2078+
let assumptions = RegionCheckingAssumptions::with_bounds(param_env, implied_bounds);
2079+
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &assumptions)
20792080
}
20802081

20812082
/// Install projection predicates that allow GATs to project to their own

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use rustc_data_structures::fx::FxIndexSet;
22
use rustc_hir as hir;
33
use rustc_hir::def_id::DefId;
4-
use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
4+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
5+
use rustc_infer::infer::TyCtxtInferExt;
56
use rustc_lint_defs::builtin::REFINING_IMPL_TRAIT;
67
use rustc_middle::traits::{ObligationCause, Reveal};
78
use rustc_middle::ty::{
89
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
910
};
1011
use rustc_span::{Span, DUMMY_SP};
12+
use rustc_trait_selection::regions::InferCtxtRegionExt;
1113
use rustc_trait_selection::traits::{
1214
elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt,
1315
};
@@ -159,11 +161,11 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
159161
);
160162
return;
161163
}
162-
let outlives_env = OutlivesEnvironment::with_bounds(
164+
let assumptions = RegionCheckingAssumptions::with_bounds(
163165
param_env,
164166
infcx.implied_bounds_tys(param_env, impl_m.def_id.expect_local(), implied_wf_types),
165167
);
166-
let errors = infcx.resolve_regions(&outlives_env);
168+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
167169
if !errors.is_empty() {
168170
tcx.sess.span_delayed_bug(
169171
DUMMY_SP,

compiler/rustc_hir_analysis/src/check/dropck.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
// We don't do any drop checking during hir typeck.
44
use rustc_data_structures::fx::FxHashSet;
55
use rustc_errors::{struct_span_err, ErrorGuaranteed};
6-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
6+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
77
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
88
use rustc_middle::ty::util::CheckRegions;
99
use rustc_middle::ty::GenericArgsRef;
1010
use rustc_middle::ty::{self, TyCtxt};
11+
use rustc_trait_selection::regions::InferCtxtRegionExt;
1112
use rustc_trait_selection::traits::{self, ObligationCtxt};
1213

1314
use crate::errors;
@@ -169,7 +170,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
169170
return Err(guar.unwrap());
170171
}
171172

172-
let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(param_env));
173+
let errors = ocx.infcx.resolve_regions_normalizing_outlives_obligations(
174+
&RegionCheckingAssumptions::new(param_env),
175+
);
173176
if !errors.is_empty() {
174177
let mut guar = None;
175178
for error in errors {
@@ -184,6 +187,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
184187
RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
185188
format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
186189
}
190+
RegionResolutionError::CannotNormalize(..) => todo!(),
187191
};
188192
guar = Some(
189193
struct_span_err!(

compiler/rustc_hir_analysis/src/check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
8383
use rustc_hir::intravisit::Visitor;
8484
use rustc_index::bit_set::BitSet;
8585
use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
86-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
86+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
8787
use rustc_infer::infer::{self, TyCtxtInferExt as _};
8888
use rustc_infer::traits::ObligationCause;
8989
use rustc_middle::query::Providers;
@@ -633,8 +633,8 @@ pub fn check_function_signature<'tcx>(
633633
}
634634
}
635635

636-
let outlives_env = OutlivesEnvironment::new(param_env);
637-
if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) {
636+
let assumptions = RegionCheckingAssumptions::new(param_env);
637+
if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &assumptions) {
638638
return Err(e);
639639
}
640640

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+19-26
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ use rustc_hir as hir;
88
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir::ItemKind;
11-
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
12-
use rustc_infer::infer::outlives::obligations::TypeOutlives;
11+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1312
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
14-
use rustc_middle::mir::ConstraintCategory;
1513
use rustc_middle::query::Providers;
1614
use rustc_middle::ty::trait_def::TraitSpecializationKind;
1715
use rustc_middle::ty::{
@@ -23,6 +21,7 @@ use rustc_session::parse::feature_err;
2321
use rustc_span::symbol::{sym, Ident, Symbol};
2422
use rustc_span::{Span, DUMMY_SP};
2523
use rustc_target::spec::abi::Abi;
24+
use rustc_trait_selection::regions::InferCtxtRegionExt;
2625
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
2726
use rustc_trait_selection::traits::misc::{
2827
type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError,
@@ -126,9 +125,9 @@ where
126125
}
127126
}
128127

129-
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
128+
let assumptions = RegionCheckingAssumptions::with_bounds(param_env, implied_bounds);
130129

131-
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env)?;
130+
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &assumptions)?;
132131
infcx.tainted_by_errors().error_reported()
133132
}
134133

@@ -673,10 +672,12 @@ fn ty_known_to_outlive<'tcx>(
673672
ty: Ty<'tcx>,
674673
region: ty::Region<'tcx>,
675674
) -> bool {
676-
resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |infcx, region_bound_pairs| {
677-
let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
678-
let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
679-
outlives.type_must_outlive(origin, ty, region, ConstraintCategory::BoringNoLocation);
675+
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
676+
infcx.register_region_obligation(infer::RegionObligation {
677+
sub_region: region,
678+
sup_type: ty,
679+
origin: infer::RelateParamBound(DUMMY_SP, ty, None),
680+
});
680681
})
681682
}
682683

@@ -690,42 +691,34 @@ fn region_known_to_outlive<'tcx>(
690691
region_a: ty::Region<'tcx>,
691692
region_b: ty::Region<'tcx>,
692693
) -> bool {
693-
resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |mut infcx, _| {
694-
use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
695-
let origin = infer::RelateRegionParamBound(DUMMY_SP);
696-
// `region_a: region_b` -> `region_b <= region_a`
697-
infcx.push_sub_region_constraint(
698-
origin,
699-
region_b,
700-
region_a,
701-
ConstraintCategory::BoringNoLocation,
702-
);
694+
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
695+
infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP), region_b, region_a);
703696
})
704697
}
705698

706699
/// Given a known `param_env` and a set of well formed types, set up an
707700
/// `InferCtxt`, call the passed function (to e.g. set up region constraints
708701
/// to be tested), then resolve region and return errors
709-
fn resolve_regions_with_wf_tys<'tcx>(
702+
fn test_region_obligations<'tcx>(
710703
tcx: TyCtxt<'tcx>,
711704
id: LocalDefId,
712705
param_env: ty::ParamEnv<'tcx>,
713706
wf_tys: &FxIndexSet<Ty<'tcx>>,
714-
add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'tcx>, &'a RegionBoundPairs<'tcx>),
707+
add_constraints: impl FnOnce(&InferCtxt<'tcx>),
715708
) -> bool {
716709
// Unfortunately, we have to use a new `InferCtxt` each call, because
717710
// region constraints get added and solved there and we need to test each
718711
// call individually.
719712
let infcx = tcx.infer_ctxt().build();
720-
let outlives_environment = OutlivesEnvironment::with_bounds(
713+
714+
add_constraints(&infcx);
715+
716+
let outlives_environment = RegionCheckingAssumptions::with_bounds(
721717
param_env,
722718
infcx.implied_bounds_tys(param_env, id, wf_tys.clone()),
723719
);
724-
let region_bound_pairs = outlives_environment.region_bound_pairs();
725-
726-
add_constraints(&infcx, region_bound_pairs);
727720

728-
let errors = infcx.resolve_regions(&outlives_environment);
721+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_environment);
729722
debug!(?errors, "errors");
730723

731724
// If we were able to prove that the type outlives the region without

0 commit comments

Comments
 (0)