diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-07 16:46:19 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-07 16:46:19 -0700 |
| commit | 61446293f91cd7a4dff7ca5e17ca5eced22577ad (patch) | |
| tree | 97d369ffb2cde11b0f94337a7efb8aaca0020af0 /src/rustc | |
| parent | 0f711e72f72cf69166902fe9df9c5063e5aa14ff (diff) | |
| download | rust-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.rs | 35 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 44 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check.rs | 72 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/coherence.rs | 50 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/collect.rs | 110 |
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 |
