rustc: move type definitions from middle::freevars to middle::ty.
This commit is contained in:
parent
6536a0c0d6
commit
5c192ae123
@ -18,13 +18,12 @@ use driver::session::Session;
|
||||
use metadata::decoder;
|
||||
use middle::def;
|
||||
use metadata::encoder as e;
|
||||
use middle::freevars::{CaptureMode, freevar_entry};
|
||||
use middle::freevars;
|
||||
use middle::region;
|
||||
use metadata::tydecode;
|
||||
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
|
||||
use metadata::tydecode::{RegionParameter};
|
||||
use metadata::tyencode;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst;
|
||||
use middle::subst::VecPerParamSpace;
|
||||
use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
|
||||
@ -540,36 +539,36 @@ impl tr for ty::TraitStore {
|
||||
// ______________________________________________________________________
|
||||
// Encoding and decoding of freevar information
|
||||
|
||||
fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &freevar_entry) {
|
||||
fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
|
||||
(*fv).encode(rbml_w).unwrap();
|
||||
}
|
||||
|
||||
fn encode_capture_mode(rbml_w: &mut Encoder, cm: CaptureMode) {
|
||||
fn encode_capture_mode(rbml_w: &mut Encoder, cm: ast::CaptureClause) {
|
||||
cm.encode(rbml_w).unwrap();
|
||||
}
|
||||
|
||||
trait rbml_decoder_helper {
|
||||
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
|
||||
-> freevar_entry;
|
||||
fn read_capture_mode(&mut self) -> CaptureMode;
|
||||
-> ty::Freevar;
|
||||
fn read_capture_mode(&mut self) -> ast::CaptureClause;
|
||||
}
|
||||
|
||||
impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
|
||||
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
|
||||
-> freevar_entry {
|
||||
let fv: freevar_entry = Decodable::decode(self).unwrap();
|
||||
-> ty::Freevar {
|
||||
let fv: ty::Freevar = Decodable::decode(self).unwrap();
|
||||
fv.tr(dcx)
|
||||
}
|
||||
|
||||
fn read_capture_mode(&mut self) -> CaptureMode {
|
||||
let cm: CaptureMode = Decodable::decode(self).unwrap();
|
||||
fn read_capture_mode(&mut self) -> ast::CaptureClause {
|
||||
let cm: ast::CaptureClause = Decodable::decode(self).unwrap();
|
||||
cm
|
||||
}
|
||||
}
|
||||
|
||||
impl tr for freevar_entry {
|
||||
fn tr(&self, dcx: &DecodeContext) -> freevar_entry {
|
||||
freevar_entry {
|
||||
impl tr for ty::Freevar {
|
||||
fn tr(&self, dcx: &DecodeContext) -> ty::Freevar {
|
||||
ty::Freevar {
|
||||
def: self.def.tr(dcx),
|
||||
span: self.span.tr(dcx),
|
||||
}
|
||||
@ -1291,8 +1290,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
});
|
||||
|
||||
for freevar in fv.iter() {
|
||||
match freevars::get_capture_mode(tcx, id) {
|
||||
freevars::CaptureByRef => {
|
||||
match tcx.capture_mode(id) {
|
||||
ast::CaptureByRef => {
|
||||
rbml_w.tag(c::tag_table_upvar_borrow_map, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.tag(c::tag_table_val, |rbml_w| {
|
||||
|
@ -17,6 +17,7 @@
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::def;
|
||||
use middle::freevars;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::pat_util;
|
||||
use middle::ty;
|
||||
use middle::typeck::{MethodCall, MethodObject, MethodOrigin, MethodParam};
|
||||
@ -911,12 +912,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
||||
debug!("walk_captures({})", closure_expr.repr(self.tcx()));
|
||||
|
||||
let tcx = self.typer.tcx();
|
||||
freevars::with_freevars(tcx, closure_expr.id, |freevars| {
|
||||
match freevars::get_capture_mode(self.tcx(), closure_expr.id) {
|
||||
freevars::CaptureByRef => {
|
||||
ty::with_freevars(tcx, closure_expr.id, |freevars| {
|
||||
match self.tcx().capture_mode(closure_expr.id) {
|
||||
ast::CaptureByRef => {
|
||||
self.walk_by_ref_captures(closure_expr, freevars);
|
||||
}
|
||||
freevars::CaptureByValue => {
|
||||
ast::CaptureByValue => {
|
||||
self.walk_by_value_captures(closure_expr, freevars);
|
||||
}
|
||||
}
|
||||
@ -925,7 +926,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
||||
|
||||
fn walk_by_ref_captures(&mut self,
|
||||
closure_expr: &ast::Expr,
|
||||
freevars: &[freevars::freevar_entry]) {
|
||||
freevars: &[ty::Freevar]) {
|
||||
for freevar in freevars.iter() {
|
||||
let id_var = freevar.def.def_id().node;
|
||||
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
|
||||
@ -950,7 +951,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
||||
|
||||
fn walk_by_value_captures(&mut self,
|
||||
closure_expr: &ast::Expr,
|
||||
freevars: &[freevars::freevar_entry]) {
|
||||
freevars: &[ty::Freevar]) {
|
||||
for freevar in freevars.iter() {
|
||||
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
|
||||
closure_expr.span,
|
||||
|
@ -14,7 +14,6 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use middle::def;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::resolve;
|
||||
use middle::ty;
|
||||
use util::nodemap::{NodeMap, NodeSet};
|
||||
@ -24,27 +23,6 @@ use syntax::codemap::Span;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
|
||||
#[deriving(Clone, Decodable, Encodable, Show)]
|
||||
pub enum CaptureMode {
|
||||
/// Copy/move the value into the environment.
|
||||
CaptureByValue,
|
||||
|
||||
/// Access by reference (used for stack closures).
|
||||
CaptureByRef
|
||||
}
|
||||
|
||||
// A vector of defs representing the free variables referred to in a function.
|
||||
// (The def_upvar will already have been stripped).
|
||||
#[deriving(Encodable, Decodable)]
|
||||
pub struct freevar_entry {
|
||||
pub def: def::Def, //< The variable being accessed free.
|
||||
pub span: Span //< First span where it is accessed (there can be multiple)
|
||||
}
|
||||
|
||||
pub type freevar_map = NodeMap<Vec<freevar_entry>>;
|
||||
|
||||
pub type CaptureModeMap = NodeMap<CaptureMode>;
|
||||
|
||||
struct CollectFreevarsVisitor<'a, 'b:'a> {
|
||||
node_id: ast::NodeId,
|
||||
seen: NodeSet,
|
||||
@ -60,7 +38,7 @@ impl<'a, 'b, 'v> Visitor<'v> for CollectFreevarsVisitor<'a, 'b> {
|
||||
fn visit_expr(&mut self, expr: &ast::Expr) {
|
||||
match expr.node {
|
||||
ast::ExprProc(..) => {
|
||||
self.cx.capture_mode_map.insert(expr.id, CaptureByValue);
|
||||
self.cx.capture_mode_map.insert(expr.id, ast::CaptureByValue);
|
||||
self.depth += 1;
|
||||
visit::walk_expr(self, expr);
|
||||
self.depth -= 1;
|
||||
@ -68,22 +46,14 @@ impl<'a, 'b, 'v> Visitor<'v> for CollectFreevarsVisitor<'a, 'b> {
|
||||
ast::ExprFnBlock(_, _, _) => {
|
||||
// NOTE(stage0): After snapshot, change to:
|
||||
//
|
||||
//let capture_mode = match capture_clause {
|
||||
// ast::CaptureByValue => CaptureByValue,
|
||||
// ast::CaptureByRef => CaptureByRef,
|
||||
//};
|
||||
let capture_mode = CaptureByRef;
|
||||
self.cx.capture_mode_map.insert(expr.id, capture_mode);
|
||||
//self.cx.capture_mode_map.insert(expr.id, capture_clause);
|
||||
self.cx.capture_mode_map.insert(expr.id, ast::CaptureByRef);
|
||||
self.depth += 1;
|
||||
visit::walk_expr(self, expr);
|
||||
self.depth -= 1;
|
||||
}
|
||||
ast::ExprUnboxedFn(capture_clause, _, _, _) => {
|
||||
let capture_mode = match capture_clause {
|
||||
ast::CaptureByValue => CaptureByValue,
|
||||
ast::CaptureByRef => CaptureByRef,
|
||||
};
|
||||
self.cx.capture_mode_map.insert(expr.id, capture_mode);
|
||||
self.cx.capture_mode_map.insert(expr.id, capture_clause);
|
||||
self.depth += 1;
|
||||
visit::walk_expr(self, expr);
|
||||
self.depth -= 1;
|
||||
@ -111,7 +81,7 @@ impl<'a, 'b, 'v> Visitor<'v> for CollectFreevarsVisitor<'a, 'b> {
|
||||
},
|
||||
_ => return
|
||||
};
|
||||
self.cx.freevars.find_or_insert(self.node_id, vec![]).push(freevar_entry {
|
||||
self.cx.freevars.find_or_insert(self.node_id, vec![]).push(ty::Freevar {
|
||||
def: def,
|
||||
span: expr.span,
|
||||
});
|
||||
@ -124,8 +94,8 @@ impl<'a, 'b, 'v> Visitor<'v> for CollectFreevarsVisitor<'a, 'b> {
|
||||
|
||||
struct AnnotateFreevarsVisitor<'a> {
|
||||
def_map: &'a resolve::DefMap,
|
||||
freevars: freevar_map,
|
||||
capture_mode_map: CaptureModeMap,
|
||||
freevars: ty::FreevarMap,
|
||||
capture_mode_map: ty::CaptureModeMap,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for AnnotateFreevarsVisitor<'a> {
|
||||
@ -147,7 +117,7 @@ impl<'a, 'v> Visitor<'v> for AnnotateFreevarsVisitor<'a> {
|
||||
// node of interest rather than building up the free variables in
|
||||
// one pass. This could be improved upon if it turns out to matter.
|
||||
pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
|
||||
-> (freevar_map, CaptureModeMap) {
|
||||
-> (ty::FreevarMap, ty::CaptureModeMap) {
|
||||
let mut visitor = AnnotateFreevarsVisitor {
|
||||
def_map: def_map,
|
||||
freevars: NodeMap::new(),
|
||||
@ -156,15 +126,3 @@ pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
(visitor.freevars, visitor.capture_mode_map)
|
||||
}
|
||||
|
||||
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T {
|
||||
match tcx.freevars.borrow().find(&fid) {
|
||||
None => fail!("with_freevars: {} has no freevars", fid),
|
||||
Some(d) => f(d.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_capture_mode<'tcx, T:Typer<'tcx>>(tcx: &T, closure_expr_id: ast::NodeId)
|
||||
-> CaptureMode {
|
||||
tcx.capture_mode(closure_expr_id)
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use middle::freevars::freevar_entry;
|
||||
use middle::freevars;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst;
|
||||
use middle::ty;
|
||||
@ -146,10 +144,10 @@ fn check_item(cx: &mut Context, item: &Item) {
|
||||
fn with_appropriate_checker(cx: &Context,
|
||||
id: NodeId,
|
||||
fn_span: Span,
|
||||
b: |checker: |&Context, &freevar_entry||) {
|
||||
b: |checker: |&Context, &ty::Freevar||) {
|
||||
fn check_for_uniq(cx: &Context,
|
||||
fn_span: Span,
|
||||
fv: &freevar_entry,
|
||||
fv: &ty::Freevar,
|
||||
bounds: ty::BuiltinBounds) {
|
||||
// all captured data must be owned, regardless of whether it is
|
||||
// moved in or copied in.
|
||||
@ -162,7 +160,7 @@ fn with_appropriate_checker(cx: &Context,
|
||||
fn check_for_block(cx: &Context,
|
||||
fn_span: Span,
|
||||
fn_id: NodeId,
|
||||
fv: &freevar_entry,
|
||||
fv: &ty::Freevar,
|
||||
bounds: ty::BuiltinBounds) {
|
||||
let id = fv.def.def_id().node;
|
||||
let var_t = ty::node_id_to_type(cx.tcx, id);
|
||||
@ -177,7 +175,7 @@ fn with_appropriate_checker(cx: &Context,
|
||||
bounds, Some(var_t));
|
||||
}
|
||||
|
||||
fn check_for_bare(cx: &Context, fv: &freevar_entry) {
|
||||
fn check_for_bare(cx: &Context, fv: &ty::Freevar) {
|
||||
span_err!(cx.tcx.sess, fv.span, E0143,
|
||||
"can't capture dynamic environment in a fn item; \
|
||||
use the || {} closure form instead", "{ ... }");
|
||||
@ -227,7 +225,7 @@ fn check_fn(
|
||||
|
||||
// <Check kinds on free variables:
|
||||
with_appropriate_checker(cx, fn_id, sp, |chk| {
|
||||
freevars::with_freevars(cx.tcx, fn_id, |freevars| {
|
||||
ty::with_freevars(cx.tcx, fn_id, |freevars| {
|
||||
for fv in freevars.iter() {
|
||||
chk(cx, fv);
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
||||
// in better error messages than just pointing at the closure
|
||||
// construction site.
|
||||
let mut call_caps = Vec::new();
|
||||
freevars::with_freevars(ir.tcx, expr.id, |freevars| {
|
||||
ty::with_freevars(ir.tcx, expr.id, |freevars| {
|
||||
for fv in freevars.iter() {
|
||||
match fv.def {
|
||||
DefLocal(rv) => {
|
||||
|
@ -273,7 +273,7 @@ pub trait Typer<'tcx> {
|
||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>;
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> freevars::CaptureMode;
|
||||
-> ast::CaptureClause;
|
||||
fn unboxed_closures<'a>(&'a self)
|
||||
-> &'a RefCell<DefIdMap<ty::UnboxedClosure>>;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use driver::config::FullDebugInfo;
|
||||
use llvm::ValueRef;
|
||||
use middle::def;
|
||||
use middle::freevars;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
@ -100,7 +101,7 @@ use syntax::ast_util;
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
pub struct EnvValue {
|
||||
action: freevars::CaptureMode,
|
||||
action: ast::CaptureClause,
|
||||
datum: Datum<Lvalue>
|
||||
}
|
||||
|
||||
@ -120,8 +121,8 @@ pub fn mk_closure_tys(tcx: &ty::ctxt,
|
||||
// converted to ptrs.
|
||||
let bound_tys = bound_values.iter().map(|bv| {
|
||||
match bv.action {
|
||||
freevars::CaptureByValue => bv.datum.ty,
|
||||
freevars::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty)
|
||||
ast::CaptureByValue => bv.datum.ty,
|
||||
ast::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty)
|
||||
}
|
||||
}).collect();
|
||||
let cdata_ty = ty::mk_tup(tcx, bound_tys);
|
||||
@ -208,10 +209,10 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]);
|
||||
|
||||
match bv.action {
|
||||
freevars::CaptureByValue => {
|
||||
ast::CaptureByValue => {
|
||||
bcx = bv.datum.store_to(bcx, bound_data);
|
||||
}
|
||||
freevars::CaptureByRef => {
|
||||
ast::CaptureByRef => {
|
||||
Store(bcx, bv.datum.to_llref(), bound_data);
|
||||
}
|
||||
}
|
||||
@ -223,8 +224,8 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Given a context and a list of upvars, build a closure. This just
|
||||
// collects the upvars and packages them up for store_environment.
|
||||
fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
|
||||
freevar_mode: freevars::CaptureMode,
|
||||
freevars: &Vec<freevars::freevar_entry>,
|
||||
freevar_mode: ast::CaptureClause,
|
||||
freevars: &Vec<ty::Freevar>,
|
||||
store: ty::TraitStore)
|
||||
-> ClosureResult<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("closure::build_closure");
|
||||
@ -247,7 +248,7 @@ fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
|
||||
// with the upvars and type descriptors.
|
||||
fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
cdata_ty: ty::t,
|
||||
freevars: &Vec<freevars::freevar_entry>,
|
||||
freevars: &Vec<ty::Freevar>,
|
||||
store: ty::TraitStore)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("closure::load_environment");
|
||||
@ -301,7 +302,7 @@ fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fn load_unboxed_closure_environment<'blk, 'tcx>(
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
arg_scope_id: ScopeId,
|
||||
freevars: &Vec<freevars::freevar_entry>,
|
||||
freevars: &Vec<ty::Freevar>,
|
||||
closure_id: ast::DefId)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("closure::load_environment");
|
||||
@ -386,11 +387,9 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// set an inline hint for all closures
|
||||
set_inline_hint(llfn);
|
||||
|
||||
let freevar_mode = freevars::get_capture_mode(tcx, id);
|
||||
let freevars: Vec<freevars::freevar_entry> =
|
||||
freevars::with_freevars(tcx,
|
||||
id,
|
||||
|fv| fv.iter().map(|&fv| fv).collect());
|
||||
let freevar_mode = tcx.capture_mode(id);
|
||||
let freevars: Vec<ty::Freevar> =
|
||||
ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect());
|
||||
|
||||
let ClosureResult {
|
||||
llbox,
|
||||
@ -476,10 +475,8 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
.clone();
|
||||
let function_type = ty::mk_closure(bcx.tcx(), function_type);
|
||||
|
||||
let freevars: Vec<freevars::freevar_entry> =
|
||||
freevars::with_freevars(bcx.tcx(),
|
||||
id,
|
||||
|fv| fv.iter().map(|&fv| fv).collect());
|
||||
let freevars: Vec<ty::Freevar> =
|
||||
ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect());
|
||||
let freevars_ptr = &freevars;
|
||||
|
||||
trans_closure(bcx.ccx(),
|
||||
|
@ -525,7 +525,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
|
||||
}
|
||||
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> freevars::CaptureMode {
|
||||
-> ast::CaptureClause {
|
||||
self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ use metadata::csearch;
|
||||
use middle::const_eval;
|
||||
use middle::def;
|
||||
use middle::dependency_format;
|
||||
use middle::freevars::CaptureModeMap;
|
||||
use middle::freevars;
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
|
||||
use middle::lang_items::{FnOnceTraitLangItem, OpaqueStructLangItem};
|
||||
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
|
||||
@ -480,7 +478,7 @@ pub struct ctxt<'tcx> {
|
||||
|
||||
pub map: ast_map::Map<'tcx>,
|
||||
pub intrinsic_defs: RefCell<DefIdMap<t>>,
|
||||
pub freevars: RefCell<freevars::freevar_map>,
|
||||
pub freevars: RefCell<FreevarMap>,
|
||||
pub tcache: type_cache,
|
||||
pub rcache: creader_cache,
|
||||
pub short_names_cache: RefCell<HashMap<t, String>>,
|
||||
@ -1463,8 +1461,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
||||
dm: resolve::DefMap,
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
map: ast_map::Map<'tcx>,
|
||||
freevars: freevars::freevar_map,
|
||||
capture_modes: freevars::CaptureModeMap,
|
||||
freevars: FreevarMap,
|
||||
capture_modes: CaptureModeMap,
|
||||
region_maps: middle::region::RegionMaps,
|
||||
lang_items: middle::lang_items::LanguageItems,
|
||||
stability: stability::Index) -> ctxt<'tcx> {
|
||||
@ -5615,7 +5613,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
|
||||
}
|
||||
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> freevars::CaptureMode {
|
||||
-> ast::CaptureClause {
|
||||
self.capture_modes.borrow().get_copy(&closure_expr_id)
|
||||
}
|
||||
|
||||
@ -5686,3 +5684,24 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// A free variable referred to in a function.
|
||||
#[deriving(Encodable, Decodable)]
|
||||
pub struct Freevar {
|
||||
/// The variable being accessed free.
|
||||
pub def: def::Def,
|
||||
|
||||
// First span where it is accessed (there can be multiple).
|
||||
pub span: Span
|
||||
}
|
||||
|
||||
pub type FreevarMap = NodeMap<Vec<Freevar>>;
|
||||
|
||||
pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
|
||||
|
||||
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
|
||||
match tcx.freevars.borrow().find(&fid) {
|
||||
None => fail!("with_freevars: {} has no freevars", fid),
|
||||
Some(d) => f(d.as_slice())
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
self.ccx.tcx.upvar_borrow(upvar_id)
|
||||
}
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> freevars::CaptureMode {
|
||||
-> ast::CaptureClause {
|
||||
self.ccx.tcx.capture_mode(closure_expr_id)
|
||||
}
|
||||
fn unboxed_closures<'a>(&'a self)
|
||||
|
@ -478,7 +478,7 @@ impl<'fcx, 'tcx> mc::Typer<'tcx> for Rcx<'fcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> freevars::CaptureMode {
|
||||
-> ast::CaptureClause {
|
||||
self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
|
||||
}
|
||||
|
||||
@ -851,7 +851,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
..}) => {
|
||||
// For closure, ensure that the variables outlive region
|
||||
// bound, since they are captured by reference.
|
||||
freevars::with_freevars(tcx, expr.id, |freevars| {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
if freevars.is_empty() {
|
||||
// No free variables means that the environment
|
||||
// will be NULL at runtime and hence the closure
|
||||
@ -874,13 +874,13 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
..}) => {
|
||||
// For proc, ensure that the *types* of the variables
|
||||
// outlive region bound, since they are captured by value.
|
||||
freevars::with_freevars(tcx, expr.id, |freevars| {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
ensure_free_variable_types_outlive_closure_bound(
|
||||
rcx, bounds.region_bound, expr, freevars);
|
||||
});
|
||||
}
|
||||
ty::ty_unboxed_closure(_, region) => {
|
||||
freevars::with_freevars(tcx, expr.id, |freevars| {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
// No free variables means that there is no environment and
|
||||
// hence the closure has static lifetime. Otherwise, the
|
||||
// closure must not outlive the variables it closes over
|
||||
@ -906,7 +906,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
store: ty::RegionTraitStore(..),
|
||||
..
|
||||
}) => {
|
||||
freevars::with_freevars(tcx, expr.id, |freevars| {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
propagate_upupvar_borrow_kind(rcx, expr, freevars);
|
||||
})
|
||||
}
|
||||
@ -917,7 +917,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
rcx: &mut Rcx,
|
||||
region_bound: ty::Region,
|
||||
expr: &ast::Expr,
|
||||
freevars: &[freevars::freevar_entry])
|
||||
freevars: &[ty::Freevar])
|
||||
{
|
||||
/*!
|
||||
* Make sure that the type of all free variables referenced
|
||||
@ -950,7 +950,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
rcx: &mut Rcx,
|
||||
region_bound: ty::Region,
|
||||
expr: &ast::Expr,
|
||||
freevars: &[freevars::freevar_entry])
|
||||
freevars: &[ty::Freevar])
|
||||
{
|
||||
/*!
|
||||
* Make sure that all free variables referenced inside the
|
||||
@ -1000,7 +1000,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
|
||||
fn propagate_upupvar_borrow_kind(rcx: &mut Rcx,
|
||||
expr: &ast::Expr,
|
||||
freevars: &[freevars::freevar_entry]) {
|
||||
freevars: &[ty::Freevar]) {
|
||||
let tcx = rcx.fcx.ccx.tcx;
|
||||
debug!("propagate_upupvar_borrow_kind({})", expr.repr(tcx));
|
||||
for freevar in freevars.iter() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user