rustc: Perform some AST surgery to separate out class fields from methods
This commit is contained in:
parent
353c632c2d
commit
3038968f28
18 changed files with 301 additions and 308 deletions
|
|
@ -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<struct_field_>;
|
||||
|
||||
#[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<class_ctor>,
|
||||
|
|
@ -750,15 +767,6 @@ enum item_ {
|
|||
item_mac(mac),
|
||||
}
|
||||
|
||||
#[auto_serialize]
|
||||
type class_member = spanned<class_member_>;
|
||||
|
||||
#[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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ type visitor<E> =
|
|||
visit_trait_method: fn@(trait_method, E, vt<E>),
|
||||
visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id, E,
|
||||
vt<E>),
|
||||
visit_class_item: fn@(@class_member, E, vt<E>)};
|
||||
visit_struct_field: fn@(@struct_field, E, vt<E>),
|
||||
visit_struct_method: fn@(@method, E, vt<E>)};
|
||||
|
||||
fn default_visitor<E>() -> visitor<E> {
|
||||
return @{visit_mod: |a,b,c,d,e|visit_mod::<E>(a, b, c, d, e),
|
||||
|
|
@ -85,7 +86,8 @@ fn default_visitor<E>() -> visitor<E> {
|
|||
visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c),
|
||||
visit_struct_def: |a,b,c,d,e,f|visit_struct_def::<E>(a, b, c,
|
||||
d, e, f),
|
||||
visit_class_item: |a,b,c|visit_class_item::<E>(a, b, c)};
|
||||
visit_struct_field: |a,b,c|visit_struct_field::<E>(a, b, c),
|
||||
visit_struct_method: |a,b,c|visit_struct_method::<E>(a, b, c)};
|
||||
}
|
||||
|
||||
fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
|
||||
|
|
@ -183,13 +185,6 @@ fn visit_enum_def<E>(enum_definition: ast::enum_def, tps: ~[ast::ty_param],
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) {
|
||||
match cm.node {
|
||||
instance_var(_, t, _, _, _) => v.visit_ty(t, e, v),
|
||||
class_method(m) => visit_method_helper(m, e, v)
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {}
|
||||
|
||||
fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
|
||||
|
|
@ -332,8 +327,11 @@ fn visit_trait_method<E>(m: trait_method, e: E, v: vt<E>) {
|
|||
|
||||
fn visit_struct_def<E>(sd: @struct_def, nm: ast::ident, tps: ~[ty_param],
|
||||
id: node_id, e: E, v: vt<E>) {
|
||||
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<E>(sd: @struct_def, nm: ast::ident, tps: ~[ty_param],
|
|||
};
|
||||
}
|
||||
|
||||
fn visit_struct_field<E>(sf: @struct_field, e: E, v: vt<E>) {
|
||||
v.visit_ty(sf.node.ty, e, v);
|
||||
}
|
||||
|
||||
fn visit_struct_method<E>(m: @method, e: E, v: vt<E>) {
|
||||
visit_method_helper(m, e, v);
|
||||
}
|
||||
|
||||
fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) {
|
||||
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)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<int>]) -> ~[entry<int>] {
|
||||
/* 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 => {
|
||||
|
|
|
|||
|
|
@ -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<class_ctor>,
|
||||
optional_destructor: option<class_dtor>,
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue