diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 242ab630a20e..bf2f5bd22c46 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -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; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 6767f77de84b..e09d29b98b09 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -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); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 902c029fef4b..376432473413 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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( diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 188a56135ec3..4a0bed57433a 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f1e73ddc5a1e..fb1d9fcada1c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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>>, + pub closure_kinds: RefCell>, + + /// Records the type of each closure. The def ID is the ID of the + /// expression defining the closure. + pub closure_tys: RefCell>>, pub node_lint_levels: RefCell>, @@ -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) } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6c723a583807..15cf37dc2f2f 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 1b212aca3303..9ec3db0f602a 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -273,7 +273,7 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } 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>, diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index a15ede095a70..8473ce1b797e 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -125,7 +125,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc closure_id: ast::DefId, substs: &Substs<'tcx>) -> Option> { - if !ccx.tcx().closures.borrow().contains_key(&closure_id) { + if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) { // Not a closure. return None } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 906a8a33314c..22390b9e98b1 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -129,12 +129,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, 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>( diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 2e366f445074..8000776ad45f 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -598,9 +598,9 @@ impl<'a,'tcx> ProbeContext<'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, @@ -610,7 +610,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { }; // this closure doesn't implement the right kind of `Fn` trait - if closure_data.kind != kind { + if closure_kind != kind { continue; } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c58377fc87bd..ed195035a41d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -160,7 +160,8 @@ pub struct Inherited<'a, 'tcx: 'a> { adjustments: RefCell>>, method_map: MethodMap<'tcx>, upvar_capture_map: RefCell, - closures: RefCell>>, + closure_tys: RefCell>>, + closure_kinds: RefCell>, object_cast_map: ObjectCastMap<'tcx>, // A mapping from each fn's id to its signature, with all bound @@ -352,7 +353,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { def_id: ast::DefId) -> Option { - Some(self.inh.closures.borrow()[def_id].kind) + self.inh.closure_kinds.borrow().get(&def_id).cloned() } fn closure_type(&self, @@ -360,7 +361,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { 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, @@ -386,7 +387,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { 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()), diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index f7e1afed8fc5..0eaecf8ac057 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -204,14 +204,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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); } }