]> git.lizzy.rs Git - rust.git/commitdiff
Separate out the unboxed closure table into two tables, so that we can
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 30 Jan 2015 16:37:23 +0000 (11:37 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 1 Feb 2015 11:13:06 +0000 (06:13 -0500)
generate the closure type and closure kind separately.

12 files changed:
src/librustc/metadata/common.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/astencode.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/ty.rs
src/librustc/util/ppaux.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/closure.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/writeback.rs

index 242ab630a20ef424a8eaef8ebd506b9d12dc9da7..bf2f5bd22c4639424e5d084db504c3d70102a52f 100644 (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;
index 6767f77de84bb61ed017a3b2874f6ed500be4209..e09d29b98b09a47517f88795246a485ba2e8f228 100644 (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 @@ struct Stats {
         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 @@ struct Stats {
         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 @@ struct Stats {
     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 @@ struct Stats {
         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);
index 902c029fef4bf3907e82dcb61a0f109b292c0ad1..3764324734132320fbea223d6f5db1303f7f4b44 100644 (file)
@@ -647,30 +647,7 @@ fn tr(&self, dcx: &DecodeContext) -> 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_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)
             })
         })
     }
@@ -1354,8 +1339,10 @@ fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, '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 @@ fn read_unsize_kind<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, '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
@@ -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(
index 188a56135ec33d26331bd3192d44c3e4ddec0397..4a0bed57433ae7a60c79acb156b4e6d8f3ab3a9b 100644 (file)
@@ -260,12 +260,10 @@ fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
     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)
     }
index f1e73ddc5a1e4389c4de13b84346a12edf68e976..fb1d9fcada1cecb4e113d0b27d2205435c48a757 100644 (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 @@ pub fn mk_region(&self, region: Region) -> &'tcx Region {
     }
 
     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 @@ 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)
     }
 }
 
index 6c723a583807e57e27e80d64ce0a55ecde3250a5..15cf37dc2f2f04b33430fbfb0b222908c07d8f96 100644 (file)
@@ -405,9 +405,9 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> 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);
index 1b212aca33034e25a92ce773b0e1b264a5207d01..9ec3db0f602af00bb76091c4ac05b4b074aff203 100644 (file)
@@ -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>,
index a15ede095a709be359a6e271f70af896bcbf05e8..8473ce1b797e360b7b06c9f3e6e6cd8fad1767d1 100644 (file)
@@ -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<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
     }
index 906a8a33314cc4070398bd948f8250111a855182..22390b9e98b11ac2d284272fd494db3f01063daa 100644 (file)
@@ -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>(
index 2e366f4450744b443485a6edf85d7599bc2ac672..8000776ad45f94227ba08143fda5d9857dec99ca 100644 (file)
@@ -598,9 +598,9 @@ fn assemble_closure_candidates(&mut self,
                 _ => 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 @@ fn assemble_closure_candidates(&mut self,
             };
 
             // this closure doesn't implement the right kind of `Fn` trait
-            if closure_data.kind != kind {
+            if closure_kind != kind {
                 continue;
             }
 
index c58377fc87bd7ac1c30fd9b0e3c3e19683df44f8..ed195035a41dfb6a37a36d1f8b6159f0efb6e018 100644 (file)
@@ -160,7 +160,8 @@ pub struct Inherited<'a, 'tcx: 'a> {
     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
@@ -352,7 +353,7 @@ fn closure_kind(&self,
                     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,
@@ -360,7 +361,7 @@ 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,
@@ -386,7 +387,8 @@ fn new(tcx: &'a ty::ctxt<'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()),
index f7e1afed8fc53f219d1ea8d25d771ab447acd7c6..0eaecf8ac0574c6c52f37f57bb966edaeaa528d2 100644 (file)
@@ -204,14 +204,13 @@ fn visit_closures(&self) {
             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);
         }
     }