Skip to content

Commit 7f8c42d

Browse files
committed
refactor away AnyRegions and AllRegions
It's a bit cleaner to just have `AnyBound` and `AllBound`, after all.
1 parent 18b86e9 commit 7f8c42d

File tree

5 files changed

+61
-69
lines changed

5 files changed

+61
-69
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,13 +723,11 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
723723
&& self.bound_is_met(b, var_values, generic_ty, min)
724724
}
725725

726-
VerifyBound::AnyRegion(rs) => rs.iter()
727-
.map(|&r| var_values.normalize(self.tcx(), r))
728-
.any(|r| self.region_rels.is_subregion_of(min, r)),
729-
730-
VerifyBound::AllRegions(rs) => rs.iter()
731-
.map(|&r| var_values.normalize(self.tcx(), r))
732-
.all(|r| self.region_rels.is_subregion_of(min, r)),
726+
VerifyBound::OutlivedBy(r) =>
727+
self.region_rels.is_subregion_of(
728+
min,
729+
var_values.normalize(self.tcx(), r),
730+
),
733731

734732
VerifyBound::AnyBound(bs) => bs.iter()
735733
.any(|b| self.bound_is_met(b, var_values, generic_ty, min)),

src/librustc/infer/outlives/verify.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,23 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
6363
fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
6464
debug!("param_bound(param_ty={:?})", param_ty);
6565

66-
let mut param_bounds = self.declared_generic_bounds_from_env(GenericKind::Param(param_ty));
66+
// Start with anything like `T: 'a` we can scrape from the
67+
// environment
68+
let param_bounds =
69+
self.declared_generic_bounds_from_env(GenericKind::Param(param_ty))
70+
.into_iter();
6771

6872
// Add in the default bound of fn body that applies to all in
6973
// scope type parameters:
70-
param_bounds.extend(self.implicit_region_bound);
74+
let param_bounds =
75+
param_bounds
76+
.chain(self.implicit_region_bound);
7177

72-
VerifyBound::AnyRegion(param_bounds)
78+
VerifyBound::AnyBound(
79+
param_bounds
80+
.map(|r| VerifyBound::OutlivedBy(r))
81+
.collect()
82+
)
7383
}
7484

7585
/// Given a projection like `T::Item`, searches the environment
@@ -115,20 +125,23 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
115125
debug!("projection_bound(projection_ty={:?})", projection_ty);
116126

117127
// Search the env for where clauses like `P: 'a`.
118-
let mut declared_bounds =
119-
self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty));
128+
let env_bounds =
129+
self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty))
130+
.into_iter();
120131

121132
// Extend with bounds that we can find from the trait.
122-
declared_bounds.extend(self.projection_declared_bounds_from_trait(projection_ty));
123-
124-
debug!("projection_bound: declared_bounds = {:?}", declared_bounds);
133+
let trait_bounds =
134+
self.projection_declared_bounds_from_trait(projection_ty)
135+
.into_iter();
125136

126137
// see the extensive comment in projection_must_outlive
127138
let ty = self.tcx
128139
.mk_projection(projection_ty.item_def_id, projection_ty.substs);
129140
let recursive_bound = self.recursive_type_bound(ty);
130141

131-
VerifyBound::AnyRegion(declared_bounds).or(recursive_bound)
142+
VerifyBound::AnyBound(
143+
env_bounds.chain(trait_bounds).map(|r| VerifyBound::OutlivedBy(r)).collect()
144+
).or(recursive_bound)
132145
}
133146

134147
fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
@@ -138,7 +151,11 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
138151

139152
let mut regions = ty.regions();
140153
regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
141-
bounds.push(VerifyBound::AllRegions(regions));
154+
bounds.push(
155+
VerifyBound::AllBounds(
156+
regions.into_iter().map(|r| VerifyBound::OutlivedBy(r)).collect()
157+
)
158+
);
142159

143160
// remove bounds that must hold, since they are not interesting
144161
bounds.retain(|b| !b.must_hold());

src/librustc/infer/region_constraints/mod.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -213,40 +213,36 @@ pub enum VerifyBound<'tcx> {
213213
/// (after inference), and `'a: min`, then `G: min`.
214214
IfEq(Ty<'tcx>, Box<VerifyBound<'tcx>>),
215215

216-
/// Given a set of regions `R`, expands to the function:
216+
/// Given a region `R`, expands to the function:
217217
///
218218
/// fn(min) -> bool {
219-
/// exists (r in R) { r: min }
219+
/// R: min
220220
/// }
221221
///
222-
/// In other words, if some r in R outlives min, then G outlives
223-
/// min. This is used when G is known to outlive all the regions
224-
/// in R.
225-
AnyRegion(Vec<Region<'tcx>>),
226-
227-
/// Given a set of regions `R`, expands to the function:
228-
///
229-
/// fn(min) -> bool {
230-
/// forall (r in R) { r: min }
231-
/// }
232-
///
233-
/// In other words, if all r in R outlives min, then G outlives
234-
/// min. This is used when G is known to outlive some region in
235-
/// R, but we don't know which.
236-
AllRegions(Vec<Region<'tcx>>),
222+
/// This is used when we can establish that `G: R` -- therefore,
223+
/// if `R: min`, then by transitivity `G: min`.
224+
OutlivedBy(Region<'tcx>),
237225

238226
/// Given a set of bounds `B`, expands to the function:
239227
///
240228
/// fn(min) -> bool {
241229
/// exists (b in B) { b(min) }
242230
/// }
231+
///
232+
/// In other words, if we meet some bound in `B`, that suffices.
233+
/// This is used when all the bounds in `B` are known to apply to
234+
/// G.
243235
AnyBound(Vec<VerifyBound<'tcx>>),
244236

245237
/// Given a set of bounds `B`, expands to the function:
246238
///
247239
/// fn(min) -> bool {
248240
/// forall (b in B) { b(min) }
249241
/// }
242+
///
243+
/// In other words, if we meet *all* bounds in `B`, that suffices.
244+
/// This is used when *some* bound in `B` is known to suffice, but
245+
/// we don't know which.
250246
AllBounds(Vec<VerifyBound<'tcx>>),
251247
}
252248

@@ -954,8 +950,8 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
954950
pub fn must_hold(&self) -> bool {
955951
match self {
956952
VerifyBound::IfEq(..) => false,
957-
VerifyBound::AnyRegion(bs) => bs.contains(&&ty::ReStatic),
958-
VerifyBound::AllRegions(bs) => bs.is_empty(),
953+
VerifyBound::OutlivedBy(ty::ReStatic) => true,
954+
VerifyBound::OutlivedBy(_) => false,
959955
VerifyBound::AnyBound(bs) => bs.iter().any(|b| b.must_hold()),
960956
VerifyBound::AllBounds(bs) => bs.iter().all(|b| b.must_hold()),
961957
}
@@ -964,8 +960,8 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
964960
pub fn cannot_hold(&self) -> bool {
965961
match self {
966962
VerifyBound::IfEq(_, b) => b.cannot_hold(),
967-
VerifyBound::AnyRegion(bs) => bs.is_empty(),
968-
VerifyBound::AllRegions(bs) => bs.contains(&&ty::ReEmpty),
963+
VerifyBound::OutlivedBy(ty::ReEmpty) => true,
964+
VerifyBound::OutlivedBy(_) => false,
969965
VerifyBound::AnyBound(bs) => bs.iter().all(|b| b.cannot_hold()),
970966
VerifyBound::AllBounds(bs) => bs.iter().any(|b| b.cannot_hold()),
971967
}

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -172,28 +172,19 @@ pub struct TypeTest<'tcx> {
172172
/// conveniently include disjuction ("a or b must be true").
173173
#[derive(Clone, Debug)]
174174
pub enum RegionTest {
175-
/// The subject region `'x` must by outlived by *some* region in
176-
/// the given set of regions.
175+
/// The subject region `'x` must by outlived by the given region.
176+
///
177+
/// This test comes from e.g. a where clause like `T: 'a`, which
178+
/// implies that we know that `T: 'a`. Therefore, if we are trying
179+
/// to prove that `T: 'x`, we can do so by showing that `'a: 'x`.
180+
IsOutlivedBy(RegionVid),
181+
182+
/// Any of the given tests are true.
177183
///
178184
/// This test comes from e.g. a where clause like `T: 'a + 'b`,
179185
/// which implies that we know that `T: 'a` and that `T:
180186
/// 'b`. Therefore, if we are trying to prove that `T: 'x`, we can
181187
/// do so by showing that `'a: 'x` *or* `'b: 'x`.
182-
IsOutlivedByAnyRegionIn(Vec<RegionVid>),
183-
184-
/// The subject region `'x` must by outlived by *all* regions in
185-
/// the given set of regions.
186-
///
187-
/// This test comes from e.g. a projection type like `T = <u32 as
188-
/// Trait<'a, 'b>>::Foo`, which must outlive `'a` or `'b`, and
189-
/// maybe both. Therefore we can prove that `T: 'x` if we know
190-
/// that `'a: 'x` *and* `'b: 'x`.
191-
IsOutlivedByAllRegionsIn(Vec<RegionVid>),
192-
193-
/// Any of the given tests are true.
194-
///
195-
/// This arises from projections, for which there are multiple
196-
/// ways to prove an outlives relationship.
197188
Any(Vec<RegionTest>),
198189

199190
/// All of the given tests are true.
@@ -895,13 +886,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
895886
);
896887

897888
match test {
898-
RegionTest::IsOutlivedByAllRegionsIn(regions) => regions
899-
.iter()
900-
.all(|&r| self.eval_outlives(mir, r, lower_bound)),
901-
902-
RegionTest::IsOutlivedByAnyRegionIn(regions) => regions
903-
.iter()
904-
.any(|&r| self.eval_outlives(mir, r, lower_bound)),
889+
RegionTest::IsOutlivedBy(r) => self.eval_outlives(mir, *r, lower_bound),
905890

906891
RegionTest::Any(tests) => tests
907892
.iter()

src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,11 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
158158
match verify_bound {
159159
VerifyBound::IfEq(..) => {
160160
// FIXME: always false right now
161-
RegionTest::IsOutlivedByAnyRegionIn(vec![])
161+
RegionTest::Any(vec![])
162162
}
163163

164-
VerifyBound::AnyRegion(regions) => RegionTest::IsOutlivedByAnyRegionIn(
165-
regions.iter().map(|r| self.to_region_vid(r)).collect(),
166-
),
167-
168-
VerifyBound::AllRegions(regions) => RegionTest::IsOutlivedByAllRegionsIn(
169-
regions.iter().map(|r| self.to_region_vid(r)).collect(),
164+
VerifyBound::OutlivedBy(r) => RegionTest::IsOutlivedBy(
165+
self.to_region_vid(r)
170166
),
171167

172168
VerifyBound::AnyBound(bounds) => RegionTest::Any(

0 commit comments

Comments
 (0)