Separate out the unboxed closure table into two tables, so that we can

generate the closure type and closure kind separately.
This commit is contained in:
Niko Matsakis 2015-01-30 11:37:23 -05:00
parent 92f94765ec
commit 2f465869fd
12 changed files with 81 additions and 148 deletions

View file

@ -139,10 +139,11 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
tag_table_adjustments = 0x51,
tag_table_moves_map = 0x52,
tag_table_capture_map = 0x53,
tag_table_closures = 0x54,
tag_table_upvar_capture_map = 0x55,
tag_table_capture_modes = 0x56,
tag_table_object_cast_map = 0x57,
tag_table_closure_tys = 0x54,
tag_table_closure_kinds = 0x55,
tag_table_upvar_capture_map = 0x56,
tag_table_capture_modes = 0x57,
tag_table_object_cast_map = 0x58,
}
static first_astencode_tag: uint = tag_ast as uint;
@ -225,10 +226,7 @@ pub struct LinkMeta {
pub crate_hash: Svh,
}
pub const tag_closures: uint = 0x95;
pub const tag_closure: uint = 0x96;
pub const tag_closure_type: uint = 0x97;
pub const tag_closure_kind: uint = 0x98;
// GAP 0x94...0x98
pub const tag_struct_fields: uint = 0x99;
pub const tag_struct_field: uint = 0x9a;

View file

@ -618,17 +618,6 @@ fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
rbml_w.end_tag();
}
fn encode_closure_kind(rbml_w: &mut Encoder, kind: ty::ClosureKind) {
rbml_w.start_tag(tag_closure_kind);
let ch = match kind {
ty::FnClosureKind => 'f',
ty::FnMutClosureKind => 'm',
ty::FnOnceClosureKind => 'o',
};
rbml_w.wr_str(&ch.to_string()[]);
rbml_w.end_tag();
}
fn encode_explicit_self(rbml_w: &mut Encoder,
explicit_self: &ty::ExplicitSelfCategory) {
rbml_w.start_tag(tag_item_trait_method_explicit_self);
@ -1843,24 +1832,6 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
rbml_w.end_tag();
}
fn encode_closures<'a>(ecx: &'a EncodeContext, rbml_w: &'a mut Encoder) {
rbml_w.start_tag(tag_closures);
for (closure_id, closure) in ecx.tcx.closures.borrow().iter() {
if closure_id.krate != ast::LOCAL_CRATE {
continue
}
rbml_w.start_tag(tag_closure);
encode_def_id(rbml_w, *closure_id);
rbml_w.start_tag(tag_closure_type);
write_closure_type(ecx, rbml_w, &closure.closure_type);
rbml_w.end_tag();
encode_closure_kind(rbml_w, closure.kind);
rbml_w.end_tag();
}
rbml_w.end_tag();
}
fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &ast::Crate) {
struct StructFieldVisitor<'a, 'b:'a> {
rbml_w: &'a mut Encoder<'b>,
@ -2069,7 +2040,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
native_lib_bytes: u64,
plugin_registrar_fn_bytes: u64,
macro_defs_bytes: u64,
closure_bytes: u64,
impl_bytes: u64,
misc_bytes: u64,
item_bytes: u64,
@ -2084,7 +2054,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
native_lib_bytes: 0,
plugin_registrar_fn_bytes: 0,
macro_defs_bytes: 0,
closure_bytes: 0,
impl_bytes: 0,
misc_bytes: 0,
item_bytes: 0,
@ -2154,11 +2123,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
encode_macro_defs(&mut rbml_w, krate);
stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
// Encode the types of all closures in this crate.
i = rbml_w.writer.tell().unwrap();
encode_closures(&ecx, &mut rbml_w);
stats.closure_bytes = rbml_w.writer.tell().unwrap() - i;
// Encode the def IDs of impls, for coherence checking.
i = rbml_w.writer.tell().unwrap();
encode_impls(&ecx, krate, &mut rbml_w);
@ -2199,7 +2163,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
println!(" native bytes: {}", stats.native_lib_bytes);
println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
println!(" macro def bytes: {}", stats.macro_defs_bytes);
println!(" closure bytes: {}", stats.closure_bytes);
println!(" impl bytes: {}", stats.impl_bytes);
println!(" misc bytes: {}", stats.misc_bytes);
println!(" item bytes: {}", stats.item_bytes);

View file

@ -647,30 +647,7 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
}
pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
use serialize::Encoder;
ebml_w.emit_enum("ClosureKind", |ebml_w| {
match kind {
ty::FnClosureKind => {
ebml_w.emit_enum_variant("FnClosureKind", 0, 3, |_| {
Ok(())
})
}
ty::FnMutClosureKind => {
ebml_w.emit_enum_variant("FnMutClosureKind", 1, 3, |_| {
Ok(())
})
}
ty::FnOnceClosureKind => {
ebml_w.emit_enum_variant("FnOnceClosureKind",
2,
3,
|_| {
Ok(())
})
}
}
}).unwrap()
kind.encode(ebml_w).unwrap();
}
pub trait vtable_decoder_helpers<'tcx> {
@ -1310,12 +1287,20 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}
for closure in tcx.closures.borrow().get(&ast_util::local_def(id)).iter() {
rbml_w.tag(c::tag_table_closures, |rbml_w| {
for &closure_type in tcx.closure_tys.borrow().get(&ast_util::local_def(id)).iter() {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
rbml_w.tag(c::tag_table_val, |rbml_w| {
rbml_w.emit_closure_type(ecx, &closure.closure_type);
encode_closure_kind(rbml_w, closure.kind)
rbml_w.emit_closure_type(ecx, closure_type);
})
})
}
for &&closure_kind in tcx.closure_kinds.borrow().get(&ast_util::local_def(id)).iter() {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
rbml_w.tag(c::tag_table_val, |rbml_w| {
encode_closure_kind(rbml_w, closure_kind)
})
})
}
@ -1354,8 +1339,10 @@ trait rbml_decoder_decoder_helpers<'tcx> {
-> subst::Substs<'tcx>;
fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoAdjustment<'tcx>;
fn read_closure<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::Closure<'tcx>;
fn read_closure_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ClosureKind;
fn read_closure_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ClosureTy<'tcx>;
fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoDerefRef<'tcx>;
fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -1782,35 +1769,23 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
}).unwrap()
}
fn read_closure<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::Closure<'tcx> {
let closure_type = self.read_opaque(|this, doc| {
fn read_closure_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ClosureKind
{
Decodable::decode(self).ok().unwrap()
}
fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ClosureTy<'tcx>
{
self.read_opaque(|this, doc| {
Ok(tydecode::parse_ty_closure_data(
doc.data,
dcx.cdata.cnum,
doc.start,
dcx.tcx,
|s, a| this.convert_def_id(dcx, s, a)))
}).unwrap();
let variants = &[
"FnClosureKind",
"FnMutClosureKind",
"FnOnceClosureKind"
];
let kind = self.read_enum("ClosureKind", |this| {
this.read_enum_variant(variants, |_, i| {
Ok(match i {
0 => ty::FnClosureKind,
1 => ty::FnMutClosureKind,
2 => ty::FnOnceClosureKind,
_ => panic!("bad enum variant for ty::ClosureKind"),
})
})
}).unwrap();
ty::Closure {
closure_type: closure_type,
kind: kind,
}
}).unwrap()
}
/// Converts a def-id that appears in a type. The correct
@ -1937,11 +1912,17 @@ fn decode_side_tables(dcx: &DecodeContext,
let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
dcx.tcx.adjustments.borrow_mut().insert(id, adj);
}
c::tag_table_closures => {
let closure =
val_dsr.read_closure(dcx);
dcx.tcx.closures.borrow_mut().insert(ast_util::local_def(id),
closure);
c::tag_table_closure_tys => {
let closure_ty =
val_dsr.read_closure_ty(dcx);
dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id),
closure_ty);
}
c::tag_table_closure_kinds => {
let closure_kind =
val_dsr.read_closure_kind(dcx);
dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id),
closure_kind);
}
_ => {
dcx.tcx.sess.bug(

View file

@ -260,12 +260,10 @@ impl OverloadedCallType {
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
-> OverloadedCallType {
let trait_did =
tcx.closures
tcx.closure_kinds
.borrow()
.get(&closure_did)
.expect("OverloadedCallType::from_closure: didn't \
find closure id")
.kind
.expect("OverloadedCallType::from_closure: didn't find closure id")
.trait_did(tcx);
OverloadedCallType::from_trait_id(tcx, trait_did)
}

View file

@ -790,7 +790,11 @@ pub struct ctxt<'tcx> {
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closures: RefCell<DefIdMap<Closure<'tcx>>>,
pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
lint::LevelSource>>,
@ -2251,16 +2255,7 @@ pub struct ItemSubsts<'tcx> {
pub substs: Substs<'tcx>,
}
/// Records information about each closure.
#[derive(Clone)]
pub struct Closure<'tcx> {
/// The type of the closure.
pub closure_type: ClosureTy<'tcx>,
/// The kind of closure this is.
pub kind: ClosureKind,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
pub enum ClosureKind {
FnClosureKind,
FnMutClosureKind,
@ -2399,7 +2394,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
extern_const_variants: RefCell::new(DefIdMap()),
method_map: RefCell::new(FnvHashMap()),
dependency_formats: RefCell::new(FnvHashMap()),
closures: RefCell::new(DefIdMap()),
closure_kinds: RefCell::new(DefIdMap()),
closure_tys: RefCell::new(DefIdMap()),
node_lint_levels: RefCell::new(FnvHashMap()),
transmute_restrictions: RefCell::new(Vec::new()),
stability: RefCell::new(stability),
@ -2446,7 +2442,7 @@ impl<'tcx> ctxt<'tcx> {
}
pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
self.closures.borrow()[def_id].kind
self.closure_kinds.borrow()[def_id]
}
pub fn closure_type(&self,
@ -2454,7 +2450,7 @@ impl<'tcx> ctxt<'tcx> {
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.closures.borrow()[def_id].closure_type.subst(self, substs)
self.closure_tys.borrow()[def_id].subst(self, substs)
}
}

View file

@ -405,9 +405,9 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
}
ty_str => "str".to_string(),
ty_closure(ref did, _, substs) => {
let closures = cx.closures.borrow();
closures.get(did).map(|cl| {
closure_to_string(cx, &cl.closure_type.subst(cx, substs))
let closure_tys = cx.closure_tys.borrow();
closure_tys.get(did).map(|closure_type| {
closure_to_string(cx, &closure_type.subst(cx, substs))
}).unwrap_or_else(|| {
if did.krate == ast::LOCAL_CRATE {
let span = cx.map.span(did.node);