Skip to content

Commit 6144629

Browse files
committed
rustc: Move some more routines that operate on struct definitions out of line
1 parent 0f711e7 commit 6144629

File tree

5 files changed

+169
-142
lines changed

5 files changed

+169
-142
lines changed

src/rustc/metadata/encoder.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
205205
// class and for its ctor
206206
add_to_index(ebml_w, path, index, it.ident);
207207

208-
match struct_def.ctor {
209-
none => {
210-
// Nothing to do.
211-
}
212-
some(ctor) => {
213-
encode_named_def_id(ebml_w, it.ident,
214-
local_def(ctor.node.id));
215-
}
216-
}
217-
218-
encode_class_item_paths(ebml_w,
219-
struct_def.members,
220-
vec::append_one(path, it.ident),
221-
index);
208+
encode_struct_def(ebml_w, struct_def, path, it.ident, index);
222209
}
223210
}
224211
item_enum(variants, _) => {
@@ -238,6 +225,26 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
238225
}
239226
}
240227

228+
fn encode_struct_def(ebml_w: ebml::writer,
229+
struct_def: ast::struct_def,
230+
path: ~[ast::ident],
231+
ident: ast::ident,
232+
&index: ~[entry<~str>]) {
233+
match struct_def.ctor {
234+
none => {
235+
// Nothing to do.
236+
}
237+
some(ctor) => {
238+
encode_named_def_id(ebml_w, ident, local_def(ctor.node.id));
239+
}
240+
}
241+
242+
encode_class_item_paths(ebml_w,
243+
struct_def.members,
244+
vec::append_one(path, ident),
245+
index);
246+
}
247+
241248
fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
242249
ebml_w.start_tag(tag_impl_trait);
243250
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));

src/rustc/middle/trans/base.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4900,30 +4900,36 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
49004900
foreign::trans_foreign_mod(ccx, foreign_mod, abi);
49014901
}
49024902
ast::item_class(struct_def, tps) => {
4903-
if tps.len() == 0u {
4904-
let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
4905-
vtables: none,
4906-
bounds: @~[]};
4907-
do option::iter(struct_def.ctor) |ctor| {
4908-
trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
4909-
get_item_val(ccx, ctor.node.id), psubsts,
4910-
ctor.node.id, local_def(item.id), ctor.span);
4911-
}
4912-
do option::iter(struct_def.dtor) |dtor| {
4913-
trans_class_dtor(ccx, *path, dtor.node.body,
4914-
dtor.node.id, none, none, local_def(item.id));
4915-
};
4916-
}
4917-
// If there are ty params, the ctor will get monomorphized
4918-
4919-
// Translate methods
4920-
let (_, ms) = ast_util::split_class_items(struct_def.members);
4921-
impl::trans_impl(ccx, *path, item.ident, ms, tps);
4903+
trans_struct_def(ccx, struct_def, tps, path, item.ident, item.id);
49224904
}
49234905
_ => {/* fall through */ }
49244906
}
49254907
}
49264908

4909+
fn trans_struct_def(ccx: @crate_ctxt, struct_def: ast::struct_def,
4910+
tps: ~[ast::ty_param], path: @ast_map::path,
4911+
ident: ast::ident, id: ast::node_id) {
4912+
if tps.len() == 0u {
4913+
let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
4914+
vtables: none,
4915+
bounds: @~[]};
4916+
do option::iter(struct_def.ctor) |ctor| {
4917+
trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
4918+
get_item_val(ccx, ctor.node.id), psubsts,
4919+
ctor.node.id, local_def(id), ctor.span);
4920+
}
4921+
do option::iter(struct_def.dtor) |dtor| {
4922+
trans_class_dtor(ccx, *path, dtor.node.body,
4923+
dtor.node.id, none, none, local_def(id));
4924+
};
4925+
}
4926+
// If there are ty params, the ctor will get monomorphized
4927+
4928+
// Translate methods
4929+
let (_, ms) = ast_util::split_class_items(struct_def.members);
4930+
impl::trans_impl(ccx, *path, ident, ms, tps);
4931+
}
4932+
49274933
// Translate a module. Doing this amounts to translating the items in the
49284934
// module; there ends up being no artifact (aside from linkage names) of
49294935
// separate modules in the compiled program. That's because modules exist

src/rustc/middle/typeck/check.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,42 @@ fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
400400

401401
}
402402

403+
fn check_struct(ccx: @crate_ctxt, struct_def: ast::struct_def,
404+
id: ast::node_id, span: span) {
405+
let tcx = ccx.tcx;
406+
let class_t = {self_ty: ty::node_id_to_type(tcx, id), node_id: id};
407+
408+
do option::iter(struct_def.ctor) |ctor| {
409+
// typecheck the ctor
410+
check_bare_fn(ccx, ctor.node.dec,
411+
ctor.node.body, ctor.node.id,
412+
some(class_t));
413+
// Write the ctor's self's type
414+
write_ty_to_tcx(tcx, ctor.node.self_id, class_t.self_ty);
415+
}
416+
417+
do option::iter(struct_def.dtor) |dtor| {
418+
// typecheck the dtor
419+
check_bare_fn(ccx, ast_util::dtor_dec(),
420+
dtor.node.body, dtor.node.id,
421+
some(class_t));
422+
// Write the dtor's self's type
423+
write_ty_to_tcx(tcx, dtor.node.self_id, class_t.self_ty);
424+
};
425+
426+
// typecheck the members
427+
for struct_def.members.each |m| {
428+
check_class_member(ccx, class_t, m);
429+
}
430+
// Check that there's at least one field
431+
let (fields,_) = split_class_items(struct_def.members);
432+
if fields.len() < 1u {
433+
ccx.tcx.sess.span_err(span, ~"a class must have at least one field");
434+
}
435+
// Check that the class is instantiable
436+
check_instantiable(ccx.tcx, span, id);
437+
}
438+
403439
fn check_item(ccx: @crate_ctxt, it: @ast::item) {
404440
match it.node {
405441
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) {
433469
}
434470
}
435471
ast::item_class(struct_def, _) => {
436-
let tcx = ccx.tcx;
437-
let class_t = {self_ty: ty::node_id_to_type(tcx, it.id),
438-
node_id: it.id};
439-
440-
do option::iter(struct_def.ctor) |ctor| {
441-
// typecheck the ctor
442-
check_bare_fn(ccx, ctor.node.dec,
443-
ctor.node.body, ctor.node.id,
444-
some(class_t));
445-
// Write the ctor's self's type
446-
write_ty_to_tcx(tcx, ctor.node.self_id, class_t.self_ty);
447-
}
448-
449-
do option::iter(struct_def.dtor) |dtor| {
450-
// typecheck the dtor
451-
check_bare_fn(ccx, ast_util::dtor_dec(),
452-
dtor.node.body, dtor.node.id,
453-
some(class_t));
454-
// Write the dtor's self's type
455-
write_ty_to_tcx(tcx, dtor.node.self_id, class_t.self_ty);
456-
};
457-
458-
// typecheck the members
459-
for struct_def.members.each |m| {
460-
check_class_member(ccx, class_t, m);
461-
}
462-
// Check that there's at least one field
463-
let (fields,_) = split_class_items(struct_def.members);
464-
if fields.len() < 1u {
465-
ccx.tcx.sess.span_err(
466-
it.span,
467-
~"a class must have at least one field");
468-
}
469-
// Check that the class is instantiable
470-
check_instantiable(ccx.tcx, it.span, it.id);
472+
check_struct(ccx, struct_def, it.id, it.span);
471473
}
472474
ast::item_ty(t, tps) => {
473475
let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);

src/rustc/middle/typeck/coherence.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -505,29 +505,9 @@ class CoherenceChecker {
505505
methods: methods
506506
};
507507
}
508-
item_class(struct_def, ty_params) => {
509-
let mut methods = ~[];
510-
for struct_def.members.each |class_member| {
511-
match class_member.node {
512-
instance_var(*) => {
513-
// Nothing to do.
514-
}
515-
class_method(ast_method) => {
516-
push(methods, @{
517-
did: local_def(ast_method.id),
518-
n_tps: ast_method.tps.len(),
519-
ident: ast_method.ident,
520-
self_type: ast_method.self_ty.node
521-
});
522-
}
523-
}
524-
}
525-
526-
return @{
527-
did: local_def(item.id),
528-
ident: item.ident,
529-
methods: methods
530-
};
508+
item_class(struct_def, _) => {
509+
return self.create_impl_from_struct(struct_def, item.ident,
510+
item.id);
531511
}
532512
_ => {
533513
self.crate_context.tcx.sess.span_bug(item.span,
@@ -537,6 +517,30 @@ class CoherenceChecker {
537517
}
538518
}
539519

520+
fn create_impl_from_struct(struct_def: ast::struct_def,
521+
ident: ast::ident,
522+
id: node_id)
523+
-> @Impl {
524+
let mut methods = ~[];
525+
for struct_def.members.each |class_member| {
526+
match class_member.node {
527+
instance_var(*) => {
528+
// Nothing to do.
529+
}
530+
class_method(ast_method) => {
531+
push(methods, @{
532+
did: local_def(ast_method.id),
533+
n_tps: ast_method.tps.len(),
534+
ident: ast_method.ident,
535+
self_type: ast_method.self_ty.node
536+
});
537+
}
538+
}
539+
}
540+
541+
return @{ did: local_def(id), ident: ident, methods: methods };
542+
}
543+
540544
fn span_of_impl(implementation: @Impl) -> span {
541545
assert implementation.did.crate == local_crate;
542546
match self.crate_context.tcx.items.find(implementation.did.node) {

src/rustc/middle/typeck/collect.rs

Lines changed: 59 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -388,57 +388,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
388388
write_ty_to_tcx(tcx, it.id, tpt.ty);
389389
tcx.tcache.insert(local_def(it.id), tpt);
390390

391-
do option::iter(struct_def.ctor) |ctor| {
392-
// Write the ctor type
393-
let t_args = ctor.node.dec.inputs.map(
394-
|a| ty_of_arg(ccx, type_rscope(rp), a, none) );
395-
let t_res = ty::mk_class(
396-
tcx, local_def(it.id),
397-
{self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
398-
self_ty: none,
399-
tps: ty::ty_params_to_tys(tcx, tps)});
400-
let t_ctor = ty::mk_fn(
401-
tcx, {purity: ast::impure_fn,
402-
proto: ast::proto_block,
403-
bounds: @~[],
404-
inputs: t_args,
405-
output: t_res,
406-
ret_style: ast::return_val});
407-
write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
408-
tcx.tcache.insert(local_def(ctor.node.id),
409-
{bounds: tpt.bounds,
410-
rp: rp,
411-
ty: t_ctor});
412-
}
413-
414-
do option::iter(struct_def.dtor) |dtor| {
415-
// Write the dtor type
416-
let t_dtor = ty::mk_fn(
417-
tcx,
418-
ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block, @~[],
419-
ast_util::dtor_dec(), none));
420-
write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
421-
tcx.tcache.insert(local_def(dtor.node.id),
422-
{bounds: tpt.bounds,
423-
rp: rp,
424-
ty: t_dtor});
425-
};
426-
ensure_trait_methods(ccx, it.id);
427-
428-
// Write the type of each of the members
429-
let (fields, methods) = split_class_items(struct_def.members);
430-
for fields.each |f| {
431-
convert_field(ccx, rp, tpt.bounds, f);
432-
}
433-
let {bounds, substs} = mk_substs(ccx, tps, rp);
434-
let selfty = ty::mk_class(tcx, local_def(it.id), substs);
435-
let cms = convert_methods(ccx, methods, rp, bounds, selfty);
436-
for struct_def.traits.each |trait_ref| {
437-
check_methods_against_trait(ccx, tps, rp, selfty, trait_ref, cms);
438-
// trait_ref.impl_id represents (class, trait) pair
439-
write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
440-
tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
441-
}
391+
convert_struct(ccx, rp, struct_def, tps, tpt, it.id);
442392
}
443393
_ => {
444394
// This call populates the type cache with the converted type
@@ -449,6 +399,64 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
449399
}
450400
}
451401
}
402+
403+
fn convert_struct(ccx: @crate_ctxt, rp: bool, struct_def: ast::struct_def,
404+
tps: ~[ast::ty_param], tpt: ty::ty_param_bounds_and_ty,
405+
id: ast::node_id) {
406+
let tcx = ccx.tcx;
407+
do option::iter(struct_def.ctor) |ctor| {
408+
// Write the ctor type
409+
let t_args = ctor.node.dec.inputs.map(
410+
|a| ty_of_arg(ccx, type_rscope(rp), a, none) );
411+
let t_res = ty::mk_class(
412+
tcx, local_def(id),
413+
{self_r: if rp {some(ty::re_bound(ty::br_self))} else {none},
414+
self_ty: none,
415+
tps: ty::ty_params_to_tys(tcx, tps)});
416+
let t_ctor = ty::mk_fn(
417+
tcx, {purity: ast::impure_fn,
418+
proto: ast::proto_block,
419+
bounds: @~[],
420+
inputs: t_args,
421+
output: t_res,
422+
ret_style: ast::return_val});
423+
write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
424+
tcx.tcache.insert(local_def(ctor.node.id),
425+
{bounds: tpt.bounds,
426+
rp: rp,
427+
ty: t_ctor});
428+
}
429+
430+
do option::iter(struct_def.dtor) |dtor| {
431+
// Write the dtor type
432+
let t_dtor = ty::mk_fn(
433+
tcx,
434+
ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block, @~[],
435+
ast_util::dtor_dec(), none));
436+
write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
437+
tcx.tcache.insert(local_def(dtor.node.id),
438+
{bounds: tpt.bounds,
439+
rp: rp,
440+
ty: t_dtor});
441+
};
442+
ensure_trait_methods(ccx, id);
443+
444+
// Write the type of each of the members
445+
let (fields, methods) = split_class_items(struct_def.members);
446+
for fields.each |f| {
447+
convert_field(ccx, rp, tpt.bounds, f);
448+
}
449+
let {bounds, substs} = mk_substs(ccx, tps, rp);
450+
let selfty = ty::mk_class(tcx, local_def(id), substs);
451+
let cms = convert_methods(ccx, methods, rp, bounds, selfty);
452+
for struct_def.traits.each |trait_ref| {
453+
check_methods_against_trait(ccx, tps, rp, selfty, trait_ref, cms);
454+
// trait_ref.impl_id represents (class, trait) pair
455+
write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
456+
tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
457+
}
458+
}
459+
452460
fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
453461
// As above, this call populates the type table with the converted
454462
// type of the foreign item. We simply write it into the node type

0 commit comments

Comments
 (0)