Skip to content

Commit 744082e

Browse files
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

+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

+11-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;
@@ -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

+4-3
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

+4-4
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

+3-3
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

+4-4
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

+5-5
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

+3-3
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

+35-32
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
{

0 commit comments

Comments
 (0)