diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a09bd073c44e..cb46f6feabcd 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -717,10 +717,27 @@ type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id}; #[auto_serialize] enum visibility { public, private, inherited } +#[auto_serialize] +type struct_field_ = { + kind: struct_field_kind, + id: node_id, + ty: @ty +}; + +#[auto_serialize] +type struct_field = spanned; + +#[auto_serialize] +enum struct_field_kind { + named_field(ident, class_mutability, visibility), + unnamed_field // element of a tuple-like struct +} + #[auto_serialize] type struct_def = { - traits: ~[@trait_ref], /* traits this class implements */ - members: ~[@class_member], /* methods, etc. */ + traits: ~[@trait_ref], /* traits this struct implements */ + fields: ~[@struct_field], /* fields */ + methods: ~[@method], /* methods */ /* (not including ctor or dtor) */ /* ctor is optional, and will soon go away */ ctor: option, @@ -750,15 +767,6 @@ enum item_ { item_mac(mac), } -#[auto_serialize] -type class_member = spanned; - -#[auto_serialize] -enum class_member_ { - instance_var(ident, @ty, class_mutability, node_id, visibility), - class_method(@method) -} - #[auto_serialize] enum class_mutability { class_mutable, class_immutable } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 5b2b4fb05613..c9b6b8794272 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -248,7 +248,6 @@ fn map_item(i: @item, cx: ctx, v: vt) { fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, ident: ast::ident, id: ast::node_id, cx: ctx, _v: vt) { - 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 struct_def.traits.each |p| { @@ -260,7 +259,7 @@ fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, let d_id = ast_util::local_def(id); let p = extend(cx, ident); // only need to handle methods - do vec::iter(ms) |m| { map_method(d_id, p, m, cx); } + do vec::iter(struct_def.methods) |m| { map_method(d_id, p, m, cx); } } fn map_view_item(vi: @view_item, cx: ctx, _v: vt) { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 4a6f8b1e77ab..0495ea7cd34c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -295,16 +295,6 @@ pure fn unguarded_pat(a: arm) -> option<~[@pat]> { if is_unguarded(a) { some(/* FIXME (#2543) */ copy a.pats) } else { none } } -pure fn class_item_ident(ci: @class_member) -> ident { - match ci.node { - instance_var(i,_,_,_,_) => /* FIXME (#2543) */ copy i, - class_method(it) => /* FIXME (#2543) */ copy it.ident - } -} - -type ivar = {ident: ident, ty: @ty, cm: class_mutability, - id: node_id, vis: visibility}; - fn public_methods(ms: ~[@method]) -> ~[@method] { vec::filter(ms, |m| match m.vis { @@ -313,23 +303,6 @@ fn public_methods(ms: ~[@method]) -> ~[@method] { }) } -fn split_class_items(cs: ~[@class_member]) -> (~[ivar], ~[@method]) { - let mut vs = ~[], ms = ~[]; - for cs.each |c| { - match c.node { - instance_var(i, t, cm, id, vis) => { - vec::push(vs, {ident: /* FIXME (#2543) */ copy i, - ty: t, - cm: cm, - id: id, - vis: vis}); - } - class_method(m) => vec::push(ms, m) - } - }; - (vs, ms) -} - // extract a ty_method from a trait_method. if the trait_method is // a default, pull out the useful fields to make a ty_method fn trait_method_to_ty_method(method: trait_method) -> ty_method { @@ -355,11 +328,11 @@ fn split_trait_methods(trait_methods: ~[trait_method]) (reqd, provd) } -pure fn class_member_visibility(ci: @class_member) -> visibility { - match ci.node { - instance_var(_, _, _, _, vis) => vis, - class_method(m) => m.vis - } +pure fn struct_field_visibility(field: ast::struct_field) -> visibility { + match field.node.kind { + ast::named_field(_, _, visibility) => visibility, + ast::unnamed_field => ast::public + } } trait inlined_item_utils { @@ -570,11 +543,11 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { _id: node_id) { }, - visit_class_item: fn@(c: @class_member) { - match c.node { - instance_var(_, _, _, id,_) => vfn(id), - class_method(_) => () - } + visit_struct_field: fn@(f: @struct_field) { + vfn(f.node.id); + }, + + visit_struct_method: fn@(_m: @method) { } }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5bd35490f0e9..705f21895b66 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -24,7 +24,7 @@ trait ast_fold { fn fold_view_item(&&@view_item) -> @view_item; fn fold_foreign_item(&&@foreign_item) -> @foreign_item; fn fold_item(&&@item) -> option<@item>; - fn fold_class_item(&&@class_member) -> @class_member; + fn fold_struct_field(&&@struct_field) -> @struct_field; fn fold_item_underscore(item_) -> item_; fn fold_method(&&@method) -> @method; fn fold_block(blk) -> blk; @@ -55,7 +55,7 @@ type ast_fold_precursor = @{ fold_view_item: fn@(view_item_, ast_fold) -> view_item_, fold_foreign_item: fn@(&&@foreign_item, ast_fold) -> @foreign_item, fold_item: fn@(&&@item, ast_fold) -> option<@item>, - fold_class_item: fn@(&&@class_member, ast_fold) -> @class_member, + fold_struct_field: fn@(&&@struct_field, ast_fold) -> @struct_field, fold_item_underscore: fn@(item_, ast_fold) -> item_, fold_method: fn@(&&@method, ast_fold) -> @method, fold_block: fn@(blk_, span, ast_fold) -> (blk_, span), @@ -214,16 +214,12 @@ fn noop_fold_item(&&i: @item, fld: ast_fold) -> option<@item> { span: fld.new_span(i.span)}); } -fn noop_fold_class_item(&&ci: @class_member, fld: ast_fold) - -> @class_member { - @{node: match ci.node { - instance_var(ident, t, cm, id, p) => { - instance_var(/* FIXME (#2543) */ copy ident, - fld.fold_ty(t), cm, id, p) - } - class_method(m) => class_method(fld.fold_method(m)) - }, - span: ci.span} +fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold) + -> @struct_field { + @{node: {kind: copy sf.node.kind, + id: sf.node.id, + ty: fld.fold_ty(sf.node.ty)}, + span: sf.span} } fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { @@ -295,7 +291,8 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) with dtor}}; return @{ traits: vec::map(struct_def.traits, |p| fold_trait_ref(p, fld)), - members: vec::map(struct_def.members, |x| fld.fold_class_item(x)), + fields: vec::map(struct_def.fields, |f| fold_struct_field(f, fld)), + methods: vec::map(struct_def.methods, |m| fld.fold_method(m)), ctor: resulting_optional_constructor, dtor: dtor }; @@ -306,6 +303,13 @@ fn fold_trait_ref(&&p: @trait_ref, fld: ast_fold) -> @trait_ref { impl_id: fld.new_id(p.impl_id)} } +fn fold_struct_field(&&f: @struct_field, fld: ast_fold) -> @struct_field { + @{node: {kind: copy f.node.kind, + id: fld.new_id(f.node.id), + ty: fld.fold_ty(f.node.ty)}, + span: fld.new_span(f.span)} +} + fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { return @{ident: fld.fold_ident(m.ident), attrs: /* FIXME (#2543) */ copy m.attrs, @@ -570,8 +574,9 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { with dtor}}; kind = struct_variant_kind(@{ traits: ~[], - members: vec::map(struct_def.members, - |x| fld.fold_class_item(x)), + fields: vec::map(struct_def.fields, + |f| fld.fold_struct_field(f)), + methods: vec::map(struct_def.methods, |m| fld.fold_method(m)), ctor: none, dtor: dtor }) @@ -644,7 +649,7 @@ fn default_ast_fold() -> ast_fold_precursor { fold_view_item: noop_fold_view_item, fold_foreign_item: noop_fold_foreign_item, fold_item: noop_fold_item, - fold_class_item: noop_fold_class_item, + fold_struct_field: noop_fold_struct_field, fold_item_underscore: noop_fold_item_underscore, fold_method: noop_fold_method, fold_block: wrap(noop_fold_block), @@ -692,16 +697,11 @@ impl ast_fold_precursor: ast_fold { fn fold_item(&&i: @item) -> option<@item> { return self.fold_item(i, self as ast_fold); } - fn fold_class_item(&&ci: @class_member) -> @class_member { - @{node: match ci.node { - instance_var(nm, t, mt, id, p) => { - instance_var(/* FIXME (#2543) */ copy nm, - (self as ast_fold).fold_ty(t), mt, id, p) - } - class_method(m) => { - class_method(self.fold_method(m, self as ast_fold)) - } - }, span: self.new_span(ci.span)} + fn fold_struct_field(&&sf: @struct_field) -> @struct_field { + @{node: {kind: copy sf.node.kind, + id: sf.node.id, + ty: (self as ast_fold).fold_ty(sf.node.ty)}, + span: self.new_span(sf.span)} } fn fold_item_underscore(i: item_) -> item_ { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4b8707d6858e..09930bc2553b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -21,7 +21,7 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, bound_copy, bound_send, bound_trait, bound_owned, box, by_copy, by_move, by_mutbl_ref, by_ref, by_val, capture_clause, capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item, - class_immutable, class_member, class_method, class_mutable, + class_immutable, class_mutable, crate, crate_cfg, crate_directive, decl, decl_item, decl_local, default_blk, deref, div, enum_def, enum_variant_kind, expl, expr, expr_, expr_addr_of, expr_match, expr_again, expr_assert, @@ -33,20 +33,21 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item, foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited, - init_assign, init_move, initializer, instance_var, item, item_, + init_assign, init_move, initializer, item, item_, item_class, item_const, item_enum, item_fn, item_foreign_mod, item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_, lit_bool, lit_float, lit_int, lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq, mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq, match_tok, method, mode, mt, mul, - mutability, neg, noreturn, not, pat, pat_box, pat_enum, + mutability, named_field, neg, noreturn, not, pat, pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare, proto_block, proto_box, proto_uniq, provided, public, pure_fn, purity, re_anon, re_named, region, rem, required, ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr, - stmt_semi, struct_def, struct_variant_kind, subtract, sty_box, + stmt_semi, struct_def, struct_field, struct_variant_kind, + subtract, sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn, @@ -94,6 +95,11 @@ enum pexpr { pexpr(@expr), } +enum class_member { + field_member(@struct_field), + method_member(@method) +} + /* So that we can distinguish a class ctor or dtor from other class members @@ -2043,8 +2049,11 @@ class parser { let name = self.parse_ident(); self.expect(token::COLON); let ty = self.parse_ty(false); - return @{node: instance_var(name, ty, is_mutbl, self.get_id(), pr), - span: mk_sp(lo, self.last_span.hi)}; + return @field_member(@spanned(lo, self.last_span.hi, { + kind: named_field(name, is_mutbl, pr), + id: self.get_id(), + ty: ty + })); } fn parse_stmt(+first_item_attrs: ~[attribute]) -> @stmt { @@ -2556,7 +2565,8 @@ class parser { { self.parse_trait_ref_list(token::LBRACE) } else { ~[] }; self.expect(token::LBRACE); - let mut ms: ~[@class_member] = ~[]; + let mut fields: ~[@struct_field] = ~[]; + let mut methods: ~[@method] = ~[]; let ctor_id = self.get_id(); let mut the_ctor : option<(fn_decl, ~[attribute], blk, codemap::span)> = none; @@ -2589,7 +2599,16 @@ class parser { } } } - members(mms) => { ms = vec::append(ms, mms); } + members(mms) => { + for mms.each |mm| { + match mm { + @field_member(struct_field) => + vec::push(fields, struct_field), + @method_member(the_method_member) => + vec::push(methods, the_method_member) + } + } + } } } let actual_dtor = do option::map(the_dtor) |dtor| { @@ -2605,7 +2624,8 @@ class parser { (class_name, item_class(@{ traits: traits, - members: ms, + fields: move fields, + methods: move methods, ctor: some({ node: {id: ctor_id, attrs: ct_attrs, @@ -2621,7 +2641,8 @@ class parser { (class_name, item_class(@{ traits: traits, - members: ms, + fields: move fields, + methods: move methods, ctor: none, dtor: actual_dtor }, ty_params), @@ -2647,7 +2668,7 @@ class parser { return a_var; } else { let m = self.parse_method(vis); - return @{node: class_method(m), span: m.span}; + return @method_member(m); } } @@ -2883,7 +2904,8 @@ class parser { fn parse_struct_def(path: @path) -> @struct_def { let mut the_dtor: option<(blk, ~[attribute], codemap::span)> = none; - let mut ms: ~[@class_member] = ~[]; + let mut fields: ~[@struct_field] = ~[]; + let mut methods: ~[@method] = ~[]; while self.token != token::RBRACE { match self.parse_class_item(path) { ctor_decl(*) => { @@ -2906,8 +2928,16 @@ class parser { } } } - members(mms) => - ms = vec::append(ms, mms) + members(mms) => { + for mms.each |mm| { + match mm { + @field_member(struct_field) => + vec::push(fields, struct_field), + @method_member(the_method_member) => + vec::push(methods, the_method_member) + } + } + } } } self.bump(); @@ -2922,7 +2952,8 @@ class parser { return @{ traits: ~[], - members: ms, + fields: move fields, + methods: move methods, ctor: none, dtor: actual_dtor }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 49ded036e045..edcdd7d2baf1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -629,45 +629,29 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], head(s, ~"drop"); print_block(s, dtor.node.body); } - for struct_def.members.each |ci| { - /* - FIXME (#1893): collect all private items and print - them in a single "priv" section - - tjc: I'm not going to fix this yet b/c we might - change how exports work, including for class items - */ - hardbreak_if_not_bol(s); - maybe_print_comment(s, ci.span.lo); - let pr = ast_util::class_member_visibility(ci); - match pr { - ast::private => { - head(s, ~"priv"); - bopen(s); - hardbreak_if_not_bol(s); - } - _ => () - } - match ci.node { - ast::instance_var(nm, t, mt, _,_) => { - word_nbsp(s, ~"let"); - match mt { - ast::class_mutable => word_nbsp(s, ~"mut"), - _ => () - } - word(s.s, *nm); - word_nbsp(s, ~":"); - print_type(s, t); - word(s.s, ~";"); - } - ast::class_method(m) => { - print_method(s, m); - } - } - match pr { - ast::private => bclose(s, ci.span), - _ => () - } + for struct_def.fields.each |field| { + match field.node.kind { + ast::unnamed_field => {} // We don't print here. + ast::named_field(ident, mutability, visibility) => { + hardbreak_if_not_bol(s); + maybe_print_comment(s, field.span.lo); + if visibility == ast::private { + head(s, ~"priv"); + bopen(s); + hardbreak_if_not_bol(s); + } + if mutability == ast::class_mutable { + word_nbsp(s, ~"mut"); + } + word(s.s, *ident); + word_nbsp(s, ~":"); + print_type(s, field.node.ty); + word(s.s, ~";"); + } + } + } + for struct_def.methods.each |method| { + print_method(s, method); } bclose(s, span); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 93d253d21639..f9d861f15e1e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -63,7 +63,8 @@ type visitor = visit_trait_method: fn@(trait_method, E, vt), visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id, E, vt), - visit_class_item: fn@(@class_member, E, vt)}; + visit_struct_field: fn@(@struct_field, E, vt), + visit_struct_method: fn@(@method, E, vt)}; fn default_visitor() -> visitor { return @{visit_mod: |a,b,c,d,e|visit_mod::(a, b, c, d, e), @@ -85,7 +86,8 @@ fn default_visitor() -> visitor { visit_trait_method: |a,b,c|visit_trait_method::(a, b, c), visit_struct_def: |a,b,c,d,e,f|visit_struct_def::(a, b, c, d, e, f), - visit_class_item: |a,b,c|visit_class_item::(a, b, c)}; + visit_struct_field: |a,b,c|visit_struct_field::(a, b, c), + visit_struct_method: |a,b,c|visit_struct_method::(a, b, c)}; } fn visit_crate(c: crate, e: E, v: vt) { @@ -183,13 +185,6 @@ fn visit_enum_def(enum_definition: ast::enum_def, tps: ~[ast::ty_param], } } -fn visit_class_item(cm: @class_member, e:E, v:vt) { - match cm.node { - instance_var(_, t, _, _, _) => v.visit_ty(t, e, v), - class_method(m) => visit_method_helper(m, e, v) - } -} - fn skip_ty(_t: @ty, _e: E, _v: vt) {} fn visit_ty(t: @ty, e: E, v: vt) { @@ -332,8 +327,11 @@ fn visit_trait_method(m: trait_method, e: E, v: vt) { fn visit_struct_def(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], id: node_id, e: E, v: vt) { - for sd.members.each |m| { - v.visit_class_item(m, e, v); + for sd.fields.each |f| { + v.visit_struct_field(f, e, v); + } + for sd.methods.each |m| { + v.visit_struct_method(m, e, v); } for sd.traits.each |p| { visit_path(p.path, e, v); } do option::iter(sd.ctor) |ctor| { @@ -344,6 +342,14 @@ fn visit_struct_def(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], }; } +fn visit_struct_field(sf: @struct_field, e: E, v: vt) { + v.visit_ty(sf.node.ty, e, v); +} + +fn visit_struct_method(m: @method, e: E, v: vt) { + visit_method_helper(m, e, v); +} + fn visit_block(b: ast::blk, e: E, v: vt) { for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); } for b.node.stmts.each |s| { v.visit_stmt(s, e, v); } @@ -492,7 +498,8 @@ type simple_visitor = visit_ty_method: fn@(ty_method), visit_trait_method: fn@(trait_method), visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id), - visit_class_item: fn@(@class_member)}; + visit_struct_field: fn@(@struct_field), + visit_struct_method: fn@(@method)}; fn simple_ignore_ty(_t: @ty) {} @@ -517,7 +524,8 @@ fn default_simple_visitor() -> simple_visitor { visit_trait_method: fn@(_m: trait_method) { }, visit_struct_def: fn@(_sd: @struct_def, _nm: ident, _tps: ~[ty_param], _id: node_id) { }, - visit_class_item: fn@(_c: @class_member) {} + visit_struct_field: fn@(_f: @struct_field) { }, + visit_struct_method: fn@(_m: @method) { } }; } @@ -607,11 +615,14 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { } else { |a,b,c| v_ty(v.visit_ty, a, b, c) }; - fn v_class_item(f: fn@(@class_member), - cm: @class_member, &&e: (), - v: vt<()>) { - f(cm); - visit_class_item(cm, e, v); + fn v_struct_field(f: fn@(@struct_field), sf: @struct_field, &&e: (), + v: vt<()>) { + f(sf); + visit_struct_field(sf, e, v); + } + fn v_struct_method(f: fn@(@method), m: @method, &&e: (), v: vt<()>) { + f(m); + visit_struct_method(m, e, v); } return mk_vt(@{visit_mod: |a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e), visit_view_item: |a,b,c| @@ -639,8 +650,10 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_trait_method(v.visit_trait_method, a, b, c), visit_struct_def: |a,b,c,d,e,f| v_struct_def(v.visit_struct_def, a, b, c, d, e, f), - visit_class_item: |a,b,c| - v_class_item(v.visit_class_item, a, b, c) + visit_struct_field: |a,b,c| + v_struct_field(v.visit_struct_field, a, b, c), + visit_struct_method: |a,b,c| + v_struct_method(v.visit_struct_method, a, b, c) }); } diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 70754ccdd820..6678b6e036ae 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -745,11 +745,12 @@ fn get_class_fields(cdata: cmd, id: ast::node_id) -> ~[ty::field_ty] { } fn family_has_type_params(fam_ch: char) -> bool { - match check fam_ch { - 'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' | 'e' => false, + match fam_ch { + 'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' | 'e' | 'N' => false, 'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' | 'C' | 'a' | 'S' - => true + => true, + _ => fail fmt!("'%c' is not a family", fam_ch) } } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 7d006369359d..968f051710bd 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -158,19 +158,27 @@ fn encode_foreign_module_item_paths(ebml_w: ebml::writer, nmod: foreign_mod, } fn encode_class_item_paths(ebml_w: ebml::writer, - items: ~[@class_member], path: ~[ident], &index: ~[entry<~str>]) { - for items.each |it| { - match ast_util::class_member_visibility(it) { - private => again, - public | inherited => { - let (id, ident) = match it.node { - instance_var(v, _, _, vid, _) => (vid, v), - class_method(it) => (it.id, it.ident) - }; - add_to_index(ebml_w, path, index, ident); - encode_named_def_id(ebml_w, ident, local_def(id)); - } - } + fields: ~[@ast::struct_field], + methods: ~[@ast::method], + path: ~[ident], + &index: ~[entry<~str>]) { + for fields.each |field| { + match field.node.kind { + ast::named_field(ident, _, visibility) => { + if visibility == private { again; } + let (id, ident) = (field.node.id, ident); + add_to_index(ebml_w, path, index, ident); + encode_named_def_id(ebml_w, ident, local_def(id)); + } + ast::unnamed_field => {} + } + } + + for methods.each |method| { + if method.vis == private { again; } + let (id, ident) = (method.id, method.ident); + add_to_index(ebml_w, path, index, ident); + encode_named_def_id(ebml_w, ident, local_def(id)); } } @@ -257,7 +265,8 @@ fn encode_struct_def(ebml_w: ebml::writer, } encode_class_item_paths(ebml_w, - struct_def.members, + struct_def.fields, + struct_def.methods, vec::append_one(path, ident), index); } @@ -527,32 +536,38 @@ fn encode_self_type(ebml_w: ebml::writer, self_type: ast::self_ty_) { fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id, path: ast_map::path, class_tps: ~[ty_param], - items: ~[@class_member], + fields: ~[@struct_field], + methods: ~[@method], global_index: @mut~[entry]) -> ~[entry] { /* Each class has its own index, since different classes may have fields with the same name */ let index = @mut ~[]; let tcx = ecx.tcx; - for items.each |ci| { /* We encode both private and public fields -- need to include private fields to get the offsets right */ - match ci.node { - instance_var(nm, _, mt, id, vis) => { - vec::push(*index, {val: id, pos: ebml_w.writer.tell()}); - vec::push(*global_index, {val: id, pos: ebml_w.writer.tell()}); - ebml_w.start_tag(tag_items_data_item); - debug!{"encode_info_for_class: doing %s %d", *nm, id}; - encode_visibility(ebml_w, vis); - encode_name(ebml_w, nm); - encode_path(ebml_w, path, ast_map::path_name(nm)); - encode_type(ecx, ebml_w, node_id_to_type(tcx, id)); - encode_mutability(ebml_w, mt); - encode_def_id(ebml_w, local_def(id)); - ebml_w.end_tag(); + for fields.each |field| { + match field.node.kind { + named_field(nm, mt, vis) => { + let id = field.node.id; + vec::push(*index, {val: id, pos: ebml_w.writer.tell()}); + vec::push(*global_index, {val: id, pos: ebml_w.writer.tell()}); + ebml_w.start_tag(tag_items_data_item); + debug!{"encode_info_for_class: doing %s %d", *nm, id}; + encode_visibility(ebml_w, vis); + encode_name(ebml_w, nm); + encode_path(ebml_w, path, ast_map::path_name(nm)); + encode_type(ecx, ebml_w, node_id_to_type(tcx, id)); + encode_mutability(ebml_w, mt); + encode_def_id(ebml_w, local_def(id)); + ebml_w.end_tag(); + } + unnamed_field => {} } - class_method(m) => { - match m.vis { - public | inherited => { + } + + for methods.each |m| { + match m.vis { + public | inherited => { vec::push(*index, {val: m.id, pos: ebml_w.writer.tell()}); vec::push(*global_index, {val: m.id, pos: ebml_w.writer.tell()}); @@ -564,10 +579,9 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer, vec::append(class_tps, m.tps)); } _ => { /* don't encode private methods */ } - } } - } - }; + } + *index } @@ -738,7 +752,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, 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, - struct_def.members, index); + struct_def.fields, struct_def.methods, + index); /* Encode the dtor */ do option::iter(struct_def.dtor) |dtor| { vec::push(*index, {val: dtor.node.id, pos: ebml_w.writer.tell()}); @@ -779,15 +794,20 @@ 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(struct_def.members); - for fs.each |f| { - ebml_w.start_tag(tag_item_field); - encode_visibility(ebml_w, f.vis); - encode_name(ebml_w, f.ident); - encode_def_id(ebml_w, local_def(f.id)); - ebml_w.end_tag(); + for struct_def.fields.each |f| { + match f.node.kind { + named_field(ident, mutability, vis) => { + ebml_w.start_tag(tag_item_field); + encode_visibility(ebml_w, vis); + encode_name(ebml_w, ident); + encode_def_id(ebml_w, local_def(f.node.id)); + ebml_w.end_tag(); + } + unnamed_field => {} + } } - for ms.each |m| { + + for struct_def.methods.each |m| { match m.vis { private => { /* do nothing */ } public | inherited => { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index 0262efca156d..9eef85600fc1 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -12,7 +12,7 @@ import syntax::ast::{bitand, bitor, bitxor}; import syntax::ast::{blk, bound_const, bound_copy, bound_owned, bound_send}; import syntax::ast::{bound_trait, binding_mode, capture_clause, class_ctor, class_dtor}; -import syntax::ast::{class_member, class_method, crate, crate_num, decl_item}; +import syntax::ast::{crate, crate_num, decl_item}; import syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn}; import syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod}; import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param}; @@ -27,15 +27,15 @@ import syntax::ast::{expr_binary, expr_break, expr_cast, expr_field, expr_fn}; import syntax::ast::{expr_fn_block, expr_index, expr_loop}; import syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl}; import syntax::ast::{foreign_item, foreign_item_fn, ge, gt, ident, trait_ref}; -import syntax::ast::{impure_fn, instance_var, item, item_class, item_const}; +import syntax::ast::{impure_fn, item, item_class, item_const}; import syntax::ast::{item_enum, item_fn, item_mac, item_foreign_mod}; import syntax::ast::{item_impl, item_mod, item_trait, item_ty, le, local}; import syntax::ast::{local_crate, lt, method, mul, ne, neg, node_id, pat}; import syntax::ast::{pat_enum, pat_ident, path, prim_ty, pat_box, pat_uniq}; import syntax::ast::{pat_lit, pat_range, pat_rec, pat_struct, pat_tup}; import syntax::ast::{pat_wild, provided, required, rem, self_ty_, shl}; -import syntax::ast::{stmt_decl, struct_variant_kind, sty_static, subtract}; -import syntax::ast::{tuple_variant_kind, ty}; +import syntax::ast::{stmt_decl, struct_field, struct_variant_kind}; +import syntax::ast::{sty_static, subtract, tuple_variant_kind, ty}; import syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i}; import syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param}; import syntax::ast::{ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8}; @@ -1021,23 +1021,16 @@ class Resolver { // bindings. let mut method_infos = ~[]; - for struct_definition.members.each |class_member| { - match class_member.node { - class_method(method) => { - // XXX: Combine with impl method code below. - method_infos += ~[ - @{ - did: local_def(method.id), - n_tps: method.tps.len(), - ident: method.ident, - self_type: method.self_ty.node - } - ]; + for struct_definition.methods.each |method| { + // XXX: Combine with impl method code below. + method_infos += ~[ + @{ + did: local_def(method.id), + n_tps: method.tps.len(), + ident: method.ident, + self_type: method.self_ty.node } - instance_var(*) => { - // Don't need to do anything with this. - } - } + ]; } let impl_info = @{ @@ -3195,7 +3188,8 @@ class Resolver { self.resolve_class(item.id, @copy ty_params, struct_def.traits, - struct_def.members, + struct_def.fields, + struct_def.methods, struct_def.ctor, struct_def.dtor, visitor); @@ -3435,7 +3429,8 @@ class Resolver { fn resolve_class(id: node_id, type_parameters: @~[ty_param], traits: ~[@trait_ref], - class_members: ~[@class_member], + fields: ~[@struct_field], + methods: ~[@method], optional_constructor: option, optional_destructor: option, visitor: ResolveVisitor) { @@ -3479,19 +3474,16 @@ class Resolver { } // Resolve methods. - for class_members.each |class_member| { - match class_member.node { - class_method(method) => { - self.resolve_method(MethodRibKind(id, - Provided(method.id)), - method, - outer_type_parameter_count, - visitor); - } - instance_var(_, field_type, _, _, _) => { - self.resolve_type(field_type, visitor); - } - } + for methods.each |method| { + self.resolve_method(MethodRibKind(id, Provided(method.id)), + method, + outer_type_parameter_count, + visitor); + } + + // Resolve fields. + for fields.each |field| { + self.resolve_type(field.node.ty, visitor); } // Resolve the constructor, if applicable. diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 487435f2ef2c..3195768a1052 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -5062,8 +5062,7 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def, // 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); + impl::trans_impl(ccx, *path, ident, struct_def.methods, tps); } fn trans_trait(ccx: @crate_ctxt, tps: ~[ast::ty_param], diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 20e005d7c54f..1d7771b57d53 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -7,7 +7,7 @@ import driver::session::session; import syntax::{ast, ast_map}; import ast_map::{path, path_mod, path_name, node_id_to_str}; import driver::session::expect; -import syntax::ast_util::{local_def, split_class_items}; +import syntax::ast_util::local_def; import metadata::csearch; import back::{link, abi}; import lib::llvm::llvm; @@ -163,8 +163,7 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, } ast_map::node_item(@{node: ast::item_class(struct_def, _), _}, _) => { - let (_,ms) = split_class_items(struct_def.members); - method_from_methods(ms, name) + method_from_methods(struct_def.methods, name) } } } else { diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 8cf4bde575d0..62107e76bdbb 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -126,16 +126,11 @@ fn traverse_public_item(cx: ctx, item: @item) { traverse_inline_body(cx, dtor.node.body); } } - for vec::each(struct_def.members) |item| { - match item.node { - class_method(m) => { - cx.rmap.insert(m.id, ()); - if tps.len() > 0u || - attr::find_inline_attr(m.attrs) != attr::ia_none { - traverse_inline_body(cx, m.body); - } - } - _ => () + for vec::each(struct_def.methods) |m| { + cx.rmap.insert(m.id, ()); + if tps.len() > 0 || + attr::find_inline_attr(m.attrs) != attr::ia_none { + traverse_inline_body(cx, m.body); } } } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 72cfbca1af03..8936e203e0d9 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -8,8 +8,7 @@ import driver::session; import session::session; import syntax::{ast, ast_map}; import syntax::ast_util; -import syntax::ast_util::{is_local, local_def, split_class_items, - new_def_hash}; +import syntax::ast_util::{is_local, local_def, new_def_hash}; import syntax::codemap::span; import metadata::csearch; import util::ppaux::{region_to_str, explain_region, vstore_to_str}; @@ -3006,10 +3005,10 @@ 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(struct_def, _) => { - class_field_tys(struct_def.members) - } - _ => cx.sess.bug(~"class ID bound to non-class") + ast::item_class(struct_def, _) => { + class_field_tys(struct_def.fields) + } + _ => cx.sess.bug(~"class ID bound to non-class") } } _ => { @@ -3062,9 +3061,9 @@ fn lookup_class_method_by_name(cx:ctxt, did: ast::def_id, name: ident, some(ast_map::node_item(@{ node: item_class(struct_def, _), _ }, _)) => { - let (_,ms) = split_class_items(struct_def.members); - vec::map(ms, |m| {name: m.ident, id: m.id, - vis: m.vis}) + vec::map(struct_def.methods, |m| {name: m.ident, + id: m.id, + vis: m.vis}) } _ => { cx.sess.bug(~"lookup_class_method_ids: id not bound to a class"); @@ -3087,15 +3086,17 @@ fn lookup_class_method_by_name(cx:ctxt, did: ast::def_id, name: ident, } } -fn class_field_tys(items: ~[@class_member]) -> ~[field_ty] { +fn class_field_tys(fields: ~[@struct_field]) -> ~[field_ty] { let mut rslt = ~[]; - for items.each |it| { - match it.node { - instance_var(nm, _, cm, id, vis) => { - vec::push(rslt, {ident: nm, id: ast_util::local_def(id), - vis: vis, mutability: cm}); - } - class_method(_) => () + for fields.each |field| { + match field.node.kind { + named_field(ident, mutability, visibility) => { + vec::push(rslt, {ident: ident, + id: ast_util::local_def(field.node.id), + vis: visibility, + mutability: mutability}); + } + unnamed_field => {} } } rslt diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 88469c33516e..2d2bf15c5a23 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -43,8 +43,7 @@ import syntax::{ast, ast_util, ast_map}; import ast::spanned; import ast::{required, provided}; import syntax::ast_map::node_id_to_str; -import syntax::ast_util::{local_def, respan, split_class_items, - split_trait_methods}; +import syntax::ast_util::{local_def, respan, split_trait_methods}; import syntax::visit; import metadata::csearch; import driver::session::session; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 64ebcd5fbbbb..0c04d71e3d72 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -372,19 +372,6 @@ fn check_method(ccx: @crate_ctxt, method: @ast::method, check_bare_fn(ccx, method.decl, method.body, method.id, some(self_info)); } -fn check_class_member(ccx: @crate_ctxt, self_ty: ty::t, - node_id: ast::node_id, - cm: @ast::class_member) { - match cm.node { - ast::instance_var(_,t,_,_,_) => (), - ast::class_method(m) => { - let class_t = {self_ty: self_ty, node_id: node_id, - explicit_self: m.self_ty.node}; - check_method(ccx, m, class_t) - } - } -} - fn check_no_duplicate_fields(tcx: ty::ctxt, fields: ~[(ast::ident, span)]) { let field_names = hashmap::<@~str, span>(|x| str::hash(*x), @@ -435,13 +422,13 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def, 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, self_ty, id, m); + // typecheck the methods + for struct_def.methods.each |m| { + check_method(ccx, m, {self_ty: self_ty, node_id: id, + explicit_self: m.self_ty.node}); } // Check that there's at least one field - let (fields,_) = split_class_items(struct_def.members); - if fields.len() < 1u { + if struct_def.fields.len() < 1u { ccx.tcx.sess.span_err(span, ~"a class must have at least one field"); } // Check that the class is instantiable diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index 24e80b137440..c8a9f850aa05 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -17,7 +17,7 @@ import middle::ty::{ty_param, ty_self, ty_type, ty_opaque_box}; import middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_is_var}; import middle::typeck::infer::{infer_ctxt, mk_subty}; import middle::typeck::infer::{new_infer_ctxt, resolve_ivar, resolve_type}; -import syntax::ast::{class_method, crate, def_id, def_mod, instance_var}; +import syntax::ast::{crate, def_id, def_mod}; import syntax::ast::{item, item_class, item_const, item_enum, item_fn}; import syntax::ast::{item_foreign_mod, item_impl, item_mac, item_mod}; import syntax::ast::{item_trait, item_ty, local_crate, method, node_id}; @@ -650,20 +650,13 @@ class CoherenceChecker { 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 - }); - } - } + for struct_def.methods.each |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 }; diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 0394813746dc..c98746f945a6 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -215,10 +215,9 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) { }); } 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| { + store_methods::<@ast::method>(ccx, id, struct_def.methods, |m| { ty_of_method(ccx, m, rp) }); } @@ -369,11 +368,12 @@ fn check_methods_against_trait(ccx: @crate_ctxt, fn convert_field(ccx: @crate_ctxt, rp: bool, bounds: @~[ty::param_bounds], - v: ast_util::ivar) { - let tt = ccx.to_ty(type_rscope(rp), v.ty); - write_ty_to_tcx(ccx.tcx, v.id, tt); + v: @ast::struct_field) { + let tt = ccx.to_ty(type_rscope(rp), v.node.ty); + write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ - ccx.tcx.tcache.insert(local_def(v.id), {bounds: bounds, rp: rp, ty: tt}); + ccx.tcx.tcache.insert(local_def(v.node.id), + {bounds: bounds, rp: rp, ty: tt}); } type converted_method = {mty: ty::method, id: ast::node_id, span: span}; @@ -505,13 +505,12 @@ fn convert_struct(ccx: @crate_ctxt, rp: bool, struct_def: @ast::struct_def, ensure_trait_methods(ccx, id, tpt.ty); // Write the type of each of the members - let (fields, methods) = split_class_items(struct_def.members); - for fields.each |f| { + for struct_def.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); + let cms = convert_methods(ccx, struct_def.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