From 71df8e655c1a7a435082de753694821f359fb8a9 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 4 Aug 2014 18:58:48 -0700 Subject: [PATCH] librustc: Encode upvar_borrow_map in metadata. --- src/librustc/metadata/common.rs | 3 ++- src/librustc/middle/astencode.rs | 43 +++++++++++++++++++++++++++++++- src/librustc/middle/freevars.rs | 8 +++--- src/librustc/middle/ty.rs | 4 +-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index a42880b2d36c..8ed471ec58a5 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -140,9 +140,10 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f tag_table_moves_map = 0x52, tag_table_capture_map = 0x53, tag_table_unboxed_closure_type = 0x54, + tag_table_upvar_borrow_map = 0x55, } static first_astencode_tag: uint = tag_ast as uint; -static last_astencode_tag: uint = tag_table_unboxed_closure_type as uint; +static last_astencode_tag: uint = tag_table_upvar_borrow_map as uint; impl astencode_tag { pub fn from_uint(value : uint) -> Option { let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index f68501bbb914..33b663dea155 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -18,6 +18,7 @@ use driver::session::Session; use metadata::decoder; use middle::def; use e = metadata::encoder; +use middle::freevars; use middle::freevars::freevar_entry; use middle::region; use metadata::tydecode; @@ -551,6 +552,15 @@ impl tr for freevar_entry { } } +impl tr for ty::UpvarBorrow { + fn tr(&self, xcx: &ExtendedDecodeContext) -> ty::UpvarBorrow { + ty::UpvarBorrow { + kind: self.kind, + region: self.region.tr(xcx) + } + } +} + // ______________________________________________________________________ // Encoding and decoding of MethodCallee @@ -1061,7 +1071,29 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, Ok(encode_freevar_entry(rbml_w, fv_entry)) }); }) - }) + }); + + for freevar in fv.iter() { + match freevars::get_capture_mode(tcx, id) { + freevars::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| { + let var_id = freevar.def.def_id().node; + let upvar_id = ty::UpvarId { + var_id: var_id, + closure_expr_id: id + }; + let upvar_borrow = tcx.upvar_borrow_map.borrow() + .get_copy(&upvar_id); + var_id.encode(rbml_w); + upvar_borrow.encode(rbml_w); + }) + }) + } + _ => {} + } + } } let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id }; @@ -1468,6 +1500,15 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, }).unwrap().move_iter().collect(); dcx.tcx.freevars.borrow_mut().insert(id, fv_info); } + c::tag_table_upvar_borrow_map => { + let var_id: ast::NodeId = Decodable::decode(val_dsr).unwrap(); + let upvar_id = ty::UpvarId { + var_id: xcx.tr_id(var_id), + closure_expr_id: id + }; + let ub: ty::UpvarBorrow = Decodable::decode(val_dsr).unwrap(); + dcx.tcx.upvar_borrow_map.borrow_mut().insert(upvar_id, ub.tr(xcx)); + } c::tag_table_tcache => { let pty = val_dsr.read_polytype(xcx); let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id }; diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index f6887718ec13..eda567f7d187 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -14,6 +14,7 @@ #![allow(non_camel_case_types)] use middle::def; +use middle::mem_categorization::Typer; use middle::resolve; use middle::ty; use util::nodemap::{DefIdSet, NodeMap, NodeSet}; @@ -147,11 +148,8 @@ pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| } } -pub fn get_capture_mode(tcx: &ty::ctxt, - closure_expr_id: ast::NodeId) - -> CaptureMode -{ - let fn_ty = ty::node_id_to_type(tcx, closure_expr_id); +pub fn get_capture_mode(tcx: &T, closure_expr_id: ast::NodeId) -> CaptureMode { + let fn_ty = tcx.node_ty(closure_expr_id).ok().expect("couldn't find closure ty?"); match ty::ty_closure_store(fn_ty) { ty::RegionTraitStore(..) => CaptureByRef, ty::UniqTraitStore => CaptureByValue diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 0cc5486013aa..a4588da1bd7d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -539,7 +539,7 @@ pub struct UpvarId { pub closure_expr_id: ast::NodeId, } -#[deriving(Clone, PartialEq, Eq, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)] pub enum BorrowKind { /// Data must be immutable and is aliasable. ImmBorrow, @@ -634,7 +634,7 @@ pub enum BorrowKind { * the closure, so sometimes it is necessary for them to be larger * than the closure lifetime itself. */ -#[deriving(PartialEq, Clone)] +#[deriving(PartialEq, Clone, Encodable, Decodable)] pub struct UpvarBorrow { pub kind: BorrowKind, pub region: ty::Region,