Skip to content

Commit d037f18

Browse files
committed
add with_bounds to OutlivesEnvironment and implied_bounds_tys to outlives_bounds::InferCtxtExt
1 parent 5d9e4d0 commit d037f18

File tree

7 files changed

+70
-82
lines changed

7 files changed

+70
-82
lines changed

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

+20-21
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,10 @@ pub struct OutlivesEnvironment<'tcx> {
5252
region_bound_pairs: RegionBoundPairs<'tcx>,
5353
}
5454

55-
/// Builder of OutlivesEnvironment. Use this structure if you need to add more outlives
56-
/// bounds than `explicit_outlives_bounds(param_env)`.
57-
pub struct OutlivesEnvironmentBuilder<'tcx> {
58-
pub param_env: ty::ParamEnv<'tcx>,
55+
/// Builder of OutlivesEnvironment.
56+
struct OutlivesEnvironmentBuilder<'tcx> {
57+
param_env: ty::ParamEnv<'tcx>,
5958
region_relation: TransitiveRelationBuilder<Region<'tcx>>,
60-
6159
region_bound_pairs: RegionBoundPairs<'tcx>,
6260
}
6361

@@ -69,7 +67,7 @@ pub type RegionBoundPairs<'tcx> =
6967

7068
impl<'tcx> OutlivesEnvironment<'tcx> {
7169
/// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
72-
pub fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
70+
fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
7371
let mut builder = OutlivesEnvironmentBuilder {
7472
param_env,
7573
region_relation: Default::default(),
@@ -87,6 +85,17 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
8785
Self::builder(param_env).build()
8886
}
8987

88+
/// Create a new `OutlivesEnvironment` with extra outlives bounds.
89+
pub fn with_bounds<'a>(
90+
param_env: ty::ParamEnv<'tcx>,
91+
infcx: Option<&InferCtxt<'a, 'tcx>>,
92+
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
93+
) -> Self {
94+
let mut builder = Self::builder(param_env);
95+
builder.add_outlives_bounds(infcx, extra_bounds);
96+
builder.build()
97+
}
98+
9099
/// Borrows current value of the `free_region_map`.
91100
pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
92101
&self.free_region_map
@@ -108,26 +117,14 @@ impl<'a, 'tcx> OutlivesEnvironmentBuilder<'tcx> {
108117
}
109118
}
110119

111-
// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
112-
// (with the exception that `'static: 'x` is not notable)
113-
fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
114-
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
115-
if sub.is_free_or_static() && sup.is_free() {
116-
self.region_relation.add(sub, sup)
117-
}
118-
}
119-
120120
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
121121
///
122122
/// The `infcx` parameter is optional; if the implied bounds may
123123
/// contain inference variables, it must be supplied, in which
124124
/// case we will register "givens" on the inference context. (See
125125
/// `RegionConstraintData`.)
126-
pub fn add_outlives_bounds<I>(
127-
&mut self,
128-
infcx: Option<&InferCtxt<'a, 'tcx>>,
129-
outlives_bounds: I,
130-
) where
126+
fn add_outlives_bounds<I>(&mut self, infcx: Option<&InferCtxt<'a, 'tcx>>, outlives_bounds: I)
127+
where
131128
I: IntoIterator<Item = OutlivesBound<'tcx>>,
132129
{
133130
// Record relationships such as `T:'x` that don't go into the
@@ -159,7 +156,9 @@ impl<'a, 'tcx> OutlivesEnvironmentBuilder<'tcx> {
159156
// system to be more general and to make use
160157
// of *every* relationship that arises here,
161158
// but presently we do not.)
162-
self.relate_regions(r_a, r_b);
159+
if r_a.is_free_or_static() && r_b.is_free() {
160+
self.region_relation.add(r_a, r_b)
161+
}
163162
}
164163
}
165164
}

compiler/rustc_typeck/src/check/compare_method.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::potentially_plural_count;
2-
use crate::check::regionck::OutlivesEnvironmentExt;
32
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
3+
use crate::outlives::outlives_bounds::InferCtxtExt as _;
44
use rustc_data_structures::fx::FxHashSet;
55
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
66
use rustc_hir as hir;
@@ -401,9 +401,11 @@ fn compare_predicate_entailment<'tcx>(
401401

402402
// Finally, resolve all regions. This catches wily misuses of
403403
// lifetime parameters.
404-
let mut outlives_environment = OutlivesEnvironment::builder(param_env);
405-
outlives_environment.add_implied_bounds(infcx, wf_tys, impl_m_hir_id);
406-
let outlives_environment = outlives_environment.build();
404+
let outlives_environment = OutlivesEnvironment::with_bounds(
405+
param_env,
406+
Some(infcx),
407+
infcx.implied_bounds_tys(param_env, impl_m_hir_id, wf_tys),
408+
);
407409
infcx.check_region_obligations_and_report_errors(
408410
impl_m.def_id.expect_local(),
409411
&outlives_environment,
@@ -1517,6 +1519,7 @@ pub fn check_type_bounds<'tcx>(
15171519
let mut outlives_environment = OutlivesEnvironment::builder(param_env);
15181520
outlives_environment.add_implied_bounds(&infcx, assumed_wf_types, impl_ty_hir_id);
15191521
let outlives_environment = outlives_environment.build();
1522+
15201523
infcx.check_region_obligations_and_report_errors(
15211524
impl_ty.def_id.expect_local(),
15221525
&outlives_environment,

compiler/rustc_typeck/src/check/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ mod op;
8787
mod pat;
8888
mod place_op;
8989
mod region;
90-
pub mod regionck;
9190
pub mod rvalue_scopes;
9291
mod upvar;
9392
pub mod wfcheck;

compiler/rustc_typeck/src/check/regionck.rs

-47
This file was deleted.

compiler/rustc_typeck/src/check/wfcheck.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::check::regionck::OutlivesEnvironmentExt;
21
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
2+
use crate::outlives::outlives_bounds::InferCtxtExt as _;
33
use rustc_ast as ast;
44
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
@@ -107,6 +107,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
107107
let mut outlives_environment = OutlivesEnvironment::builder(param_env);
108108
outlives_environment.add_implied_bounds(infcx, assumed_wf_types, body_id);
109109
let outlives_environment = outlives_environment.build();
110+
110111
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
111112
})
112113
}
@@ -695,9 +696,11 @@ fn resolve_regions_with_wf_tys<'tcx>(
695696
// region constraints get added and solved there and we need to test each
696697
// call individually.
697698
tcx.infer_ctxt().enter(|infcx| {
698-
let mut outlives_environment = OutlivesEnvironment::builder(param_env);
699-
outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id);
700-
let outlives_environment = outlives_environment.build();
699+
let outlives_environment = OutlivesEnvironment::with_bounds(
700+
param_env,
701+
Some(&infcx),
702+
infcx.implied_bounds_tys(param_env, id, wf_tys.iter().map(|ty| *ty)),
703+
);
701704
let region_bound_pairs = outlives_environment.region_bound_pairs();
702705

703706
add_constraints(&infcx, region_bound_pairs);

compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
//! cause use after frees with purely safe code in the same way as specializing
6666
//! on traits with methods can.
6767
68-
use crate::check::regionck::OutlivesEnvironmentExt;
6968
use crate::constrained_generic_params as cgp;
7069
use crate::errors::SubstsOnOverriddenImpl;
70+
use crate::outlives::outlives_bounds::InferCtxtExt;
7171

7272
use rustc_data_structures::fx::FxHashSet;
7373
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -147,10 +147,17 @@ fn get_impl_substs<'tcx>(
147147
let assumed_wf_types =
148148
ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
149149

150-
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
150+
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
151151
let impl2_substs =
152152
translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
153153

154+
155+
156+
157+
158+
159+
160+
154161
let errors = ocx.select_all_or_error();
155162
if !errors.is_empty() {
156163
ocx.infcx.report_fulfillment_errors(&errors, None, false);

compiler/rustc_typeck/src/outlives/outlives_bounds.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
use rustc_hir as hir;
2-
use rustc_middle::ty::{self, Ty};
2+
use rustc_hir::HirId;
3+
use rustc_middle::ty::{self, ParamEnv, Ty};
34
use rustc_trait_selection::infer::InferCtxt;
45
use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput};
56
use rustc_trait_selection::traits::query::NoSolution;
67
use rustc_trait_selection::traits::{ObligationCause, TraitEngine, TraitEngineExt};
78

89
pub use rustc_middle::traits::query::OutlivesBound;
910

10-
pub trait InferCtxtExt<'tcx> {
11+
pub trait InferCtxtExt<'a, 'tcx> {
1112
fn implied_outlives_bounds(
1213
&self,
1314
param_env: ty::ParamEnv<'tcx>,
1415
body_id: hir::HirId,
1516
ty: Ty<'tcx>,
1617
) -> Vec<OutlivesBound<'tcx>>;
18+
19+
fn implied_bounds_tys(
20+
&'a self,
21+
param_env: ty::ParamEnv<'tcx>,
22+
body_id: hir::HirId,
23+
tys: impl IntoIterator<Item = Ty<'tcx>> + 'a,
24+
) -> Box<dyn Iterator<Item = OutlivesBound<'tcx>> + 'a>;
1725
}
1826

19-
impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
27+
impl<'a, 'cx, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'cx, 'tcx> {
2028
/// Implied bounds are region relationships that we deduce
2129
/// automatically. The idea is that (e.g.) a caller must check that a
2230
/// function's argument types are well-formed immediately before
@@ -87,4 +95,20 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
8795

8896
output
8997
}
98+
99+
fn implied_bounds_tys(
100+
&'a self,
101+
param_env: ParamEnv<'tcx>,
102+
body_id: HirId,
103+
tys: impl IntoIterator<Item = Ty<'tcx>> + 'a,
104+
) -> Box<dyn Iterator<Item = OutlivesBound<'tcx>> + 'a> {
105+
Box::new(
106+
tys.into_iter()
107+
.map(move |ty| {
108+
let ty = self.resolve_vars_if_possible(ty);
109+
self.implied_outlives_bounds(param_env, body_id, ty)
110+
})
111+
.flatten(),
112+
)
113+
}
90114
}

0 commit comments

Comments
 (0)