generate the closure type and closure kind separately.
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;
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;
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);
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>,
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,
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,
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);
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);
}
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> {
})
}
- 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_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| {
- rbml_w.emit_closure_type(ecx, &closure.closure_type);
- encode_closure_kind(rbml_w, closure.kind)
+ encode_closure_kind(rbml_w, closure_kind)
})
})
}
-> 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>)
}).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
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(
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)
}
/// 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>>,
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,
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),
}
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,
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)
}
}
}
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);
}
pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
- ccx.tcx().closures.borrow()[closure_id].kind
+ ccx.tcx().closure_kinds.borrow()[closure_id]
}
pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Datum<'tcx, Rvalue>> {
- if !ccx.tcx().closures.borrow().contains_key(&closure_id) {
+ if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) {
// Not a closure.
return None
}
fn_ty.sig.repr(fcx.tcx()),
kind);
- let closure = ty::Closure {
- closure_type: fn_ty,
- kind: kind,
- };
-
- fcx.inh.closures.borrow_mut().insert(expr_def_id, closure);
+ fcx.inh.closure_tys.borrow_mut().insert(expr_def_id, fn_ty);
+ fcx.inh.closure_kinds.borrow_mut().insert(expr_def_id, kind);
}
fn deduce_expectations_from_expected_type<'a,'tcx>(
_ => continue,
};
- let closures = self.fcx.inh.closures.borrow();
- let closure_data = match closures.get(&closure_def_id) {
- Some(data) => data,
+ let closure_kinds = self.fcx.inh.closure_kinds.borrow();
+ let closure_kind = match closure_kinds.get(&closure_def_id) {
+ Some(&k) => k,
None => {
self.tcx().sess.span_bug(
self.span,
};
// this closure doesn't implement the right kind of `Fn` trait
- if closure_data.kind != kind {
+ if closure_kind != kind {
continue;
}
adjustments: RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>,
method_map: MethodMap<'tcx>,
upvar_capture_map: RefCell<ty::UpvarCaptureMap>,
- closures: RefCell<DefIdMap<ty::Closure<'tcx>>>,
+ closure_tys: RefCell<DefIdMap<ty::ClosureTy<'tcx>>>,
+ closure_kinds: RefCell<DefIdMap<ty::ClosureKind>>,
object_cast_map: ObjectCastMap<'tcx>,
// A mapping from each fn's id to its signature, with all bound
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
- Some(self.inh.closures.borrow()[def_id].kind)
+ self.inh.closure_kinds.borrow().get(&def_id).cloned()
}
fn closure_type(&self,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
- self.inh.closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
+ self.inh.closure_tys.borrow()[def_id].subst(self.tcx(), substs)
}
fn closure_upvars(&self,
method_map: RefCell::new(FnvHashMap()),
object_cast_map: RefCell::new(NodeMap()),
upvar_capture_map: RefCell::new(FnvHashMap()),
- closures: RefCell::new(DefIdMap()),
+ closure_tys: RefCell::new(DefIdMap()),
+ closure_kinds: RefCell::new(DefIdMap()),
fn_sig_map: RefCell::new(NodeMap()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
deferred_resolutions: RefCell::new(Vec::new()),
return
}
- for (def_id, closure) in self.fcx.inh.closures.borrow().iter() {
- let closure_ty = self.resolve(&closure.closure_type,
- ResolvingClosure(*def_id));
- let closure = ty::Closure {
- closure_type: closure_ty,
- kind: closure.kind,
- };
- self.fcx.tcx().closures.borrow_mut().insert(*def_id, closure);
+ for (def_id, closure_ty) in self.fcx.inh.closure_tys.borrow().iter() {
+ let closure_ty = self.resolve(closure_ty, ResolvingClosure(*def_id));
+ self.fcx.tcx().closure_tys.borrow_mut().insert(*def_id, closure_ty);
+ }
+
+ for (def_id, &closure_kind) in self.fcx.inh.closure_kinds.borrow().iter() {
+ self.fcx.tcx().closure_kinds.borrow_mut().insert(*def_id, closure_kind);
}
}