提交 deaef486 编写于 作者: P Patrick Walton

rustc: Split out struct bodies into a separate "struct_def" type in the AST

上级 1a6dadad
......@@ -710,6 +710,17 @@ enum attr_style { attr_outer, attr_inner, }
#[auto_serialize]
enum visibility { public, private, inherited }
#[auto_serialize]
type struct_def = {
traits: ~[@trait_ref], /* traits this class implements */
members: ~[@class_member], /* methods, etc. */
/* (not including ctor or dtor) */
/* ctor is optional, and will soon go away */
ctor: option<class_ctor>,
/* dtor is optional */
dtor: option<class_dtor>
};
#[auto_serialize]
type item = {ident: ident, attrs: ~[attribute],
id: node_id, node: item_,
......@@ -723,15 +734,7 @@ enum item_ {
item_foreign_mod(foreign_mod),
item_ty(@ty, ~[ty_param]),
item_enum(~[variant], ~[ty_param]),
item_class(~[ty_param], /* ty params for class */
~[@trait_ref], /* traits this class implements */
~[@class_member], /* methods, etc. */
/* (not including ctor or dtor) */
/* ctor is optional, and will soon go away */
option<class_ctor>,
/* dtor is optional */
option<class_dtor>
),
item_class(struct_def, ~[ty_param]),
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
item_impl(~[ty_param],
~[@trait_ref], /* traits this impl implements */
......
......@@ -216,11 +216,11 @@ fn map_item(i: @item, cx: ctx, v: vt) {
extend(cx, i.ident)));
}
}
item_class(tps, traits, items, ctor, dtor) => {
let (_, ms) = ast_util::split_class_items(items);
item_class(struct_def, _) => {
let (_, ms) = ast_util::split_class_items(struct_def.members);
// Map trait refs to their parent classes. This is
// so we can find the self_ty
for traits.each |p| {
for struct_def.traits.each |p| {
cx.map.insert(p.ref_id, node_item(i, item_path));
// This is so we can look up the right things when
// encoding/decoding
......
......@@ -242,9 +242,9 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
item_enum(vec::map(variants, |x| fld.fold_variant(x)),
fold_ty_params(typms, fld))
}
item_class(typms, traits, items, m_ctor, m_dtor) => {
item_class(struct_def, typms) => {
let resulting_optional_constructor;
match m_ctor {
match struct_def.ctor {
none => {
resulting_optional_constructor = none;
}
......@@ -260,18 +260,20 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
});
}
}
let dtor = do option::map(m_dtor) |dtor| {
let dtor = do option::map(struct_def.dtor) |dtor| {
let dtor_body = fld.fold_block(dtor.node.body);
let dtor_id = fld.new_id(dtor.node.id);
{node: {body: dtor_body,
id: dtor_id with dtor.node}
with dtor}};
item_class(
/* FIXME (#2543) */ copy typms,
vec::map(traits, |p| fold_trait_ref(p, fld)),
vec::map(items, |x| fld.fold_class_item(x)),
resulting_optional_constructor,
dtor)
item_class({
traits: vec::map(struct_def.traits,
|p| fold_trait_ref(p, fld)),
members: vec::map(struct_def.members,
|x| fld.fold_class_item(x)),
ctor: resulting_optional_constructor,
dtor: dtor},
/* FIXME (#2543) */ copy typms)
}
item_impl(tps, ifce, ty, methods) => {
item_impl(fold_ty_params(tps, fld),
......
......@@ -2581,18 +2581,28 @@ fn parse_item_class() -> item_info {
match the_ctor {
some((ct_d, ct_attrs, ct_b, ct_s)) => {
(class_name,
item_class(ty_params, traits, ms, some({
item_class({
traits: traits,
members: ms,
ctor: some({
node: {id: ctor_id,
attrs: ct_attrs,
self_id: self.get_id(),
dec: ct_d,
body: ct_b},
span: ct_s}), actual_dtor),
span: ct_s}),
dtor: actual_dtor
}, ty_params),
none)
}
none => {
(class_name,
item_class(ty_params, traits, ms, none, actual_dtor),
item_class({
traits: traits,
members: ms,
ctor: none,
dtor: actual_dtor
}, ty_params),
none)
}
}
......
......@@ -530,18 +530,18 @@ fn print_item(s: ps, &&item: @ast::item) {
bclose(s, item.span);
}
}
ast::item_class(tps, traits, items, m_ctor, m_dtor) => {
ast::item_class(struct_def, tps) => {
head(s, ~"class");
word_nbsp(s, *item.ident);
print_type_params(s, tps);
if vec::len(traits) != 0u {
if vec::len(struct_def.traits) != 0u {
word_space(s, ~":");
commasep(s, inconsistent, traits, |s, p|
commasep(s, inconsistent, struct_def.traits, |s, p|
print_path(s, p.path, false));
}
bopen(s);
hardbreak_if_not_bol(s);
do option::iter(m_ctor) |ctor| {
do option::iter(struct_def.ctor) |ctor| {
maybe_print_comment(s, ctor.span.lo);
print_outer_attributes(s, ctor.node.attrs);
// Doesn't call head because there shouldn't be a space after new.
......@@ -553,14 +553,14 @@ fn print_item(s: ps, &&item: @ast::item) {
space(s.s);
print_block(s, ctor.node.body);
}
do option::iter(m_dtor) |dtor| {
do option::iter(struct_def.dtor) |dtor| {
hardbreak_if_not_bol(s);
maybe_print_comment(s, dtor.span.lo);
print_outer_attributes(s, dtor.node.attrs);
head(s, ~"drop");
print_block(s, dtor.node.body);
}
for items.each |ci| {
for struct_def.members.each |ci| {
/*
FIXME (#1893): collect all private items and print
them in a single "priv" section
......
......@@ -152,17 +152,17 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
visit_method_helper(m, e, v)
}
}
item_class(tps, traits, members, m_ctor, m_dtor) => {
item_class(struct_def, tps) => {
v.visit_ty_params(tps, e, v);
for members.each |m| {
for struct_def.members.each |m| {
v.visit_class_item(m, e, v);
}
for traits.each |p| { visit_path(p.path, e, v); }
do option::iter(m_ctor) |ctor| {
for struct_def.traits.each |p| { visit_path(p.path, e, v); }
do option::iter(struct_def.ctor) |ctor| {
visit_class_ctor_helper(ctor, i.ident, tps,
ast_util::local_def(i.id), e, v);
};
do option::iter(m_dtor) |dtor| {
do option::iter(struct_def.dtor) |dtor| {
visit_class_dtor_helper(dtor, tps,
ast_util::local_def(i.id), e, v)
};
......
......@@ -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 add_to_index_(item: @item, ebml_w: ebml::writer,
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 add_to_index_(item: @item, ebml_w: ebml::writer,
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 add_to_index_(item: @item, ebml_w: ebml::writer,
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 add_to_index_(item: @item, ebml_w: ebml::writer,
/* 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 add_to_index_(item: @item, ebml_w: ebml::writer,
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 @@ fn build_reduced_graph_for_item(item: @item,
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 @@ fn build_reduced_graph_for_item(item: @item,
// 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 @@ fn build_reduced_graph_for_item(item: @item,
// 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 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
(*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_ids(cx: ctxt, did: ast::def_id)
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 get_node(f: spanned<field>) -> field { f.node }
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 @@ fn check_coherence(crate: @crate) {
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 @@ fn create_impl_from_item(item: @item) -> @Impl {
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 store_methods<T>(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};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册