Skip to content

Commit 70be49d

Browse files
committed
Move the list of region obligations into the fulfillment context.
1 parent 9bdd7f0 commit 70be49d

File tree

4 files changed

+83
-67
lines changed

4 files changed

+83
-67
lines changed

src/librustc/middle/traits/fulfill.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
// except according to those terms.
1010

1111
use middle::mem_categorization::Typer;
12-
use middle::ty;
13-
use middle::infer::InferCtxt;
12+
use middle::ty::{mod, Ty};
13+
use middle::infer::{mod, InferCtxt};
1414
use std::collections::HashSet;
15+
use std::collections::hash_map::{Occupied, Vacant};
16+
use std::default::Default;
1517
use std::rc::Rc;
18+
use syntax::ast;
1619
use util::ppaux::Repr;
20+
use util::nodemap::NodeMap;
1721

1822
use super::CodeAmbiguity;
1923
use super::TraitObligation;
@@ -47,6 +51,38 @@ pub struct FulfillmentContext<'tcx> {
4751
// attempted to select. This is used to avoid repeating work
4852
// when `select_new_obligations` is called.
4953
attempted_mark: uint,
54+
55+
// A set of constraints that regionck must validate. Each
56+
// constraint has the form `T:'a`, meaning "some type `T` must
57+
// outlive the lifetime 'a". These constraints derive from
58+
// instantiated type parameters. So if you had a struct defined
59+
// like
60+
//
61+
// struct Foo<T:'static> { ... }
62+
//
63+
// then in some expression `let x = Foo { ... }` it will
64+
// instantiate the type parameter `T` with a fresh type `$0`. At
65+
// the same time, it will record a region obligation of
66+
// `$0:'static`. This will get checked later by regionck. (We
67+
// can't generally check these things right away because we have
68+
// to wait until types are resolved.)
69+
//
70+
// These are stored in a map keyed to the id of the innermost
71+
// enclosing fn body / static initializer expression. This is
72+
// because the location where the obligation was incurred can be
73+
// relevant with respect to which sublifetime assumptions are in
74+
// place. The reason that we store under the fn-id, and not
75+
// something more fine-grained, is so that it is easier for
76+
// regionck to be sure that it has found *all* the region
77+
// obligations (otherwise, it's easy to fail to walk to a
78+
// particular node-id).
79+
region_obligations: NodeMap<Vec<RegionObligation<'tcx>>>,
80+
}
81+
82+
pub struct RegionObligation<'tcx> {
83+
pub sub_region: ty::Region,
84+
pub sup_type: Ty<'tcx>,
85+
pub origin: infer::SubregionOrigin<'tcx>,
5086
}
5187

5288
impl<'tcx> FulfillmentContext<'tcx> {
@@ -55,6 +91,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
5591
duplicate_set: HashSet::new(),
5692
trait_obligations: Vec::new(),
5793
attempted_mark: 0,
94+
region_obligations: NodeMap::new(),
5895
}
5996
}
6097

@@ -71,6 +108,26 @@ impl<'tcx> FulfillmentContext<'tcx> {
71108
}
72109
}
73110

111+
pub fn register_region_obligation(&mut self,
112+
body_id: ast::NodeId,
113+
region_obligation: RegionObligation<'tcx>)
114+
{
115+
match self.region_obligations.entry(body_id) {
116+
Vacant(entry) => { entry.set(vec![region_obligation]); },
117+
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
118+
}
119+
}
120+
121+
pub fn region_obligations(&self,
122+
body_id: ast::NodeId)
123+
-> &[RegionObligation<'tcx>]
124+
{
125+
match self.region_obligations.get(&body_id) {
126+
None => Default::default(),
127+
Some(vec) => vec.as_slice(),
128+
}
129+
}
130+
74131
pub fn select_all_or_error<'a>(&mut self,
75132
infcx: &InferCtxt<'a,'tcx>,
76133
param_env: &ty::ParameterEnvironment<'tcx>,
@@ -208,3 +265,12 @@ impl<'tcx> FulfillmentContext<'tcx> {
208265
}
209266
}
210267
}
268+
269+
impl<'tcx> Repr<'tcx> for RegionObligation<'tcx> {
270+
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
271+
format!("RegionObligation(sub_region={}, sup_type={}, origin={})",
272+
self.sub_region.repr(tcx),
273+
self.sup_type.repr(tcx),
274+
self.origin.repr(tcx))
275+
}
276+
}

src/librustc/middle/traits/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax::ast;
2525
use syntax::codemap::{Span, DUMMY_SP};
2626
use util::common::ErrorReported;
2727

28-
pub use self::fulfill::FulfillmentContext;
28+
pub use self::fulfill::{FulfillmentContext, RegionObligation};
2929
pub use self::select::SelectionContext;
3030
pub use self::select::SelectionCache;
3131
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};

src/librustc_typeck/check/mod.rs

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,14 @@ use self::TupleArgumentsFlag::*;
8484

8585
use astconv::{mod, ast_region_to_region, ast_ty_to_ty, AstConv};
8686
use check::_match::pat_ctxt;
87-
use middle::{const_eval, def, traits};
87+
use middle::{const_eval, def};
8888
use middle::infer;
8989
use middle::lang_items::IteratorItem;
9090
use middle::mem_categorization::{mod, McResult};
9191
use middle::pat_util::{mod, pat_id_map};
9292
use middle::region::CodeExtent;
9393
use middle::subst::{mod, Subst, Substs, VecPerParamSpace, ParamSpace};
94+
use middle::traits;
9495
use middle::ty::{FnSig, VariantInfo, Polytype};
9596
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
9697
use middle::ty::{mod, Ty};
@@ -108,7 +109,6 @@ use util::ppaux::{mod, UserString, Repr};
108109
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
109110

110111
use std::cell::{Cell, Ref, RefCell};
111-
use std::collections::hash_map::{Occupied, Vacant};
112112
use std::mem::replace;
113113
use std::rc::Rc;
114114
use syntax::{mod, abi, attr};
@@ -161,42 +161,10 @@ pub struct Inherited<'a, 'tcx: 'a> {
161161
// one is never copied into the tcx: it is only used by regionck.
162162
fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
163163

164-
// A set of constraints that regionck must validate. Each
165-
// constraint has the form `T:'a`, meaning "some type `T` must
166-
// outlive the lifetime 'a". These constraints derive from
167-
// instantiated type parameters. So if you had a struct defined
168-
// like
169-
//
170-
// struct Foo<T:'static> { ... }
171-
//
172-
// then in some expression `let x = Foo { ... }` it will
173-
// instantiate the type parameter `T` with a fresh type `$0`. At
174-
// the same time, it will record a region obligation of
175-
// `$0:'static`. This will get checked later by regionck. (We
176-
// can't generally check these things right away because we have
177-
// to wait until types are resolved.)
178-
//
179-
// These are stored in a map keyed to the id of the innermost
180-
// enclosing fn body / static initializer expression. This is
181-
// because the location where the obligation was incurred can be
182-
// relevant with respect to which sublifetime assumptions are in
183-
// place. The reason that we store under the fn-id, and not
184-
// something more fine-grained, is so that it is easier for
185-
// regionck to be sure that it has found *all* the region
186-
// obligations (otherwise, it's easy to fail to walk to a
187-
// particular node-id).
188-
region_obligations: RefCell<NodeMap<Vec<RegionObligation<'tcx>>>>,
189-
190164
// Tracks trait obligations incurred during this function body.
191165
fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
192166
}
193167

194-
struct RegionObligation<'tcx> {
195-
sub_region: ty::Region,
196-
sup_type: Ty<'tcx>,
197-
origin: infer::SubregionOrigin<'tcx>,
198-
}
199-
200168
/// When type-checking an expression, we propagate downward
201169
/// whatever type hint we are able in the form of an `Expectation`.
202170
enum Expectation<'tcx> {
@@ -328,7 +296,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
328296
upvar_borrow_map: RefCell::new(FnvHashMap::new()),
329297
unboxed_closures: RefCell::new(DefIdMap::new()),
330298
fn_sig_map: RefCell::new(NodeMap::new()),
331-
region_obligations: RefCell::new(NodeMap::new()),
332299
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
333300
}
334301
}
@@ -1988,15 +1955,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19881955
ty: Ty<'tcx>,
19891956
r: ty::Region)
19901957
{
1991-
let mut region_obligations = self.inh.region_obligations.borrow_mut();
1992-
let region_obligation = RegionObligation { sub_region: r,
1993-
sup_type: ty,
1994-
origin: origin };
1995-
1996-
match region_obligations.entry(self.body_id) {
1997-
Vacant(entry) => { entry.set(vec![region_obligation]); },
1998-
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
1999-
}
1958+
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1959+
let region_obligation = traits::RegionObligation { sub_region: r,
1960+
sup_type: ty,
1961+
origin: origin };
1962+
fulfillment_cx.register_region_obligation(self.body_id, region_obligation);
20001963
}
20011964

20021965
pub fn add_default_region_param_bounds(&self,
@@ -5833,11 +5796,3 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
58335796
}
58345797
}
58355798

5836-
impl<'tcx> Repr<'tcx> for RegionObligation<'tcx> {
5837-
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
5838-
format!("RegionObligation(sub_region={}, sup_type={}, origin={})",
5839-
self.sub_region.repr(tcx),
5840-
self.sup_type.repr(tcx),
5841-
self.origin.repr(tcx))
5842-
}
5843-
}

src/librustc_typeck/check/regionck.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -353,18 +353,13 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
353353
fn visit_region_obligations(&mut self, node_id: ast::NodeId)
354354
{
355355
debug!("visit_region_obligations: node_id={}", node_id);
356-
let region_obligations = self.fcx.inh.region_obligations.borrow();
357-
match region_obligations.get(&node_id) {
358-
None => { }
359-
Some(vec) => {
360-
for r_o in vec.iter() {
361-
debug!("visit_region_obligations: r_o={}",
362-
r_o.repr(self.tcx()));
363-
let sup_type = self.resolve_type(r_o.sup_type);
364-
type_must_outlive(self, r_o.origin.clone(),
365-
sup_type, r_o.sub_region);
366-
}
367-
}
356+
let fulfillment_cx = self.fcx.inh.fulfillment_cx.borrow();
357+
for r_o in fulfillment_cx.region_obligations(node_id).iter() {
358+
debug!("visit_region_obligations: r_o={}",
359+
r_o.repr(self.tcx()));
360+
let sup_type = self.resolve_type(r_o.sup_type);
361+
type_must_outlive(self, r_o.origin.clone(),
362+
sup_type, r_o.sub_region);
368363
}
369364
}
370365

0 commit comments

Comments
 (0)