Skip to content

Commit f6e76be

Browse files
nikomatsakisbrson
authored andcommitted
move implied_bounds into regionck
1 parent d8fd8df commit f6e76be

File tree

3 files changed

+142
-165
lines changed

3 files changed

+142
-165
lines changed

src/librustc/middle/free_region.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use hir::def_id::DefId;
1919
use middle::region::RegionMaps;
2020
use ty::{self, Lift, TyCtxt, Region};
21-
use ty::wf::ImpliedBound;
2221
use rustc_data_structures::transitive_relation::TransitiveRelation;
2322

2423
/// Combines a `RegionMaps` (which governs relationships between
@@ -136,23 +135,6 @@ impl<'tcx> FreeRegionMap<'tcx> {
136135
self.relation.is_empty()
137136
}
138137

139-
pub fn relate_free_regions_from_implied_bounds(&mut self,
140-
implied_bounds: &[ImpliedBound<'tcx>])
141-
{
142-
debug!("relate_free_regions_from_implied_bounds()");
143-
for implied_bound in implied_bounds {
144-
debug!("implied bound: {:?}", implied_bound);
145-
match *implied_bound {
146-
ImpliedBound::RegionSubRegion(a, b) => {
147-
self.relate_regions(a, b);
148-
}
149-
ImpliedBound::RegionSubParam(..) |
150-
ImpliedBound::RegionSubProjection(..) => {
151-
}
152-
}
153-
}
154-
}
155-
156138
pub fn relate_free_regions_from_predicates(&mut self,
157139
predicates: &[ty::Predicate<'tcx>]) {
158140
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
@@ -177,7 +159,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
177159

178160
// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
179161
// (with the exception that `'static: 'x` is not notable)
180-
fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
162+
pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
181163
if (is_free(sub) || *sub == ty::ReStatic) && is_free(sup) {
182164
self.relation.add(sub, sup)
183165
}

src/librustc/ty/wf.rs

-128
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use hir::def_id::DefId;
1212
use infer::InferCtxt;
13-
use ty::outlives::Component;
1413
use ty::subst::Substs;
1514
use traits;
1615
use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
@@ -107,133 +106,6 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
107106
wf.normalize()
108107
}
109108

110-
/// Implied bounds are region relationships that we deduce
111-
/// automatically. The idea is that (e.g.) a caller must check that a
112-
/// function's argument types are well-formed immediately before
113-
/// calling that fn, and hence the *callee* can assume that its
114-
/// argument types are well-formed. This may imply certain relationships
115-
/// between generic parameters. For example:
116-
///
117-
/// fn foo<'a,T>(x: &'a T)
118-
///
119-
/// can only be called with a `'a` and `T` such that `&'a T` is WF.
120-
/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
121-
#[derive(Debug)]
122-
pub enum ImpliedBound<'tcx> {
123-
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
124-
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
125-
RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),
126-
}
127-
128-
/// Compute the implied bounds that a callee/impl can assume based on
129-
/// the fact that caller/projector has ensured that `ty` is WF. See
130-
/// the `ImpliedBound` type for more details.
131-
pub fn implied_bounds<'a, 'gcx, 'tcx>(
132-
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
133-
param_env: ty::ParamEnv<'tcx>,
134-
body_id: ast::NodeId,
135-
ty: Ty<'tcx>,
136-
span: Span)
137-
-> Vec<ImpliedBound<'tcx>>
138-
{
139-
// Sometimes when we ask what it takes for T: WF, we get back that
140-
// U: WF is required; in that case, we push U onto this stack and
141-
// process it next. Currently (at least) these resulting
142-
// predicates are always guaranteed to be a subset of the original
143-
// type, so we need not fear non-termination.
144-
let mut wf_types = vec![ty];
145-
146-
let mut implied_bounds = vec![];
147-
148-
while let Some(ty) = wf_types.pop() {
149-
// Compute the obligations for `ty` to be well-formed. If `ty` is
150-
// an unresolved inference variable, just substituted an empty set
151-
// -- because the return type here is going to be things we *add*
152-
// to the environment, it's always ok for this set to be smaller
153-
// than the ultimate set. (Note: normally there won't be
154-
// unresolved inference variables here anyway, but there might be
155-
// during typeck under some circumstances.)
156-
let obligations = obligations(infcx, param_env, body_id, ty, span).unwrap_or(vec![]);
157-
158-
// From the full set of obligations, just filter down to the
159-
// region relationships.
160-
implied_bounds.extend(
161-
obligations
162-
.into_iter()
163-
.flat_map(|obligation| {
164-
assert!(!obligation.has_escaping_regions());
165-
match obligation.predicate {
166-
ty::Predicate::Trait(..) |
167-
ty::Predicate::Equate(..) |
168-
ty::Predicate::Subtype(..) |
169-
ty::Predicate::Projection(..) |
170-
ty::Predicate::ClosureKind(..) |
171-
ty::Predicate::ObjectSafe(..) =>
172-
vec![],
173-
174-
ty::Predicate::WellFormed(subty) => {
175-
wf_types.push(subty);
176-
vec![]
177-
}
178-
179-
ty::Predicate::RegionOutlives(ref data) =>
180-
match infcx.tcx.no_late_bound_regions(data) {
181-
None =>
182-
vec![],
183-
Some(ty::OutlivesPredicate(r_a, r_b)) =>
184-
vec![ImpliedBound::RegionSubRegion(r_b, r_a)],
185-
},
186-
187-
ty::Predicate::TypeOutlives(ref data) =>
188-
match infcx.tcx.no_late_bound_regions(data) {
189-
None => vec![],
190-
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
191-
let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
192-
let components = infcx.tcx.outlives_components(ty_a);
193-
implied_bounds_from_components(r_b, components)
194-
}
195-
},
196-
}}));
197-
}
198-
199-
implied_bounds
200-
}
201-
202-
/// When we have an implied bound that `T: 'a`, we can further break
203-
/// this down to determine what relationships would have to hold for
204-
/// `T: 'a` to hold. We get to assume that the caller has validated
205-
/// those relationships.
206-
fn implied_bounds_from_components<'tcx>(sub_region: ty::Region<'tcx>,
207-
sup_components: Vec<Component<'tcx>>)
208-
-> Vec<ImpliedBound<'tcx>>
209-
{
210-
sup_components
211-
.into_iter()
212-
.flat_map(|component| {
213-
match component {
214-
Component::Region(r) =>
215-
vec![ImpliedBound::RegionSubRegion(sub_region, r)],
216-
Component::Param(p) =>
217-
vec![ImpliedBound::RegionSubParam(sub_region, p)],
218-
Component::Projection(p) =>
219-
vec![ImpliedBound::RegionSubProjection(sub_region, p)],
220-
Component::EscapingProjection(_) =>
221-
// If the projection has escaping regions, don't
222-
// try to infer any implied bounds even for its
223-
// free components. This is conservative, because
224-
// the caller will still have to prove that those
225-
// free components outlive `sub_region`. But the
226-
// idea is that the WAY that the caller proves
227-
// that may change in the future and we want to
228-
// give ourselves room to get smarter here.
229-
vec![],
230-
Component::UnresolvedInferenceVariable(..) =>
231-
vec![],
232-
}
233-
})
234-
.collect()
235-
}
236-
237109
struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
238110
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
239111
param_env: ty::ParamEnv<'tcx>,

0 commit comments

Comments
 (0)