Skip to content

Commit abd7d88

Browse files
committed
move free_regions_map into infer::outlives
1 parent aa51603 commit abd7d88

File tree

11 files changed

+152
-137
lines changed

11 files changed

+152
-137
lines changed

src/librustc/infer/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use ty::IntVarValue;
1818
pub use self::freshen::TypeFreshener;
1919

2020
use hir::def_id::DefId;
21-
use middle::free_region::{FreeRegionMap, RegionRelations};
21+
use middle::free_region::RegionRelations;
2222
use middle::region;
2323
use middle::lang_items;
2424
use mir::tcx::PlaceTy;
@@ -44,6 +44,7 @@ use self::higher_ranked::HrMatchResult;
4444
use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
4545
use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins};
4646
use self::lexical_region_resolve::LexicalRegionResolutions;
47+
use self::outlives::free_region_map::FreeRegionMap;
4748
use self::type_variable::TypeVariableOrigin;
4849
use self::unify_key::ToType;
4950

@@ -58,7 +59,7 @@ pub mod lattice;
5859
mod lub;
5960
pub mod region_constraints;
6061
mod lexical_region_resolve;
61-
mod outlives;
62+
pub mod outlives;
6263
pub mod resolve;
6364
mod freshen;
6465
mod sub;

src/librustc/infer/outlives/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use middle::free_region::FreeRegionMap;
1211
use infer::{InferCtxt, GenericKind};
12+
use infer::outlives::free_region_map::FreeRegionMap;
1313
use infer::outlives::implied_bounds::ImpliedBound;
1414
use ty::{self, Ty};
1515

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use ty::{self, Lift, TyCtxt, Region};
12+
use rustc_data_structures::transitive_relation::TransitiveRelation;
13+
14+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
15+
pub struct FreeRegionMap<'tcx> {
16+
// Stores the relation `a < b`, where `a` and `b` are regions.
17+
//
18+
// Invariant: only free regions like `'x` or `'static` are stored
19+
// in this relation, not scopes.
20+
relation: TransitiveRelation<Region<'tcx>>
21+
}
22+
23+
impl<'tcx> FreeRegionMap<'tcx> {
24+
pub fn new() -> Self {
25+
FreeRegionMap { relation: TransitiveRelation::new() }
26+
}
27+
28+
pub fn is_empty(&self) -> bool {
29+
self.relation.is_empty()
30+
}
31+
32+
pub fn relate_free_regions_from_predicates(&mut self,
33+
predicates: &[ty::Predicate<'tcx>]) {
34+
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
35+
for predicate in predicates {
36+
match *predicate {
37+
ty::Predicate::Projection(..) |
38+
ty::Predicate::Trait(..) |
39+
ty::Predicate::Equate(..) |
40+
ty::Predicate::Subtype(..) |
41+
ty::Predicate::WellFormed(..) |
42+
ty::Predicate::ObjectSafe(..) |
43+
ty::Predicate::ClosureKind(..) |
44+
ty::Predicate::TypeOutlives(..) |
45+
ty::Predicate::ConstEvaluatable(..) => {
46+
// No region bounds here
47+
}
48+
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
49+
self.relate_regions(r_b, r_a);
50+
}
51+
}
52+
}
53+
}
54+
55+
/// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
56+
/// (with the exception that `'static: 'x` is not notable)
57+
pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
58+
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
59+
if is_free_or_static(sub) && is_free(sup) {
60+
self.relation.add(sub, sup)
61+
}
62+
}
63+
64+
/// Tests whether `r_a <= sup`. Both must be free regions or
65+
/// `'static`.
66+
pub fn sub_free_regions<'a, 'gcx>(&self,
67+
r_a: Region<'tcx>,
68+
r_b: Region<'tcx>)
69+
-> bool {
70+
assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
71+
if let ty::ReStatic = r_b {
72+
true // `'a <= 'static` is just always true, and not stored in the relation explicitly
73+
} else {
74+
r_a == r_b || self.relation.contains(&r_a, &r_b)
75+
}
76+
}
77+
78+
/// Compute the least-upper-bound of two free regions. In some
79+
/// cases, this is more conservative than necessary, in order to
80+
/// avoid making arbitrary choices. See
81+
/// `TransitiveRelation::postdom_upper_bound` for more details.
82+
pub fn lub_free_regions<'a, 'gcx>(&self,
83+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
84+
r_a: Region<'tcx>,
85+
r_b: Region<'tcx>)
86+
-> Region<'tcx> {
87+
debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
88+
assert!(is_free(r_a));
89+
assert!(is_free(r_b));
90+
let result = if r_a == r_b { r_a } else {
91+
match self.relation.postdom_upper_bound(&r_a, &r_b) {
92+
None => tcx.mk_region(ty::ReStatic),
93+
Some(r) => *r,
94+
}
95+
};
96+
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
97+
result
98+
}
99+
100+
/// Returns all regions that are known to outlive `r_a`. For
101+
/// example, in a function:
102+
///
103+
/// ```
104+
/// fn foo<'a, 'b: 'a, 'c: 'b>() { .. }
105+
/// ```
106+
///
107+
/// if `r_a` represents `'a`, this function would return `{'b, 'c}`.
108+
pub fn regions_that_outlive<'a, 'gcx>(&self, r_a: Region<'tcx>) -> Vec<&Region<'tcx>> {
109+
assert!(is_free(r_a) || *r_a == ty::ReStatic);
110+
self.relation.greater_than(&r_a)
111+
}
112+
}
113+
114+
fn is_free(r: Region) -> bool {
115+
match *r {
116+
ty::ReEarlyBound(_) | ty::ReFree(_) => true,
117+
_ => false
118+
}
119+
}
120+
121+
fn is_free_or_static(r: Region) -> bool {
122+
match *r {
123+
ty::ReStatic => true,
124+
_ => is_free(r),
125+
}
126+
}
127+
128+
impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
129+
relation
130+
});
131+
132+
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
133+
type Lifted = FreeRegionMap<'tcx>;
134+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
135+
self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
136+
.map(|relation| FreeRegionMap { relation })
137+
}
138+
}

src/librustc/infer/outlives/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
//! Various code related to computing outlives relations.
1212
1313
pub mod env;
14+
pub mod free_region_map;
1415
pub mod implied_bounds;
1516
mod obligations;

src/librustc/middle/free_region.rs

+3-128
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
//! `TransitiveRelation` type and use that to decide when one free
1616
//! region outlives another and so forth.
1717
18+
use infer::outlives::free_region_map::FreeRegionMap;
1819
use hir::def_id::DefId;
1920
use middle::region;
20-
use ty::{self, Lift, TyCtxt, Region};
21-
use rustc_data_structures::transitive_relation::TransitiveRelation;
21+
use ty::{self, TyCtxt, Region};
2222

2323
/// Combines a `region::ScopeTree` (which governs relationships between
2424
/// scopes) and a `FreeRegionMap` (which governs relationships between
@@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
103103
ty::ReStatic => true,
104104
ty::ReEarlyBound(_) | ty::ReFree(_) => {
105105
let re_static = self.tcx.mk_region(ty::ReStatic);
106-
self.free_regions.relation.contains(&re_static, &super_region)
106+
self.free_regions.sub_free_regions(&re_static, &super_region)
107107
}
108108
_ => false
109109
}
@@ -117,128 +117,3 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
117117
}
118118
}
119119

120-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
121-
pub struct FreeRegionMap<'tcx> {
122-
// Stores the relation `a < b`, where `a` and `b` are regions.
123-
//
124-
// Invariant: only free regions like `'x` or `'static` are stored
125-
// in this relation, not scopes.
126-
relation: TransitiveRelation<Region<'tcx>>
127-
}
128-
129-
impl<'tcx> FreeRegionMap<'tcx> {
130-
pub fn new() -> Self {
131-
FreeRegionMap { relation: TransitiveRelation::new() }
132-
}
133-
134-
pub fn is_empty(&self) -> bool {
135-
self.relation.is_empty()
136-
}
137-
138-
pub fn relate_free_regions_from_predicates(&mut self,
139-
predicates: &[ty::Predicate<'tcx>]) {
140-
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
141-
for predicate in predicates {
142-
match *predicate {
143-
ty::Predicate::Projection(..) |
144-
ty::Predicate::Trait(..) |
145-
ty::Predicate::Equate(..) |
146-
ty::Predicate::Subtype(..) |
147-
ty::Predicate::WellFormed(..) |
148-
ty::Predicate::ObjectSafe(..) |
149-
ty::Predicate::ClosureKind(..) |
150-
ty::Predicate::TypeOutlives(..) |
151-
ty::Predicate::ConstEvaluatable(..) => {
152-
// No region bounds here
153-
}
154-
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
155-
self.relate_regions(r_b, r_a);
156-
}
157-
}
158-
}
159-
}
160-
161-
/// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
162-
/// (with the exception that `'static: 'x` is not notable)
163-
pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
164-
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
165-
if is_free_or_static(sub) && is_free(sup) {
166-
self.relation.add(sub, sup)
167-
}
168-
}
169-
170-
/// Tests whether `r_a <= sup`. Both must be free regions or
171-
/// `'static`.
172-
pub fn sub_free_regions<'a, 'gcx>(&self,
173-
r_a: Region<'tcx>,
174-
r_b: Region<'tcx>)
175-
-> bool {
176-
assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
177-
if let ty::ReStatic = r_b {
178-
true // `'a <= 'static` is just always true, and not stored in the relation explicitly
179-
} else {
180-
r_a == r_b || self.relation.contains(&r_a, &r_b)
181-
}
182-
}
183-
184-
/// Compute the least-upper-bound of two free regions. In some
185-
/// cases, this is more conservative than necessary, in order to
186-
/// avoid making arbitrary choices. See
187-
/// `TransitiveRelation::postdom_upper_bound` for more details.
188-
pub fn lub_free_regions<'a, 'gcx>(&self,
189-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
190-
r_a: Region<'tcx>,
191-
r_b: Region<'tcx>)
192-
-> Region<'tcx> {
193-
debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
194-
assert!(is_free(r_a));
195-
assert!(is_free(r_b));
196-
let result = if r_a == r_b { r_a } else {
197-
match self.relation.postdom_upper_bound(&r_a, &r_b) {
198-
None => tcx.mk_region(ty::ReStatic),
199-
Some(r) => *r,
200-
}
201-
};
202-
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
203-
result
204-
}
205-
206-
/// Returns all regions that are known to outlive `r_a`. For
207-
/// example, in a function:
208-
///
209-
/// ```
210-
/// fn foo<'a, 'b: 'a, 'c: 'b>() { .. }
211-
/// ```
212-
///
213-
/// if `r_a` represents `'a`, this function would return `{'b, 'c}`.
214-
pub fn regions_that_outlive<'a, 'gcx>(&self, r_a: Region<'tcx>) -> Vec<&Region<'tcx>> {
215-
assert!(is_free(r_a) || *r_a == ty::ReStatic);
216-
self.relation.greater_than(&r_a)
217-
}
218-
}
219-
220-
fn is_free(r: Region) -> bool {
221-
match *r {
222-
ty::ReEarlyBound(_) | ty::ReFree(_) => true,
223-
_ => false
224-
}
225-
}
226-
227-
fn is_free_or_static(r: Region) -> bool {
228-
match *r {
229-
ty::ReStatic => true,
230-
_ => is_free(r),
231-
}
232-
}
233-
234-
impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
235-
relation
236-
});
237-
238-
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
239-
type Lifted = FreeRegionMap<'tcx>;
240-
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
241-
self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
242-
.map(|relation| FreeRegionMap { relation })
243-
}
244-
}

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pub use self::ObligationCauseCode::*;
1717

1818
use hir;
1919
use hir::def_id::DefId;
20+
use infer::outlives::free_region_map::FreeRegionMap;
2021
use middle::const_val::ConstEvalErr;
2122
use middle::region;
22-
use middle::free_region::FreeRegionMap;
2323
use ty::subst::Substs;
2424
use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, ToPredicate};
2525
use ty::error::{ExpectedFound, TypeError};

src/librustc/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ use hir::map as hir_map;
2323
use hir::map::DefPathHash;
2424
use lint::{self, Lint};
2525
use ich::{StableHashingContext, NodeIdHashingMode};
26+
use infer::outlives::free_region_map::FreeRegionMap;
2627
use middle::const_val::ConstVal;
2728
use middle::cstore::{CrateStore, LinkMeta};
2829
use middle::cstore::EncodedMetadata;
29-
use middle::free_region::FreeRegionMap;
3030
use middle::lang_items;
3131
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
3232
use middle::stability;

src/librustc_mir/borrow_check/nll/free_regions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
2525
use rustc::hir::def_id::DefId;
2626
use rustc::infer::InferCtxt;
27-
use rustc::middle::free_region::FreeRegionMap;
27+
use rustc::infer::outlives::free_region_map::FreeRegionMap;
2828
use rustc::ty::{self, RegionVid};
2929
use rustc::ty::subst::Substs;
3030
use rustc::util::nodemap::FxHashMap;

src/librustc_mir/borrow_check/nll/region_infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc::infer::InferCtxt;
1313
use rustc::infer::RegionVariableOrigin;
1414
use rustc::infer::NLLRegionVariableOrigin;
1515
use rustc::infer::region_constraints::VarOrigins;
16-
use rustc::middle::free_region::FreeRegionMap;
16+
use rustc::infer::outlives::free_region_map::FreeRegionMap;
1717
use rustc::mir::{Location, Mir};
1818
use rustc::ty::{self, RegionVid};
1919
use rustc_data_structures::indexed_vec::IndexVec;

src/librustc_typeck/check/dropck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
use check::regionck::RegionCtxt;
1212

1313
use hir::def_id::DefId;
14-
use middle::free_region::FreeRegionMap;
1514
use rustc::infer::{self, InferOk};
15+
use rustc::infer::outlives::free_region_map::FreeRegionMap;
1616
use rustc::middle::region;
1717
use rustc::ty::subst::{Subst, Substs};
1818
use rustc::ty::{self, Ty, TyCtxt};

src/librustc_typeck/coherence/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Check properties that are required by built-in traits and set
1212
//! up data structures required by type-checking/translation.
1313
14-
use rustc::middle::free_region::FreeRegionMap;
14+
use rustc::infer::outlives::free_region_map::FreeRegionMap;
1515
use rustc::middle::region;
1616
use rustc::middle::lang_items::UnsizeTraitLangItem;
1717

0 commit comments

Comments
 (0)