Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 744082e

Browse files
committedDec 19, 2023
Normalize param-env used by lexical region checking in new solver
1 parent 76ed61e commit 744082e

File tree

21 files changed

+167
-105
lines changed

21 files changed

+167
-105
lines changed
 

‎compiler/rustc_borrowck/src/type_check/free_region_relations.rs

Lines changed: 2 additions & 1 deletion
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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 11 additions & 11 deletions
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;
@@ -377,11 +377,11 @@ fn compare_method_predicate_entailment<'tcx>(
377377

378378
// Finally, resolve all regions. This catches wily misuses of
379379
// lifetime parameters.
380-
let outlives_env = OutlivesEnvironment::with_bounds(
380+
let assumptions = RegionCheckingAssumptions::with_bounds(
381381
param_env,
382382
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
383383
);
384-
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_env);
384+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
385385
if !errors.is_empty() {
386386
return Err(infcx
387387
.tainted_by_errors()
@@ -701,11 +701,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
701701

702702
// Finally, resolve all regions. This catches wily misuses of
703703
// lifetime parameters.
704-
let outlives_env = OutlivesEnvironment::with_bounds(
704+
let assumptions = RegionCheckingAssumptions::with_bounds(
705705
param_env,
706706
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
707707
);
708-
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
708+
ocx.resolve_regions_and_report_errors(impl_m_def_id, &assumptions)?;
709709

710710
let mut remapped_types = FxHashMap::default();
711711
for (def_id, (ty, args)) in collected_types {
@@ -1873,8 +1873,8 @@ fn compare_const_predicate_entailment<'tcx>(
18731873
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
18741874
}
18751875

1876-
let outlives_env = OutlivesEnvironment::new(param_env);
1877-
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)
18781878
}
18791879

18801880
pub(super) fn compare_impl_ty<'tcx>(
@@ -1969,8 +1969,8 @@ fn compare_type_predicate_entailment<'tcx>(
19691969

19701970
// Finally, resolve all regions. This catches wily misuses of
19711971
// lifetime parameters.
1972-
let outlives_env = OutlivesEnvironment::new(param_env);
1973-
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)
19741974
}
19751975

19761976
/// Validate that `ProjectionCandidate`s created for this associated type will
@@ -2075,8 +2075,8 @@ pub(super) fn check_type_bounds<'tcx>(
20752075
// Finally, resolve all regions. This catches wily misuses of
20762076
// lifetime parameters.
20772077
let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types);
2078-
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
2079-
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)
20802080
}
20812081

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

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
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::{
@@ -160,11 +161,11 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
160161
);
161162
return;
162163
}
163-
let outlives_env = OutlivesEnvironment::with_bounds(
164+
let assumptions = RegionCheckingAssumptions::with_bounds(
164165
param_env,
165166
infcx.implied_bounds_tys(param_env, impl_m.def_id.expect_local(), implied_wf_types),
166167
);
167-
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_env);
168+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
168169
if !errors.is_empty() {
169170
tcx.sess.span_delayed_bug(
170171
DUMMY_SP,

‎compiler/rustc_hir_analysis/src/check/dropck.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
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;
@@ -170,9 +170,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
170170
return Err(guar.unwrap());
171171
}
172172

173-
let errors = ocx
174-
.infcx
175-
.resolve_regions_normalizing_outlives_obligations(&OutlivesEnvironment::new(param_env));
173+
let errors = ocx.infcx.resolve_regions_normalizing_outlives_obligations(
174+
&RegionCheckingAssumptions::new(param_env),
175+
);
176176
if !errors.is_empty() {
177177
let mut guar = None;
178178
for error in errors {

‎compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
8282
use rustc_hir::intravisit::Visitor;
8383
use rustc_index::bit_set::BitSet;
8484
use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
85-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
85+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
8686
use rustc_infer::infer::{self, TyCtxtInferExt as _};
8787
use rustc_infer::traits::ObligationCause;
8888
use rustc_middle::query::Providers;
@@ -615,8 +615,8 @@ pub fn check_function_signature<'tcx>(
615615
}
616616
}
617617

618-
let outlives_env = OutlivesEnvironment::new(param_env);
619-
let _ = ocx.resolve_regions_and_report_errors(local_id, &outlives_env);
618+
let assumptions = RegionCheckingAssumptions::new(param_env);
619+
let _ = ocx.resolve_regions_and_report_errors(local_id, &assumptions);
620620

621621
fn extract_span_for_error_reporting<'tcx>(
622622
tcx: TyCtxt<'tcx>,

‎compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ 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;
11+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1212
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1313
use rustc_middle::query::Providers;
1414
use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -125,9 +125,9 @@ where
125125
}
126126
}
127127

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

130-
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env)?;
130+
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &assumptions)?;
131131
infcx.tainted_by_errors().error_reported()
132132
}
133133

@@ -713,7 +713,7 @@ fn test_region_obligations<'tcx>(
713713

714714
add_constraints(&infcx);
715715

716-
let outlives_environment = OutlivesEnvironment::with_bounds(
716+
let outlives_environment = RegionCheckingAssumptions::with_bounds(
717717
param_env,
718718
infcx.implied_bounds_tys(param_env, id, wf_tys.clone()),
719719
);

‎compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_hir as hir;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::ItemKind;
12-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
12+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1313
use rustc_infer::infer::{self, RegionResolutionError};
1414
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
1515
use rustc_infer::traits::Obligation;
@@ -265,8 +265,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
265265
}
266266

267267
// Finally, resolve all regions.
268-
let outlives_env = OutlivesEnvironment::new(param_env);
269-
let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env);
268+
let assumptions = RegionCheckingAssumptions::new(param_env);
269+
let _ = ocx.resolve_regions_and_report_errors(impl_did, &assumptions);
270270
}
271271
}
272272
_ => {
@@ -474,8 +474,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
474474
}
475475

476476
// Finally, resolve all regions.
477-
let outlives_env = OutlivesEnvironment::new(param_env);
478-
let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env);
477+
let assumptions = RegionCheckingAssumptions::new(param_env);
478+
let _ = ocx.resolve_regions_and_report_errors(impl_did, &assumptions);
479479

480480
CoerceUnsizedInfo { custom_kind: kind }
481481
}

‎compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use crate::{constrained_generic_params as cgp, errors};
7171
use rustc_data_structures::fx::FxHashSet;
7272
use rustc_hir as hir;
7373
use rustc_hir::def_id::{DefId, LocalDefId};
74-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
74+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
7575
use rustc_infer::infer::TyCtxtInferExt;
7676
use rustc_infer::traits::specialization_graph::Node;
7777
use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -203,8 +203,8 @@ fn get_impl_args(
203203
}
204204

205205
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
206-
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
207-
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
206+
let assumptions = RegionCheckingAssumptions::with_bounds(param_env, implied_bounds);
207+
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &assumptions);
208208
let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {
209209
let span = tcx.def_span(impl1_def_id);
210210
let guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span });

‎compiler/rustc_infer/src/infer/outlives/env.rs

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
1-
use crate::infer::free_regions::FreeRegionMap;
21
use crate::infer::GenericKind;
2+
use crate::infer::{free_regions::FreeRegionMap, outlives::explicit_outlives_bounds};
33
use crate::traits::query::OutlivesBound;
44
use rustc_data_structures::fx::FxIndexSet;
55
use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
66
use rustc_middle::ty::{self, Region};
77

8-
use super::explicit_outlives_bounds;
8+
pub struct RegionCheckingAssumptions<'tcx> {
9+
pub param_env: ty::ParamEnv<'tcx>,
10+
pub extra_bounds: FxIndexSet<OutlivesBound<'tcx>>,
11+
}
12+
13+
impl<'tcx> RegionCheckingAssumptions<'tcx> {
14+
/// Create a new `RegionCheckingAssumptions` without extra outlives bounds.
15+
pub fn new(param_env: ty::ParamEnv<'tcx>) -> RegionCheckingAssumptions<'tcx> {
16+
RegionCheckingAssumptions { param_env, extra_bounds: Default::default() }
17+
}
18+
19+
/// Create a new `RegionCheckingAssumptions` with extra outlives bounds.
20+
pub fn with_bounds(
21+
param_env: ty::ParamEnv<'tcx>,
22+
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
23+
) -> RegionCheckingAssumptions<'tcx> {
24+
RegionCheckingAssumptions { param_env, extra_bounds: extra_bounds.into_iter().collect() }
25+
}
26+
}
927

1028
/// The `OutlivesEnvironment` collects information about what outlives
1129
/// what in a given type-checking setting. For example, if we have a
@@ -28,7 +46,7 @@ use super::explicit_outlives_bounds;
2846
/// interested in the `OutlivesEnvironment`. -nmatsakis
2947
#[derive(Clone)]
3048
pub struct OutlivesEnvironment<'tcx> {
31-
pub param_env: ty::ParamEnv<'tcx>,
49+
pub clauses: Vec<ty::Clause<'tcx>>,
3250
free_region_map: FreeRegionMap<'tcx>,
3351

3452
// Contains the implied region bounds in scope for our current body.
@@ -54,8 +72,8 @@ pub struct OutlivesEnvironment<'tcx> {
5472

5573
/// Builder of OutlivesEnvironment.
5674
#[derive(Debug)]
57-
struct OutlivesEnvironmentBuilder<'tcx> {
58-
param_env: ty::ParamEnv<'tcx>,
75+
pub struct OutlivesEnvironmentBuilder<'tcx> {
76+
clauses: Vec<ty::Clause<'tcx>>,
5977
region_relation: TransitiveRelationBuilder<Region<'tcx>>,
6078
region_bound_pairs: RegionBoundPairs<'tcx>,
6179
}
@@ -68,32 +86,12 @@ pub type RegionBoundPairs<'tcx> =
6886

6987
impl<'tcx> OutlivesEnvironment<'tcx> {
7088
/// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
71-
fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
72-
let mut builder = OutlivesEnvironmentBuilder {
73-
param_env,
89+
pub fn builder() -> OutlivesEnvironmentBuilder<'tcx> {
90+
OutlivesEnvironmentBuilder {
91+
clauses: vec![],
7492
region_relation: Default::default(),
7593
region_bound_pairs: Default::default(),
76-
};
77-
78-
builder.add_outlives_bounds(explicit_outlives_bounds(param_env));
79-
80-
builder
81-
}
82-
83-
#[inline]
84-
/// Create a new `OutlivesEnvironment` without extra outlives bounds.
85-
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
86-
Self::builder(param_env).build()
87-
}
88-
89-
/// Create a new `OutlivesEnvironment` with extra outlives bounds.
90-
pub fn with_bounds(
91-
param_env: ty::ParamEnv<'tcx>,
92-
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
93-
) -> Self {
94-
let mut builder = Self::builder(param_env);
95-
builder.add_outlives_bounds(extra_bounds);
96-
builder.build()
94+
}
9795
}
9896

9997
/// Borrows current value of the `free_region_map`.
@@ -110,16 +108,21 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
110108
impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
111109
#[inline]
112110
#[instrument(level = "debug")]
113-
fn build(self) -> OutlivesEnvironment<'tcx> {
111+
pub fn build(self) -> OutlivesEnvironment<'tcx> {
114112
OutlivesEnvironment {
115-
param_env: self.param_env,
113+
clauses: self.clauses,
116114
free_region_map: FreeRegionMap { relation: self.region_relation.freeze() },
117115
region_bound_pairs: self.region_bound_pairs,
118116
}
119117
}
120118

119+
pub fn add_clauses(&mut self, clauses: &[ty::Clause<'tcx>]) {
120+
self.add_outlives_bounds(explicit_outlives_bounds(clauses));
121+
self.clauses.extend(clauses.iter().copied());
122+
}
123+
121124
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
122-
fn add_outlives_bounds<I>(&mut self, outlives_bounds: I)
125+
pub fn add_outlives_bounds<I>(&mut self, outlives_bounds: I)
123126
where
124127
I: IntoIterator<Item = OutlivesBound<'tcx>>,
125128
{

‎compiler/rustc_infer/src/infer/outlives/mod.rs

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
//! Various code related to computing outlives relations.
2-
use self::env::OutlivesEnvironment;
2+
use self::env::{OutlivesEnvironment, RegionCheckingAssumptions};
33
use super::region_constraints::RegionConstraintData;
4-
use super::{InferCtxt, RegionResolutionError};
4+
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
55
use crate::infer::free_regions::RegionRelations;
66
use crate::infer::lexical_region_resolve;
7+
use rustc_data_structures::captures::Captures;
78
use rustc_middle::traits::query::OutlivesBound;
8-
use rustc_middle::ty::{self, Ty};
9+
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
10+
use rustc_span::DUMMY_SP;
911

1012
pub mod components;
1113
pub mod env;
@@ -14,16 +16,12 @@ pub mod obligations;
1416
pub mod test_type_match;
1517
pub mod verify;
1618

17-
#[instrument(level = "debug", skip(param_env), ret)]
18-
pub fn explicit_outlives_bounds<'tcx>(
19-
param_env: ty::ParamEnv<'tcx>,
20-
) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
21-
param_env
22-
.caller_bounds()
23-
.into_iter()
24-
.map(ty::Clause::kind)
25-
.filter_map(ty::Binder::no_bound_vars)
26-
.filter_map(move |kind| match kind {
19+
#[instrument(level = "debug", skip(clauses), ret)]
20+
pub fn explicit_outlives_bounds<'a, 'tcx>(
21+
clauses: &'a [ty::Clause<'tcx>],
22+
) -> impl Iterator<Item = OutlivesBound<'tcx>> + Captures<'tcx> + 'a {
23+
clauses.iter().copied().map(ty::Clause::kind).filter_map(ty::Binder::no_bound_vars).filter_map(
24+
move |kind| match kind {
2725
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
2826
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
2927
}
@@ -33,7 +31,44 @@ pub fn explicit_outlives_bounds<'tcx>(
3331
| ty::ClauseKind::ConstArgHasType(_, _)
3432
| ty::ClauseKind::WellFormed(_)
3533
| ty::ClauseKind::ConstEvaluatable(_) => None,
34+
},
35+
)
36+
}
37+
38+
pub fn lower_region_checking_assumptions<'tcx, E>(
39+
tcx: TyCtxt<'tcx>,
40+
x: &RegionCheckingAssumptions<'tcx>,
41+
deeply_normalize_ty: impl Fn(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
42+
) -> Result<OutlivesEnvironment<'tcx>, E> {
43+
let mut outlives_env = OutlivesEnvironment::builder();
44+
let caller_bounds: Vec<_> = x
45+
.param_env
46+
.caller_bounds()
47+
.iter()
48+
.filter_map(|clause| {
49+
let bound_clause = clause.kind();
50+
let clause = match bound_clause.skip_binder() {
51+
region_outlives @ ty::ClauseKind::RegionOutlives(..) => region_outlives,
52+
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, region)) => {
53+
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
54+
match deeply_normalize_ty(ty) {
55+
Ok(ty) => ty,
56+
Err(e) => return Some(Err(e)),
57+
},
58+
region,
59+
))
60+
}
61+
_ => return None,
62+
};
63+
Some(Ok(bound_clause.rebind(clause).to_predicate(tcx)))
3664
})
65+
.try_collect()?;
66+
67+
println!("normalized caller bounds: {caller_bounds:#?}");
68+
69+
outlives_env.add_clauses(&caller_bounds);
70+
outlives_env.add_outlives_bounds(x.extra_bounds.iter().copied());
71+
Ok(outlives_env.build())
3772
}
3873

3974
impl<'tcx> InferCtxt<'tcx> {
@@ -48,14 +83,27 @@ impl<'tcx> InferCtxt<'tcx> {
4883
#[must_use]
4984
pub fn resolve_regions(
5085
&self,
51-
outlives_env: &OutlivesEnvironment<'tcx>,
86+
assumptions: &RegionCheckingAssumptions<'tcx>,
5287
deeply_normalize_ty: impl Fn(Ty<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
5388
) -> Vec<RegionResolutionError<'tcx>> {
54-
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
89+
let outlives_env =
90+
match lower_region_checking_assumptions(self.tcx, assumptions, &deeply_normalize_ty) {
91+
Ok(outlives_env) => outlives_env,
92+
Err(ty) => {
93+
return vec![RegionResolutionError::CannotNormalize(
94+
ty,
95+
SubregionOrigin::RelateRegionParamBound(DUMMY_SP),
96+
)];
97+
}
98+
};
99+
100+
match self.process_registered_region_obligations(
101+
&outlives_env,
102+
assumptions.param_env,
103+
&deeply_normalize_ty,
104+
) {
55105
Ok(()) => {}
56-
Err((ty, origin)) => {
57-
return vec![RegionResolutionError::CannotNormalize(ty, origin)];
58-
}
106+
Err((ty, origin)) => return vec![RegionResolutionError::CannotNormalize(ty, origin)],
59107
};
60108

61109
let (var_infos, data) = {

‎compiler/rustc_infer/src/infer/outlives/obligations.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl<'tcx> InferCtxt<'tcx> {
127127
pub fn process_registered_region_obligations<E>(
128128
&self,
129129
outlives_env: &OutlivesEnvironment<'tcx>,
130+
param_env: ty::ParamEnv<'tcx>,
130131
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
131132
) -> Result<(), (E, SubregionOrigin<'tcx>)> {
132133
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
@@ -142,7 +143,7 @@ impl<'tcx> InferCtxt<'tcx> {
142143
self.tcx,
143144
outlives_env.region_bound_pairs(),
144145
None,
145-
outlives_env.param_env,
146+
param_env,
146147
);
147148
let category = origin.to_constraint_category();
148149
outlives.type_must_outlive(origin, sup_type, sub_region, category);

‎compiler/rustc_infer/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(min_specialization)]
2626
#![feature(never_type)]
2727
#![feature(try_blocks)]
28+
#![feature(iterator_try_collect)]
2829
#![recursion_limit = "512"] // For rustdoc
2930

3031
#[macro_use]

‎compiler/rustc_middle/src/traits/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub struct NormalizationResult<'tcx> {
191191
/// case they are called implied bounds). They are fed to the
192192
/// `OutlivesEnv` which in turn is supplied to the region checker and
193193
/// other parts of the inference system.
194-
#[derive(Clone, Debug, TypeFoldable, TypeVisitable, HashStable)]
194+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, TypeVisitable, HashStable)]
195195
pub enum OutlivesBound<'tcx> {
196196
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
197197
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),

‎compiler/rustc_trait_selection/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![feature(never_type)]
2424
#![feature(type_alias_impl_trait)]
2525
#![feature(min_specialization)]
26+
#![feature(unwrap_infallible)]
2627
#![recursion_limit = "512"] // For rustdoc
2728

2829
#[macro_use]

‎compiler/rustc_trait_selection/src/regions.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
1-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
22
use rustc_infer::infer::{InferCtxt, RegionResolutionError};
33
use rustc_middle::traits::ObligationCause;
44

55
pub trait InferCtxtRegionExt<'tcx> {
66
fn resolve_regions_normalizing_outlives_obligations(
77
&self,
8-
outlives_env: &OutlivesEnvironment<'tcx>,
8+
outlives_env: &RegionCheckingAssumptions<'tcx>,
99
) -> Vec<RegionResolutionError<'tcx>>;
1010
}
1111

1212
impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
1313
fn resolve_regions_normalizing_outlives_obligations(
1414
&self,
15-
outlives_env: &OutlivesEnvironment<'tcx>,
15+
outlives_env: &RegionCheckingAssumptions<'tcx>,
1616
) -> Vec<RegionResolutionError<'tcx>> {
1717
self.resolve_regions(outlives_env, |ty| {
1818
let ty = self.resolve_vars_if_possible(ty);
1919

2020
if self.next_trait_solver() {
21-
crate::solve::deeply_normalize(
21+
crate::solve::deeply_normalize_with_skipped_universes(
2222
self.at(&ObligationCause::dummy(), outlives_env.param_env),
2323
ty,
24+
vec![None; ty.outer_exclusive_binder().as_usize()],
2425
)
2526
.map_err(|_| ty)
2627
} else {

‎compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::*;
66
use crate::errors::UnableToConstructConstantValue;
77
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
88
use crate::traits::project::ProjectAndUnifyResult;
9+
use rustc_infer::infer::outlives::lower_region_checking_assumptions;
910
use rustc_infer::infer::DefineOpaqueTypes;
1011
use rustc_middle::mir::interpret::ErrorHandled;
1112
use rustc_middle::ty::{ImplPolarity, Region, RegionVid};
@@ -178,8 +179,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
178179
panic!("Unable to fulfill trait {trait_did:?} for '{ty:?}': {errors:?}");
179180
}
180181

181-
let outlives_env = OutlivesEnvironment::new(full_env);
182-
let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty| Ok(ty));
182+
let assumptions = RegionCheckingAssumptions::new(full_env);
183+
let outlives_env =
184+
lower_region_checking_assumptions::<!>(self.tcx, &assumptions, |ty| Ok(ty)).into_ok();
185+
let _ =
186+
infcx.process_registered_region_obligations::<!>(&outlives_env, full_env, |ty| Ok(ty));
183187

184188
let region_data =
185189
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();

‎compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! [trait-resolution]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
55
//! [trait-specialization]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
66
7-
use crate::infer::outlives::env::OutlivesEnvironment;
7+
use crate::infer::outlives::env::RegionCheckingAssumptions;
88
use crate::infer::InferOk;
99
use crate::regions::InferCtxtRegionExt;
1010
use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
@@ -589,9 +589,9 @@ fn try_prove_negated_where_clause<'tcx>(
589589
// FIXME: We could use the assumed_wf_types from both impls, I think,
590590
// if that wasn't implemented just for LocalDefId, and we'd need to do
591591
// the normalization ourselves since this is totally fallible...
592-
let outlives_env = OutlivesEnvironment::new(param_env);
592+
let assumptions = RegionCheckingAssumptions::new(param_env);
593593

594-
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_env);
594+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
595595
if !errors.is_empty() {
596596
return false;
597597
}

‎compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_infer::infer::at::ToTrace;
1414
use rustc_infer::infer::canonical::{
1515
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
1616
};
17-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
17+
use rustc_infer::infer::outlives::env::RegionCheckingAssumptions;
1818
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
1919
use rustc_infer::traits::{
2020
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
@@ -200,7 +200,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
200200
pub fn resolve_regions_and_report_errors(
201201
self,
202202
generic_param_scope: LocalDefId,
203-
outlives_env: &OutlivesEnvironment<'tcx>,
203+
outlives_env: &RegionCheckingAssumptions<'tcx>,
204204
) -> Result<(), ErrorGuaranteed> {
205205
let errors = self.infcx.resolve_regions_normalizing_outlives_obligations(outlives_env);
206206
if errors.is_empty() {

‎compiler/rustc_trait_selection/src/traits/misc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_hir as hir;
99
use rustc_infer::infer::canonical::Canonical;
1010
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
1111
use rustc_infer::traits::query::NoSolution;
12-
use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError};
12+
use rustc_infer::{infer::outlives::env::RegionCheckingAssumptions, traits::FulfillmentError};
1313
use rustc_middle::ty::{self, AdtDef, GenericArg, List, Ty, TyCtxt, TypeVisitableExt};
1414
use rustc_span::DUMMY_SP;
1515

@@ -190,15 +190,15 @@ pub fn all_fields_implement_trait<'tcx>(
190190
}
191191

192192
// Check regions assuming the self type of the impl is WF
193-
let outlives_env = OutlivesEnvironment::with_bounds(
193+
let assumptions = RegionCheckingAssumptions::with_bounds(
194194
param_env,
195195
infcx.implied_bounds_tys(
196196
param_env,
197197
parent_cause.body_id,
198198
FxIndexSet::from_iter([self_type]),
199199
),
200200
);
201-
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_env);
201+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
202202
if !errors.is_empty() {
203203
infringing.push((field, ty, InfringingFieldsReason::Regions(errors)));
204204
}

‎compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mod util;
2323
pub mod vtable;
2424
pub mod wf;
2525

26-
use crate::infer::outlives::env::OutlivesEnvironment;
26+
use crate::infer::outlives::env::RegionCheckingAssumptions;
2727
use crate::infer::{InferCtxt, TyCtxtInferExt};
2828
use crate::regions::InferCtxtRegionExt;
2929
use crate::traits::error_reporting::TypeErrCtxtExt as _;
@@ -209,12 +209,12 @@ fn do_normalize_predicates<'tcx>(
209209

210210
// We can use the `elaborated_env` here; the region code only
211211
// cares about declarations like `'a: 'b`.
212-
let outlives_env = OutlivesEnvironment::new(elaborated_env);
212+
let assumptions = RegionCheckingAssumptions::new(elaborated_env);
213213

214214
// FIXME: It's very weird that we ignore region obligations but apparently
215215
// still need to use `resolve_regions` as we need the resolved regions in
216216
// the normalized predicates.
217-
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&outlives_env);
217+
let errors = infcx.resolve_regions_normalizing_outlives_obligations(&assumptions);
218218
if !errors.is_empty() {
219219
tcx.sess.span_delayed_bug(
220220
span,

0 commit comments

Comments
 (0)
Please sign in to comment.