rustc: Split out struct bodies into a separate "struct_def" type in the AST
This commit is contained in:
parent
1a6dadad5b
commit
deaef48675
15 changed files with 115 additions and 96 deletions
|
|
@ -196,7 +196,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
|||
encode_name_and_def_id(ebml_w, it.ident, it.id);
|
||||
}
|
||||
}
|
||||
item_class(_, _, items, m_ctor, m_dtor) => {
|
||||
item_class(struct_def, _) => {
|
||||
do ebml_w.wr_tag(tag_paths_data_item) {
|
||||
encode_name_and_def_id(ebml_w, it.ident, it.id);
|
||||
}
|
||||
|
|
@ -205,7 +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 m_ctor {
|
||||
match struct_def.ctor {
|
||||
none => {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
|
@ -215,7 +215,8 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
|||
}
|
||||
}
|
||||
|
||||
encode_class_item_paths(ebml_w, items,
|
||||
encode_class_item_paths(ebml_w,
|
||||
struct_def.members,
|
||||
vec::append_one(path, it.ident),
|
||||
index);
|
||||
}
|
||||
|
|
@ -700,15 +701,15 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
|
||||
path, index, tps);
|
||||
}
|
||||
item_class(tps, traits, items, ctor, m_dtor) => {
|
||||
item_class(struct_def, tps) => {
|
||||
/* First, encode the fields and methods
|
||||
These come first because we need to write them to make
|
||||
the index, and the index needs to be in the item for the
|
||||
class itself */
|
||||
let idx = encode_info_for_class(ecx, ebml_w, item.id, path, tps,
|
||||
items, index);
|
||||
struct_def.members, index);
|
||||
/* Encode the dtor */
|
||||
do option::iter(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
vec::push(*index, {val: dtor.node.id, pos: ebml_w.writer.tell()});
|
||||
encode_info_for_fn(ecx, ebml_w, dtor.node.id, @(*item.ident
|
||||
+ ~"_dtor"), path, if tps.len() > 0u {
|
||||
|
|
@ -723,7 +724,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
|
||||
match ctor {
|
||||
match struct_def.ctor {
|
||||
none => encode_family(ebml_w, 'S'),
|
||||
some(_) => encode_family(ebml_w, 'C')
|
||||
}
|
||||
|
|
@ -733,12 +734,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_name(ebml_w, item.ident);
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_region_param(ecx, ebml_w, item);
|
||||
for traits.each |t| {
|
||||
for struct_def.traits.each |t| {
|
||||
encode_trait_ref(ebml_w, ecx, t);
|
||||
}
|
||||
/* Encode the dtor */
|
||||
/* Encode id for dtor */
|
||||
do option::iter(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
do ebml_w.wr_tag(tag_item_dtor) {
|
||||
encode_def_id(ebml_w, local_def(dtor.node.id));
|
||||
}
|
||||
|
|
@ -747,7 +748,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
/* Encode def_ids for each field and method
|
||||
for methods, write all the stuff get_trait_method
|
||||
needs to know*/
|
||||
let (fs,ms) = ast_util::split_class_items(items);
|
||||
let (fs,ms) = ast_util::split_class_items(struct_def.members);
|
||||
for fs.each |f| {
|
||||
ebml_w.start_tag(tag_item_field);
|
||||
encode_visibility(ebml_w, f.vis);
|
||||
|
|
@ -783,7 +784,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
ebml_w.end_tag();
|
||||
|
||||
/* Encode the constructor */
|
||||
for ctor.each |ctor| {
|
||||
for struct_def.ctor.each |ctor| {
|
||||
debug!{"encoding info for ctor %s %d", *item.ident,
|
||||
ctor.node.id};
|
||||
vec::push(*index, {
|
||||
|
|
|
|||
|
|
@ -984,13 +984,13 @@ class Resolver {
|
|||
visitor);
|
||||
}
|
||||
}
|
||||
item_class(_, _, class_members, optional_ctor, _) => {
|
||||
item_class(struct_definition, _) => {
|
||||
let (name_bindings, new_parent) = self.add_child(atom, parent,
|
||||
~[ValueNS, TypeNS], sp);
|
||||
|
||||
(*name_bindings).define_type(def_ty(local_def(item.id)), sp);
|
||||
|
||||
match optional_ctor {
|
||||
match struct_definition.ctor {
|
||||
none => {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
|
@ -1008,7 +1008,7 @@ class Resolver {
|
|||
// bindings.
|
||||
|
||||
let mut method_infos = ~[];
|
||||
for class_members.each |class_member| {
|
||||
for struct_definition.members.each |class_member| {
|
||||
match class_member.node {
|
||||
class_method(method) => {
|
||||
// XXX: Combine with impl method code below.
|
||||
|
|
@ -1037,7 +1037,7 @@ class Resolver {
|
|||
|
||||
// Record the def ID of this struct.
|
||||
self.structs.insert(local_def(item.id),
|
||||
is_some(optional_ctor));
|
||||
is_some(struct_definition.ctor));
|
||||
|
||||
visit_item(item, new_parent, visitor);
|
||||
}
|
||||
|
|
@ -3249,15 +3249,13 @@ class Resolver {
|
|||
(*self.type_ribs).pop();
|
||||
}
|
||||
|
||||
item_class(ty_params, traits, class_members,
|
||||
optional_constructor, optional_destructor) => {
|
||||
|
||||
item_class(struct_def, ty_params) => {
|
||||
self.resolve_class(item.id,
|
||||
@copy ty_params,
|
||||
traits,
|
||||
class_members,
|
||||
optional_constructor,
|
||||
optional_destructor,
|
||||
struct_def.traits,
|
||||
struct_def.members,
|
||||
struct_def.ctor,
|
||||
struct_def.dtor,
|
||||
visitor);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4899,17 +4899,17 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
|||
};
|
||||
foreign::trans_foreign_mod(ccx, foreign_mod, abi);
|
||||
}
|
||||
ast::item_class(tps, _traits, items, m_ctor, m_dtor) => {
|
||||
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(m_ctor) |ctor| {
|
||||
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(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
trans_class_dtor(ccx, *path, dtor.node.body,
|
||||
dtor.node.id, none, none, local_def(item.id));
|
||||
};
|
||||
|
|
@ -4917,7 +4917,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
|||
// If there are ty params, the ctor will get monomorphized
|
||||
|
||||
// Translate methods
|
||||
let (_, ms) = ast_util::split_class_items(items);
|
||||
let (_, ms) = ast_util::split_class_items(struct_def.members);
|
||||
impl::trans_impl(ccx, *path, item.ident, ms, tps);
|
||||
}
|
||||
_ => {/* fall through */ }
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
|||
method_from_methods(ms, name)
|
||||
}
|
||||
ast_map::node_item(@{node:
|
||||
ast::item_class(_, _, items, _, _), _}, _) => {
|
||||
let (_,ms) = split_class_items(items);
|
||||
ast::item_class(struct_def, _), _}, _) => {
|
||||
let (_,ms) = split_class_items(struct_def.members);
|
||||
method_from_methods(ms, name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,22 +111,22 @@ fn traverse_public_item(cx: ctx, item: @item) {
|
|||
}
|
||||
}
|
||||
}
|
||||
item_class(tps, _traits, items, m_ctor, m_dtor) => {
|
||||
do option::iter(m_ctor) |ctor| {
|
||||
item_class(struct_def, tps) => {
|
||||
do option::iter(struct_def.ctor) |ctor| {
|
||||
cx.rmap.insert(ctor.node.id, ());
|
||||
if tps.len() > 0u || attr::find_inline_attr(ctor.node.attrs)
|
||||
!= attr::ia_none {
|
||||
traverse_inline_body(cx, ctor.node.body);
|
||||
}
|
||||
}
|
||||
do option::iter(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
cx.rmap.insert(dtor.node.id, ());
|
||||
if tps.len() > 0u || attr::find_inline_attr(dtor.node.attrs)
|
||||
!= attr::ia_none {
|
||||
traverse_inline_body(cx, dtor.node.body);
|
||||
}
|
||||
}
|
||||
for vec::each(items) |item| {
|
||||
for vec::each(struct_def.members) |item| {
|
||||
match item.node {
|
||||
class_method(m) => {
|
||||
cx.rmap.insert(m.id, ());
|
||||
|
|
@ -214,7 +214,7 @@ fn traverse_all_resources_and_impls(cx: ctx, crate_mod: _mod) {
|
|||
visit_item: |i, cx, v| {
|
||||
visit::visit_item(i, cx, v);
|
||||
match i.node {
|
||||
item_class(_, _, _, _, some(_)) => {
|
||||
item_class(struct_def, _) if struct_def.dtor.is_some() => {
|
||||
traverse_public_item(cx, i);
|
||||
}
|
||||
item_impl(*) => {
|
||||
|
|
|
|||
|
|
@ -2741,10 +2741,13 @@ fn item_path_str(cx: ctxt, id: ast::def_id) -> ~str {
|
|||
fn ty_dtor(cx: ctxt, class_id: def_id) -> option<def_id> {
|
||||
if is_local(class_id) {
|
||||
match cx.items.find(class_id.node) {
|
||||
some(ast_map::node_item(@{node: ast::item_class(_, _, _, _,
|
||||
some(dtor)), _}, _))
|
||||
=> some(local_def(dtor.node.id)),
|
||||
_ => none
|
||||
some(ast_map::node_item(@{
|
||||
node: ast::item_class({ dtor: some(dtor), _ }, _),
|
||||
_
|
||||
}, _)) =>
|
||||
some(local_def(dtor.node.id)),
|
||||
_ =>
|
||||
none
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -2936,8 +2939,8 @@ fn lookup_class_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
|
|||
match cx.items.find(did.node) {
|
||||
some(ast_map::node_item(i,_)) => {
|
||||
match i.node {
|
||||
ast::item_class(_, _, items, _, _) => {
|
||||
class_field_tys(items)
|
||||
ast::item_class(struct_def, _) => {
|
||||
class_field_tys(struct_def.members)
|
||||
}
|
||||
_ => cx.sess.bug(~"class ID bound to non-class")
|
||||
}
|
||||
|
|
@ -2990,9 +2993,9 @@ fn lookup_class_method_by_name(cx:ctxt, did: ast::def_id, name: ident,
|
|||
assert is_local(did);
|
||||
match cx.items.find(did.node) {
|
||||
some(ast_map::node_item(@{
|
||||
node: item_class(_,_,items,_,_), _
|
||||
node: item_class(struct_def, _), _
|
||||
}, _)) => {
|
||||
let (_,ms) = split_class_items(items);
|
||||
let (_,ms) = split_class_items(struct_def.members);
|
||||
vec::map(ms, |m| {name: m.ident, id: m.id,
|
||||
vis: m.vis})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,12 +432,12 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::item_class(tps, _, members, m_ctor, m_dtor) => {
|
||||
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(m_ctor) |ctor| {
|
||||
do option::iter(struct_def.ctor) |ctor| {
|
||||
// typecheck the ctor
|
||||
check_bare_fn(ccx, ctor.node.dec,
|
||||
ctor.node.body, ctor.node.id,
|
||||
|
|
@ -446,7 +446,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
write_ty_to_tcx(tcx, ctor.node.self_id, class_t.self_ty);
|
||||
}
|
||||
|
||||
do option::iter(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
// typecheck the dtor
|
||||
check_bare_fn(ccx, ast_util::dtor_dec(),
|
||||
dtor.node.body, dtor.node.id,
|
||||
|
|
@ -456,9 +456,11 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
};
|
||||
|
||||
// typecheck the members
|
||||
for members.each |m| { check_class_member(ccx, class_t, m); }
|
||||
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(members);
|
||||
let (fields,_) = split_class_items(struct_def.members);
|
||||
if fields.len() < 1u {
|
||||
ccx.tcx.sess.span_err(
|
||||
it.span,
|
||||
|
|
@ -747,8 +749,8 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
|
|||
rp: rp,
|
||||
raw_ty: fcx.ccx.to_ty(rscope::type_rscope(rp), st)}
|
||||
}
|
||||
some(ast_map::node_item(@{node: ast::item_class(ts,
|
||||
_,_,_,_), id: class_id, _},_)) => {
|
||||
some(ast_map::node_item(@{node: ast::item_class(_, ts),
|
||||
id: class_id, _},_)) => {
|
||||
/* If the impl is a class, the self ty is just the class ty
|
||||
(doing a no-op subst for the ty params; in the next step,
|
||||
we substitute in fresh vars for them)
|
||||
|
|
@ -1720,7 +1722,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
tcx.region_paramd_items.contains_key(class_id.node);
|
||||
match tcx.items.find(class_id.node) {
|
||||
some(ast_map::node_item(@{
|
||||
node: ast::item_class(type_parameters, _, _, _, _),
|
||||
node: ast::item_class(_, type_parameters),
|
||||
_
|
||||
}, _)) => {
|
||||
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ class CoherenceChecker {
|
|||
item_impl(_, associated_traits, _, _) => {
|
||||
self.check_implementation(item, associated_traits);
|
||||
}
|
||||
item_class(_, associated_traits, _, _, _) => {
|
||||
self.check_implementation(item, associated_traits);
|
||||
item_class(struct_def, _) => {
|
||||
self.check_implementation(item, struct_def.traits);
|
||||
}
|
||||
_ => {
|
||||
// Nothing to do.
|
||||
|
|
@ -505,9 +505,9 @@ class CoherenceChecker {
|
|||
methods: methods
|
||||
};
|
||||
}
|
||||
item_class(ty_params, _, class_members, _, _) => {
|
||||
item_class(struct_def, ty_params) => {
|
||||
let mut methods = ~[];
|
||||
for class_members.each |class_member| {
|
||||
for struct_def.members.each |class_member| {
|
||||
match class_member.node {
|
||||
instance_var(*) => {
|
||||
// Nothing to do.
|
||||
|
|
|
|||
|
|
@ -162,8 +162,8 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id) {
|
|||
}
|
||||
});
|
||||
}
|
||||
ast_map::node_item(@{node: ast::item_class(_,_,its,_,_), _}, _) => {
|
||||
let (_,ms) = split_class_items(its);
|
||||
ast_map::node_item(@{node: ast::item_class(struct_def, _), _}, _) => {
|
||||
let (_,ms) = split_class_items(struct_def.members);
|
||||
// All methods need to be stored, since lookup_method
|
||||
// relies on the same method cache for self-calls
|
||||
store_methods::<@ast::method>(ccx, id, ms, |m| {
|
||||
|
|
@ -382,13 +382,13 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
|||
// check_methods_against_trait(ccx, tps, rp, selfty, t, cms);
|
||||
// }
|
||||
}
|
||||
ast::item_class(tps, trait_refs, members, m_ctor, m_dtor) => {
|
||||
ast::item_class(struct_def, tps) => {
|
||||
// Write the class type
|
||||
let tpt = ty_of_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, tpt.ty);
|
||||
tcx.tcache.insert(local_def(it.id), tpt);
|
||||
|
||||
do option::iter(m_ctor) |ctor| {
|
||||
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) );
|
||||
|
|
@ -411,7 +411,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
|||
ty: t_ctor});
|
||||
}
|
||||
|
||||
do option::iter(m_dtor) |dtor| {
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
// Write the dtor type
|
||||
let t_dtor = ty::mk_fn(
|
||||
tcx,
|
||||
|
|
@ -426,14 +426,14 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
|||
ensure_trait_methods(ccx, it.id);
|
||||
|
||||
// Write the type of each of the members
|
||||
let (fields, methods) = split_class_items(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 trait_refs.each |trait_ref| {
|
||||
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);
|
||||
|
|
@ -583,7 +583,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
|
|||
tcx.tcache.insert(local_def(it.id), tpt);
|
||||
return tpt;
|
||||
}
|
||||
ast::item_class(tps, _, _, _, _) => {
|
||||
ast::item_class(_, tps) => {
|
||||
let {bounds,substs} = mk_substs(ccx, tps, rp);
|
||||
let t = ty::mk_class(tcx, local_def(it.id), substs);
|
||||
let tpt = {bounds: bounds, rp: rp, ty: t};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue