about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-07 16:46:19 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-07 16:46:19 -0700
commit61446293f91cd7a4dff7ca5e17ca5eced22577ad (patch)
tree97d369ffb2cde11b0f94337a7efb8aaca0020af0 /src/rustc
parent0f711e72f72cf69166902fe9df9c5063e5aa14ff (diff)
downloadrust-61446293f91cd7a4dff7ca5e17ca5eced22577ad.tar.gz
rust-61446293f91cd7a4dff7ca5e17ca5eced22577ad.zip
rustc: Move some more routines that operate on struct definitions out of line
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/metadata/encoder.rs35
-rw-r--r--src/rustc/middle/trans/base.rs44
-rw-r--r--src/rustc/middle/typeck/check.rs72
-rw-r--r--src/rustc/middle/typeck/coherence.rs50
-rw-r--r--src/rustc/middle/typeck/collect.rs110
5 files changed, 169 insertions, 142 deletions
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 8d31bd333a1..545d3821f02 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -205,20 +205,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
                 // class and for its ctor
                 add_to_index(ebml_w, path, index, it.ident);
 
-                match struct_def.ctor {
-                    none => {
-                        // Nothing to do.
-                    }
-                    some(ctor) => {
-                        encode_named_def_id(ebml_w, it.ident,
-                                            local_def(ctor.node.id));
-                    }
-                }
-
-                encode_class_item_paths(ebml_w,
-                                        struct_def.members,
-                                        vec::append_one(path, it.ident),
-                                        index);
+                encode_struct_def(ebml_w, struct_def, path, it.ident, index);
             }
           }
           item_enum(variants, _) => {
@@ -238,6 +225,26 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
     }
 }
 
+fn encode_struct_def(ebml_w: ebml::writer,
+                     struct_def: ast::struct_def,
+                     path: ~[ast::ident],
+                     ident: ast::ident,
+                     &index: ~[entry<~str>]) {
+    match struct_def.ctor {
+        none => {
+            // Nothing to do.
+        }
+        some(ctor) => {
+            encode_named_def_id(ebml_w, ident, local_def(ctor.node.id));
+        }
+    }
+
+    encode_class_item_paths(ebml_w,
+                            struct_def.members,
+                            vec::append_one(path, ident),
+                            index);
+}
+
 fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
     ebml_w.start_tag(tag_impl_trait);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index e5a3a8e4e13..36397250f1a 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -4900,30 +4900,36 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
         foreign::trans_foreign_mod(ccx, foreign_mod, abi);
       }
       ast::item_class(struct_def, tps) => {
-        if tps.len() == 0u {
-          let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
-                         vtables: none,
-                         bounds: @~[]};
-          do option::iter(struct_def.ctor) |ctor| {
-            trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
-                             get_item_val(ccx, ctor.node.id), psubsts,
-                             ctor.node.id, local_def(item.id), ctor.span);
-          }
-          do option::iter(struct_def.dtor) |dtor| {
-             trans_class_dtor(ccx, *path, dtor.node.body,
-               dtor.node.id, none, none, local_def(item.id));
-          };
-        }
-        // If there are ty params, the ctor will get monomorphized
-
-        // Translate methods
-        let (_, ms) = ast_util::split_class_items(struct_def.members);
-        impl::trans_impl(ccx, *path, item.ident, ms, tps);
+        trans_struct_def(ccx, struct_def, tps, path, item.ident, item.id);
       }
       _ => {/* fall through */ }
     }
 }
 
+fn trans_struct_def(ccx: @crate_ctxt, struct_def: ast::struct_def,
+                    tps: ~[ast::ty_param], path: @ast_map::path,
+                    ident: ast::ident, id: ast::node_id) {
+    if tps.len() == 0u {
+      let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
+                     vtables: none,
+                     bounds: @~[]};
+      do option::iter(struct_def.ctor) |ctor| {
+        trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
+                         get_item_val(ccx, ctor.node.id), psubsts,
+                         ctor.node.id, local_def(id), ctor.span);
+      }
+      do option::iter(struct_def.dtor) |dtor| {
+         trans_class_dtor(ccx, *path, dtor.node.body,
+           dtor.node.id, none, none, local_def(id));
+      };
+    }
+    // If there are ty params, the ctor will get monomorphized
+
+    // Translate methods
+    let (_, ms) = ast_util::split_class_items(struct_def.members);
+    impl::trans_impl(ccx, *path, ident, ms, tps);
+}
+
 // Translate a module. Doing this amounts to translating the items in the
 // module; there ends up being no artifact (aside from linkage names) of
 // separate modules in the compiled program.  That's because modules exist
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 9dac176c564..d5165e26a2b 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -400,6 +400,42 @@ fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
 
 }
 
+fn check_struct(ccx: @crate_ctxt, struct_def: ast::struct_def,
+                id: ast::node_id, span: span) {
+    let tcx = ccx.tcx;
+    let class_t = {self_ty: ty::node_id_to_type(tcx, id), node_id: id};
+
+    do option::iter(struct_def.ctor) |ctor| {
+        // typecheck the ctor
+        check_bare_fn(ccx, ctor.node.dec,
+                      ctor.node.body, ctor.node.id,
+                      some(class_t));
+        // Write the ctor's self's type
+        write_ty_to_tcx(tcx, ctor.node.self_id, class_t.self_ty);
+    }
+
+    do option::iter(struct_def.dtor) |dtor| {
+        // typecheck the dtor
+        check_bare_fn(ccx, ast_util::dtor_dec(),
+                      dtor.node.body, dtor.node.id,
+                      some(class_t));
+        // Write the dtor's self's type
+        write_ty_to_tcx(tcx, dtor.node.self_id, class_t.self_ty);
+    };
+
+    // typecheck the members
+    for struct_def.members.each |m| {
+        check_class_member(ccx, class_t, m);
+    }
+    // Check that there's at least one field
+    let (fields,_) = split_class_items(struct_def.members);
+    if fields.len() < 1u {
+        ccx.tcx.sess.span_err(span, ~"a class must have at least one field");
+    }
+    // Check that the class is instantiable
+    check_instantiable(ccx.tcx, span, id);
+}
+
 fn check_item(ccx: @crate_ctxt, it: @ast::item) {
     match it.node {
       ast::item_const(_, e) => check_const(ccx, it.span, e, it.id),
@@ -433,41 +469,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
         }
       }
       ast::item_class(struct_def, _) => {
-        let tcx = ccx.tcx;
-        let class_t = {self_ty: ty::node_id_to_type(tcx, it.id),
-                       node_id: it.id};
-
-        do option::iter(struct_def.ctor) |ctor| {
-            // typecheck the ctor
-            check_bare_fn(ccx, ctor.node.dec,
-                          ctor.node.body, ctor.node.id,
-                          some(class_t));
-            // Write the ctor's self's type
-            write_ty_to_tcx(tcx, ctor.node.self_id, class_t.self_ty);
-        }
-
-        do option::iter(struct_def.dtor) |dtor| {
-            // typecheck the dtor
-            check_bare_fn(ccx, ast_util::dtor_dec(),
-                          dtor.node.body, dtor.node.id,
-                          some(class_t));
-            // Write the dtor's self's type
-            write_ty_to_tcx(tcx, dtor.node.self_id, class_t.self_ty);
-        };
-
-        // typecheck the members
-        for struct_def.members.each |m| {
-            check_class_member(ccx, class_t, m);
-        }
-        // Check that there's at least one field
-        let (fields,_) = split_class_items(struct_def.members);
-        if fields.len() < 1u {
-            ccx.tcx.sess.span_err(
-                it.span,
-                ~"a class must have at least one field");
-        }
-        // Check that the class is instantiable
-        check_instantiable(ccx.tcx, it.span, it.id);
+        check_struct(ccx, struct_def, it.id, it.span);
       }
       ast::item_ty(t, tps) => {
         let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs
index 798c3a2af17..539c0ea2e5a 100644
--- a/src/rustc/middle/typeck/coherence.rs
+++ b/src/rustc/middle/typeck/coherence.rs
@@ -505,29 +505,9 @@ class CoherenceChecker {
                     methods: methods
                 };
             }
-            item_class(struct_def, ty_params) => {
-                let mut methods = ~[];
-                for struct_def.members.each |class_member| {
-                    match class_member.node {
-                        instance_var(*) => {
-                            // Nothing to do.
-                        }
-                        class_method(ast_method) => {
-                            push(methods, @{
-                                did: local_def(ast_method.id),
-                                n_tps: ast_method.tps.len(),
-                                ident: ast_method.ident,
-                                self_type: ast_method.self_ty.node
-                            });
-                        }
-                    }
-                }
-
-                return @{
-                    did: local_def(item.id),
-                    ident: item.ident,
-                    methods: methods
-                };
+            item_class(struct_def, _) => {
+                return self.create_impl_from_struct(struct_def, item.ident,
+                                                    item.id);
             }
             _ => {
                 self.crate_context.tcx.sess.span_bug(item.span,
@@ -537,6 +517,30 @@ class CoherenceChecker {
         }
     }
 
+    fn create_impl_from_struct(struct_def: ast::struct_def,
+                               ident: ast::ident,
+                               id: node_id)
+                            -> @Impl {
+        let mut methods = ~[];
+        for struct_def.members.each |class_member| {
+            match class_member.node {
+                instance_var(*) => {
+                    // Nothing to do.
+                }
+                class_method(ast_method) => {
+                    push(methods, @{
+                        did: local_def(ast_method.id),
+                        n_tps: ast_method.tps.len(),
+                        ident: ast_method.ident,
+                        self_type: ast_method.self_ty.node
+                    });
+                }
+            }
+        }
+
+        return @{ did: local_def(id), ident: ident, methods: methods };
+    }
+
     fn span_of_impl(implementation: @Impl) -> span {
         assert implementation.did.crate == local_crate;
         match self.crate_context.tcx.items.find(implementation.did.node) {
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index c9da4db0531..2abc201d132 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -388,57 +388,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
         write_ty_to_tcx(tcx, it.id, tpt.ty);
         tcx.tcache.insert(local_def(it.id), tpt);
 
-        do option::iter(struct_def.ctor) |ctor| {
-            // Write the ctor type
-            let t_args = ctor.node.dec.inputs.map(
-                |a| ty_of_arg(ccx, type_rscope(rp), a, none) );
-            let t_res = ty::mk_class(
-                tcx, local_def(it.id),
-                {self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
-                 self_ty: none,
-                 tps: ty::ty_params_to_tys(tcx, tps)});
-            let t_ctor = ty::mk_fn(
-                tcx, {purity: ast::impure_fn,
-                      proto: ast::proto_block,
-                      bounds: @~[],
-                      inputs: t_args,
-                      output: t_res,
-                      ret_style: ast::return_val});
-            write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
-            tcx.tcache.insert(local_def(ctor.node.id),
-                              {bounds: tpt.bounds,
-                               rp: rp,
-                               ty: t_ctor});
-        }
-
-        do option::iter(struct_def.dtor) |dtor| {
-            // Write the dtor type
-            let t_dtor = ty::mk_fn(
-                tcx,
-                ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block, @~[],
-                              ast_util::dtor_dec(), none));
-            write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
-            tcx.tcache.insert(local_def(dtor.node.id),
-                              {bounds: tpt.bounds,
-                               rp: rp,
-                               ty: t_dtor});
-        };
-        ensure_trait_methods(ccx, it.id);
-
-        // Write the type of each of the members
-        let (fields, methods) = split_class_items(struct_def.members);
-        for fields.each |f| {
-           convert_field(ccx, rp, tpt.bounds, f);
-        }
-        let {bounds, substs} = mk_substs(ccx, tps, rp);
-        let selfty = ty::mk_class(tcx, local_def(it.id), substs);
-        let cms = convert_methods(ccx, methods, rp, bounds, selfty);
-        for struct_def.traits.each |trait_ref| {
-            check_methods_against_trait(ccx, tps, rp, selfty, trait_ref, cms);
-            // trait_ref.impl_id represents (class, trait) pair
-            write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
-            tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
-        }
+        convert_struct(ccx, rp, struct_def, tps, tpt, it.id);
       }
       _ => {
         // This call populates the type cache with the converted type
@@ -449,6 +399,64 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
       }
     }
 }
+
+fn convert_struct(ccx: @crate_ctxt, rp: bool, struct_def: ast::struct_def,
+                  tps: ~[ast::ty_param], tpt: ty::ty_param_bounds_and_ty,
+                  id: ast::node_id) {
+    let tcx = ccx.tcx;
+    do option::iter(struct_def.ctor) |ctor| {
+        // Write the ctor type
+        let t_args = ctor.node.dec.inputs.map(
+            |a| ty_of_arg(ccx, type_rscope(rp), a, none) );
+        let t_res = ty::mk_class(
+            tcx, local_def(id),
+            {self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
+             self_ty: none,
+             tps: ty::ty_params_to_tys(tcx, tps)});
+        let t_ctor = ty::mk_fn(
+            tcx, {purity: ast::impure_fn,
+                  proto: ast::proto_block,
+                  bounds: @~[],
+                  inputs: t_args,
+                  output: t_res,
+                  ret_style: ast::return_val});
+        write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
+        tcx.tcache.insert(local_def(ctor.node.id),
+                          {bounds: tpt.bounds,
+                           rp: rp,
+                           ty: t_ctor});
+    }
+
+    do option::iter(struct_def.dtor) |dtor| {
+        // Write the dtor type
+        let t_dtor = ty::mk_fn(
+            tcx,
+            ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block, @~[],
+                          ast_util::dtor_dec(), none));
+        write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
+        tcx.tcache.insert(local_def(dtor.node.id),
+                          {bounds: tpt.bounds,
+                           rp: rp,
+                           ty: t_dtor});
+    };
+    ensure_trait_methods(ccx, id);
+
+    // Write the type of each of the members
+    let (fields, methods) = split_class_items(struct_def.members);
+    for fields.each |f| {
+       convert_field(ccx, rp, tpt.bounds, f);
+    }
+    let {bounds, substs} = mk_substs(ccx, tps, rp);
+    let selfty = ty::mk_class(tcx, local_def(id), substs);
+    let cms = convert_methods(ccx, methods, rp, bounds, selfty);
+    for struct_def.traits.each |trait_ref| {
+        check_methods_against_trait(ccx, tps, rp, selfty, trait_ref, cms);
+        // trait_ref.impl_id represents (class, trait) pair
+        write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
+        tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
+    }
+}
+
 fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
     // As above, this call populates the type table with the converted
     // type of the foreign item. We simply write it into the node type