diff --git a/src/rustc/metadata/astencode_gen.rs b/src/rustc/metadata/astencode_gen.rs index 1c413de261ca..5bf9829b99d3 100644 --- a/src/rustc/metadata/astencode_gen.rs +++ b/src/rustc/metadata/astencode_gen.rs @@ -3783,8 +3783,39 @@ fn serialize_148(s: S, }) }); } -/*syntax::ast::ty_method*/ +/*syntax::ast::class_ctor_*/ fn serialize_156(s: S, + v: + syntax::ast::class_ctor_) { + s.emit_rec(/*syntax::ast::node_id*//*syntax::ast::fn_decl*/ + /*syntax::ast::blk*/ + {|| + { + s.emit_rec_field("id", 0u, + {|| serialize_27(s, v.id) }); + s.emit_rec_field("dec", 1u, + {|| serialize_38(s, v.dec) }); + s.emit_rec_field("body", 2u, + {|| serialize_81(s, v.body) }) + } + }); +} +/*syntax::ast::class_ctor*/ +fn serialize_155(s: S, + v: + syntax::ast::class_ctor) { + s.emit_rec(/*syntax::ast::class_ctor_*//*syntax::codemap::span*/ + {|| + { + s.emit_rec_field("node", 0u, + {|| serialize_156(s, v.node) }); + s.emit_rec_field("span", 1u, + {|| serialize_19(s, v.span) }) + } + }); +} +/*syntax::ast::ty_method*/ +fn serialize_158(s: S, v: syntax::ast::ty_method) { s.emit_rec(/*syntax::ast::ident*//*[syntax::ast::attribute]*/ @@ -3806,19 +3837,19 @@ fn serialize_156(s: S, }); } /*[syntax::ast::ty_method]*/ -fn serialize_155(s: S, +fn serialize_157(s: S, v: [syntax::ast::ty_method]) { s.emit_vec(vec::len(v), /*syntax::ast::ty_method*/ {|| vec::iteri(v, {|i, e| - s.emit_vec_elt(i, {|| serialize_156(s, e) }) + s.emit_vec_elt(i, {|| serialize_158(s, e) }) }) }); } /*core::option::t<@syntax::ast::ty>*/ -fn serialize_157(s: S, +fn serialize_159(s: S, v: core::option::t<@syntax::ast::ty>) { s.emit_enum("core::option::t", @@ -3846,7 +3877,7 @@ fn serialize_157(s: S, }); } /*syntax::ast::method*/ -fn serialize_160(s: S, +fn serialize_162(s: S, v: syntax::ast::method) { s.emit_rec(/*syntax::ast::ident*//*[syntax::ast::attribute]*/ @@ -3873,20 +3904,20 @@ fn serialize_160(s: S, }); } /*@syntax::ast::method*/ -fn serialize_159(s: S, +fn serialize_161(s: S, v: @syntax::ast::method) { - s.emit_box(/*syntax::ast::method*/{|| serialize_160(s, *v) }); + s.emit_box(/*syntax::ast::method*/{|| serialize_162(s, *v) }); } /*[@syntax::ast::method]*/ -fn serialize_158(s: S, +fn serialize_160(s: S, v: [@syntax::ast::method]) { s.emit_vec(vec::len(v), /*@syntax::ast::method*/ {|| vec::iteri(v, {|i, e| - s.emit_vec_elt(i, {|| serialize_159(s, e) }) + s.emit_vec_elt(i, {|| serialize_161(s, e) }) }) }); } @@ -3906,8 +3937,7 @@ fn serialize_28(s: S, /*syntax::ast::blk*//*syntax::ast::node_id*/ /*syntax::ast::node_id*/ /*[syntax::ast::ty_param]*//*[@syntax::ast::class_item]*/ - /*syntax::ast::node_id*//*syntax::ast::fn_decl*/ - /*syntax::ast::blk*/ + /*syntax::ast::class_ctor*/ /*[syntax::ast::ty_param]*//*[syntax::ast::ty_method]*/ /*[syntax::ast::ty_param]*/ /*core::option::t<@syntax::ast::ty>*//*@syntax::ast::ty*/ @@ -4044,8 +4074,8 @@ fn serialize_28(s: S, } }) } - syntax::ast::item_class(v0, v1, v2, v3, v4) { - s.emit_enum_variant("syntax::ast::item_class", 7u, 5u, + syntax::ast::item_class(v0, v1, v2) { + s.emit_enum_variant("syntax::ast::item_class", 7u, 3u, {|| { s.emit_enum_variant_arg(0u, @@ -4060,18 +4090,8 @@ fn serialize_28(s: S, }); s.emit_enum_variant_arg(2u, {|| - serialize_27(s, - v2) - }); - s.emit_enum_variant_arg(3u, - {|| - serialize_38(s, - v3) - }); - s.emit_enum_variant_arg(4u, - {|| - serialize_81(s, - v4) + serialize_155(s, + v2) }) } }) @@ -4087,7 +4107,7 @@ fn serialize_28(s: S, }); s.emit_enum_variant_arg(1u, {|| - serialize_155(s, + serialize_157(s, v1) }) } @@ -4104,7 +4124,7 @@ fn serialize_28(s: S, }); s.emit_enum_variant_arg(1u, {|| - serialize_157(s, + serialize_159(s, v1) }); s.emit_enum_variant_arg(2u, @@ -4114,7 +4134,7 @@ fn serialize_28(s: S, }); s.emit_enum_variant_arg(3u, {|| - serialize_158(s, + serialize_160(s, v3) }) } @@ -7599,8 +7619,51 @@ fn deserialize_148(s: S) -> }) }) } -/*syntax::ast::ty_method*/ +/*syntax::ast::class_ctor_*/ fn deserialize_156(s: S) -> + syntax::ast::class_ctor_ { + + s.read_rec( + + + /*syntax::ast::node_id*/ + + /*syntax::ast::fn_decl*/ + + /*syntax::ast::blk*/ + + {|| + {id: s.read_rec_field("id", 0u, {|| deserialize_27(s) }), + dec: s.read_rec_field("dec", 1u, {|| deserialize_38(s) }), + body: + s.read_rec_field("body", 2u, + {|| deserialize_81(s) }),} + }) + +} +/*syntax::ast::class_ctor*/ +fn deserialize_155(s: S) -> + syntax::ast::class_ctor { + + s.read_rec( + + + /*syntax::ast::class_ctor_*/ + + /*syntax::codemap::span*/ + + {|| + {node: + s.read_rec_field("node", 0u, + {|| deserialize_156(s) }), + span: + s.read_rec_field("span", 1u, + {|| deserialize_19(s) }),} + }) + +} +/*syntax::ast::ty_method*/ +fn deserialize_158(s: S) -> syntax::ast::ty_method { s.read_rec( @@ -7632,7 +7695,7 @@ fn deserialize_156(s: S) -> } /*[syntax::ast::ty_method]*/ -fn deserialize_155(s: S) -> +fn deserialize_157(s: S) -> [syntax::ast::ty_method] { s.read_vec( @@ -7641,12 +7704,12 @@ fn deserialize_155(s: S) -> vec::init_fn(len, {|i| s.read_vec_elt(i, - {|| deserialize_156(s) }) + {|| deserialize_158(s) }) }) }) } /*core::option::t<@syntax::ast::ty>*/ -fn deserialize_157(s: S) -> +fn deserialize_159(s: S) -> core::option::t<@syntax::ast::ty> { s.read_enum("core::option::t", @@ -7667,7 +7730,7 @@ fn deserialize_157(s: S) -> }) } /*syntax::ast::method*/ -fn deserialize_160(s: S) -> +fn deserialize_162(s: S) -> syntax::ast::method { s.read_rec( @@ -7706,14 +7769,14 @@ fn deserialize_160(s: S) -> } /*@syntax::ast::method*/ -fn deserialize_159(s: S) -> +fn deserialize_161(s: S) -> @syntax::ast::method { - s.read_box(/*syntax::ast::method*/{|| @deserialize_160(s) }) + s.read_box(/*syntax::ast::method*/{|| @deserialize_162(s) }) } /*[@syntax::ast::method]*/ -fn deserialize_158(s: S) -> +fn deserialize_160(s: S) -> [@syntax::ast::method] { s.read_vec( @@ -7722,7 +7785,7 @@ fn deserialize_158(s: S) -> vec::init_fn(len, {|i| s.read_vec_elt(i, - {|| deserialize_159(s) }) + {|| deserialize_161(s) }) }) }) } @@ -7748,8 +7811,7 @@ fn deserialize_28(s: S) -> /*syntax::ast::node_id*/ /*[syntax::ast::ty_param]*//*[@syntax::ast::class_item]*/ - /*syntax::ast::node_id*//*syntax::ast::fn_decl*/ - /*syntax::ast::blk*/ + /*syntax::ast::class_ctor*/ /*[syntax::ast::ty_param]*//*[syntax::ast::ty_method]*/ @@ -7848,15 +7910,7 @@ fn deserialize_28(s: S) -> }), s.read_enum_variant_arg(2u, {|| - deserialize_27(s) - }), - s.read_enum_variant_arg(3u, - {|| - deserialize_38(s) - }), - s.read_enum_variant_arg(4u, - {|| - deserialize_81(s) + deserialize_155(s) })) } 8u { @@ -7866,7 +7920,7 @@ fn deserialize_28(s: S) -> }), s.read_enum_variant_arg(1u, {|| - deserialize_155(s) + deserialize_157(s) })) } 9u { @@ -7876,7 +7930,7 @@ fn deserialize_28(s: S) -> }), s.read_enum_variant_arg(1u, {|| - deserialize_157(s) + deserialize_159(s) }), s.read_enum_variant_arg(2u, {|| @@ -7884,7 +7938,7 @@ fn deserialize_28(s: S) -> }), s.read_enum_variant_arg(3u, {|| - deserialize_158(s) + deserialize_160(s) })) } } @@ -7927,27 +7981,27 @@ fn deserialize_syntax_ast_item(s: S) -> deserialize_0(s) } /*syntax::ast::crate_num*/ -fn serialize_163(s: S, +fn serialize_165(s: S, v: syntax::ast::crate_num) { s.emit_int(v); } /*syntax::ast::def_id*/ -fn serialize_162(s: S, +fn serialize_164(s: S, v: syntax::ast::def_id) { s.emit_rec(/*syntax::ast::crate_num*//*syntax::ast::node_id*/ {|| { s.emit_rec_field("crate", 0u, - {|| serialize_163(s, v.crate) }); + {|| serialize_165(s, v.crate) }); s.emit_rec_field("node", 1u, {|| serialize_27(s, v.node) }) } }); } /*syntax::ast::prim_ty*/ -fn serialize_164(s: S, +fn serialize_166(s: S, v: syntax::ast::prim_ty) { s.emit_enum("syntax::ast::prim_ty", @@ -8005,13 +8059,13 @@ fn serialize_164(s: S, }); } /*@syntax::ast::def*/ -fn serialize_165(s: S, +fn serialize_167(s: S, v: @syntax::ast::def) { - s.emit_box(/*syntax::ast::def*/{|| serialize_161(s, *v) }); + s.emit_box(/*syntax::ast::def*/{|| serialize_163(s, *v) }); } /*syntax::ast::def*/ -fn serialize_161(s: S, +fn serialize_163(s: S, v: syntax::ast::def) { s.emit_enum("syntax::ast::def", @@ -8042,7 +8096,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, @@ -8071,7 +8125,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8084,7 +8138,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8096,7 +8150,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8143,12 +8197,12 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, {|| - serialize_162(s, + serialize_164(s, v1) }) } @@ -8160,7 +8214,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8173,7 +8227,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_164(s, + serialize_166(s, v0) }) } @@ -8186,7 +8240,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, @@ -8216,7 +8270,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8233,7 +8287,7 @@ fn serialize_161(s: S, }); s.emit_enum_variant_arg(1u, {|| - serialize_165(s, + serialize_167(s, v1) }); s.emit_enum_variant_arg(2u, @@ -8250,7 +8304,7 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8263,12 +8317,12 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, {|| - serialize_162(s, + serialize_164(s, v1) }) } @@ -8281,12 +8335,12 @@ fn serialize_161(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, {|| - serialize_162(s, + serialize_164(s, v1) }) } @@ -8298,15 +8352,15 @@ fn serialize_161(s: S, fn serialize_syntax_ast_def(s: S, v: syntax::ast::def) { - serialize_161(s, v); + serialize_163(s, v); } /*syntax::ast::crate_num*/ -fn deserialize_163(s: S) -> +fn deserialize_165(s: S) -> syntax::ast::crate_num { s.read_int() } /*syntax::ast::def_id*/ -fn deserialize_162(s: S) -> +fn deserialize_164(s: S) -> syntax::ast::def_id { s.read_rec( @@ -8319,7 +8373,7 @@ fn deserialize_162(s: S) -> {|| {crate: s.read_rec_field("crate", 0u, - {|| deserialize_163(s) }), + {|| deserialize_165(s) }), node: s.read_rec_field("node", 1u, {|| deserialize_27(s) }),} @@ -8327,7 +8381,7 @@ fn deserialize_162(s: S) -> } /*syntax::ast::prim_ty*/ -fn deserialize_164(s: S) -> +fn deserialize_166(s: S) -> syntax::ast::prim_ty { s.read_enum("syntax::ast::prim_ty", /*syntax::ast::int_ty*/ @@ -8367,14 +8421,14 @@ fn deserialize_164(s: S) -> }) } /*@syntax::ast::def*/ -fn deserialize_165(s: S) -> +fn deserialize_167(s: S) -> @syntax::ast::def { - s.read_box(/*syntax::ast::def*/{|| @deserialize_161(s) }) + s.read_box(/*syntax::ast::def*/{|| @deserialize_163(s) }) } /*syntax::ast::def*/ -fn deserialize_161(s: S) -> +fn deserialize_163(s: S) -> syntax::ast::def { s.read_enum("syntax::ast::def", /*syntax::ast::def_id*//*syntax::ast::purity*/ @@ -8418,7 +8472,7 @@ fn deserialize_161(s: S) -> 0u { syntax::ast::def_fn(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| @@ -8434,19 +8488,19 @@ fn deserialize_161(s: S) -> 2u { syntax::ast::def_mod(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 3u { syntax::ast::def_native_mod(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 4u { syntax::ast::def_const(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 5u { @@ -8472,29 +8526,29 @@ fn deserialize_161(s: S) -> 7u { syntax::ast::def_variant(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| - deserialize_162(s) + deserialize_164(s) })) } 8u { syntax::ast::def_ty(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 9u { syntax::ast::def_prim_ty(s.read_enum_variant_arg(0u, {|| - deserialize_164(s) + deserialize_166(s) })) } 10u { syntax::ast::def_ty_param(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| @@ -8510,7 +8564,7 @@ fn deserialize_161(s: S) -> 12u { syntax::ast::def_use(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 13u { @@ -8520,7 +8574,7 @@ fn deserialize_161(s: S) -> }), s.read_enum_variant_arg(1u, {|| - deserialize_165(s) + deserialize_167(s) }), s.read_enum_variant_arg(2u, {|| @@ -8530,27 +8584,27 @@ fn deserialize_161(s: S) -> 14u { syntax::ast::def_class(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 15u { syntax::ast::def_class_field(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| - deserialize_162(s) + deserialize_164(s) })) } 16u { syntax::ast::def_class_method(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| - deserialize_162(s) + deserialize_164(s) })) } } @@ -8559,10 +8613,10 @@ fn deserialize_161(s: S) -> } fn deserialize_syntax_ast_def(s: S) -> syntax::ast::def { - deserialize_161(s) + deserialize_163(s) } /*middle::typeck::method_origin*/ -fn serialize_166(s: S, +fn serialize_168(s: S, v: middle::typeck::method_origin) { s.emit_enum("middle::typeck::method_origin", @@ -8578,7 +8632,7 @@ fn serialize_166(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }) } @@ -8591,7 +8645,7 @@ fn serialize_166(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, @@ -8619,7 +8673,7 @@ fn serialize_166(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, @@ -8637,10 +8691,10 @@ fn serialize_middle_typeck_method_origin(s: S, v: middle::typeck::method_origin) { - serialize_166(s, v); + serialize_168(s, v); } /*middle::typeck::method_origin*/ -fn deserialize_166(s: S) -> +fn deserialize_168(s: S) -> middle::typeck::method_origin { s.read_enum("middle::typeck::method_origin", /*syntax::ast::def_id*/ @@ -8654,13 +8708,13 @@ fn deserialize_166(s: S) -> 0u { middle::typeck::method_static(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) })) } 1u { middle::typeck::method_param(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| @@ -8678,7 +8732,7 @@ fn deserialize_166(s: S) -> 2u { middle::typeck::method_iface(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| @@ -8692,17 +8746,17 @@ fn deserialize_166(s: S) -> fn deserialize_middle_typeck_method_origin(s: S) -> middle::typeck::method_origin { - deserialize_166(s) + deserialize_168(s) } /*middle::freevars::freevar_entry*/ -fn serialize_167(s: S, +fn serialize_169(s: S, v: middle::freevars::freevar_entry) { s.emit_rec(/*syntax::ast::def*//*syntax::codemap::span*/ {|| { s.emit_rec_field("def", 0u, - {|| serialize_161(s, v.def) }); + {|| serialize_163(s, v.def) }); s.emit_rec_field("span", 1u, {|| serialize_19(s, v.span) }) } @@ -8712,10 +8766,10 @@ fn serialize_middle_freevars_freevar_entry(s: S, v: middle::freevars::freevar_entry) { - serialize_167(s, v); + serialize_169(s, v); } /*middle::freevars::freevar_entry*/ -fn deserialize_167(s: S) -> +fn deserialize_169(s: S) -> middle::freevars::freevar_entry { s.read_rec( @@ -8727,7 +8781,7 @@ fn deserialize_167(s: S) -> {|| {def: - s.read_rec_field("def", 0u, {|| deserialize_161(s) }), + s.read_rec_field("def", 0u, {|| deserialize_163(s) }), span: s.read_rec_field("span", 1u, {|| deserialize_19(s) }),} @@ -8737,19 +8791,19 @@ fn deserialize_167(s: S) -> fn deserialize_middle_freevars_freevar_entry(s: S) -> middle::freevars::freevar_entry { - deserialize_167(s) + deserialize_169(s) } fn serialize_syntax_ast_def_id(s: S, v: syntax::ast::def_id) { - serialize_162(s, v); + serialize_164(s, v); } fn deserialize_syntax_ast_def_id(s: S) -> syntax::ast::def_id { - deserialize_162(s) + deserialize_164(s) } /*syntax::ast::inlined_item*/ -fn serialize_168(s: S, +fn serialize_170(s: S, v: syntax::ast::inlined_item) { s.emit_enum("syntax::ast::inlined_item", @@ -8775,12 +8829,12 @@ fn serialize_168(s: S, { s.emit_enum_variant_arg(0u, {|| - serialize_162(s, + serialize_164(s, v0) }); s.emit_enum_variant_arg(1u, {|| - serialize_159(s, + serialize_161(s, v1) }) } @@ -8792,10 +8846,10 @@ fn serialize_168(s: S, fn serialize_syntax_ast_inlined_item(s: S, v: syntax::ast::inlined_item) { - serialize_168(s, v); + serialize_170(s, v); } /*syntax::ast::inlined_item*/ -fn deserialize_168(s: S) -> +fn deserialize_170(s: S) -> syntax::ast::inlined_item { s.read_enum("syntax::ast::inlined_item", /*@syntax::ast::item*/ @@ -8813,11 +8867,11 @@ fn deserialize_168(s: S) -> 1u { syntax::ast::ii_method(s.read_enum_variant_arg(0u, {|| - deserialize_162(s) + deserialize_164(s) }), s.read_enum_variant_arg(1u, {|| - deserialize_159(s) + deserialize_161(s) })) } } @@ -8827,5 +8881,5 @@ fn deserialize_168(s: S) -> fn deserialize_syntax_ast_inlined_item(s: S) -> syntax::ast::inlined_item { - deserialize_168(s) + deserialize_170(s) } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 2da07511628f..a8173d51f061 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -127,7 +127,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str], encode_def_id(ebml_w, local_def(it.id)); ebml_w.end_tag(); } - item_class(_,_,_,_,_) { + item_class(_,_,_) { fail "encode: implement item_class"; } item_enum(variants, tps) { @@ -384,7 +384,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_enum_variant_info(ecx, ebml_w, item.id, variants, path, index, tps); } - item_class(_,_,_,_,_) { + item_class(_,_,_) { fail "encode: implement item_class"; } item_res(_, tps, _, _, ctor_id) { diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 117641c9fe87..aa8f7ac53672 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -541,12 +541,12 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt) { v.visit_ty(m.decl.output, msc, v); } } - ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) { + ast::item_class(tps, members, ctor) { visit::visit_ty_params(tps, sc, v); let class_scope = cons(scope_item(i), @sc); /* visit the constructor... */ - visit_fn_with_scope(e, visit::fk_item_fn(i.ident, tps), ctor_decl, - ctor_block, ctor_block.span, ctor_id, + visit_fn_with_scope(e, visit::fk_item_fn(i.ident, tps), ctor.node.dec, + ctor.node.body, ctor.span, ctor.node.id, class_scope, v); /* visit the items */ for cm in members { @@ -1029,12 +1029,12 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) ast::item_native_mod(m) { ret lookup_in_local_native_mod(e, it.id, sp, name, ns); } - ast::item_class(tps, members, ctor_id, _, _) { + ast::item_class(tps, members, ctor) { if ns == ns_type { ret lookup_in_ty_params(e, name, tps); } if ns == ns_val(value_or_enum) && name == it.ident { - ret some(ast::def_fn(local_def(ctor_id), + ret some(ast::def_fn(local_def(ctor.node.id), ast::impure_fn)); } if ns == ns_val(value_or_enum) { @@ -1359,7 +1359,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option { _ { } } } - ast::item_class(_, _, _, _, _) { + ast::item_class(_, _, _) { if ns == ns_type { ret some(ast::def_class(local_def(i.id))); } @@ -1664,16 +1664,16 @@ fn index_mod(md: ast::_mod) -> mod_index { variant_idx += 1u; } } - ast::item_class(tps, items, ctor_id, ctor_decl, ctor_body) { + ast::item_class(tps, items, ctor) { // add the class name itself add_to_index(index, it.ident, mie_item(it)); // add the constructor decl add_to_index(index, it.ident, mie_item(@{ident: it.ident, attrs: [], - id: ctor_id, - node: - item_fn(ctor_decl, tps, ctor_body), - span: ctor_body.span})); + id: ctor.node.id, + node: + item_fn(ctor.node.dec, tps, ctor.node.body), + span: ctor.node.body.span})); // add the members for ci in items { add_to_index(index, class_item_ident(ci), diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 6947a6875c49..12beb363d04a 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -49,6 +49,8 @@ import type_of::*; import type_of::type_of; // Issue #1873 import ast_map::{path, path_mod, path_name}; +import std::smallintmap; + // Destinations // These are passed around by the code generating functions to track the @@ -1208,6 +1210,15 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, } ret next_cx; } + ty::ty_class(did, tps) { + // a class is like a record type + let i: int = 0; + for fld: ty::field in ty::class_items_as_fields(cx.tcx(), did) { + let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]); + cx = f(bcx, llfld_a, fld.mt.ty); + i += 1; + } + } _ { cx.sess().unimpl("type in iter_structural_ty"); } } ret cx; @@ -2096,7 +2107,7 @@ fn monomorphic_fn(ccx: crate_ctxt, fn_id: ast::def_id, substs: [ty::t], alt check map_node { ast_map::node_item(@{node: ast::item_fn(decl, _, body), _}, _) { trans_fn(ccx, pt, decl, body, lldecl, no_self, [], - psubsts, fn_id.node); + psubsts, fn_id.node, none); } ast_map::node_item(@{node: ast::item_res(decl, _, _, _, _), _}, _) { trans_res_ctor(ccx, pt, decl, fn_id.node, [], psubsts, lldecl); @@ -2112,7 +2123,7 @@ fn monomorphic_fn(ccx: crate_ctxt, fn_id: ast::def_id, substs: [ty::t], let selfty = ty::lookup_item_type(ccx.tcx, impl_def_id).ty; let selfty = ty::substitute_type_params(ccx.tcx, substs, selfty); trans_fn(ccx, pt, mth.decl, mth.body, lldecl, - impl_self(selfty), [], psubsts, fn_id.node); + impl_self(selfty), [], psubsts, fn_id.node, none); } } some({llfn: lldecl, fty: mono_ty}) @@ -2267,17 +2278,26 @@ fn trans_local_var(cx: block, def: ast::def) -> local_var_result { ret {val: ptr, kind: owned}; } _ { - cx.sess().unimpl("unsupported def type in trans_local_def"); + cx.sess().unimpl(#fmt("unsupported def type in trans_local_def: %?", + def)); } } } -fn trans_path(cx: block, id: ast::node_id) +// The third argument (path) ends up getting used when the id +// refers to a field within the enclosing class, since the name +// gets turned into a record field name. +fn trans_path(cx: block, id: ast::node_id, path: @ast::path) -> lval_maybe_callee { - ret trans_var(cx, cx.tcx().def_map.get(id), id); + alt cx.tcx().def_map.find(id) { + none { cx.sess().bug("trans_path: unbound node ID"); } + some(df) { + ret trans_var(cx, df, id, path); + } + } } -fn trans_var(cx: block, def: ast::def, id: ast::node_id) +fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path) -> lval_maybe_callee { let ccx = cx.ccx(); alt def { @@ -2313,6 +2333,18 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id) ret lval_no_env(cx, load_if_immediate(cx, val, tp), owned_imm); } } + ast::def_class_field(parent, did) { + // base is implicitly "Self" + alt cx.fcx.self_id { + some(slf) { + let {bcx, val, kind} = trans_rec_field(cx, slf, + // TODO: only supporting local objects for now + path_to_ident(path)); + ret lval_no_env(bcx, val, kind); + } + _ { cx.sess().bug("unbound self param in class"); } + } + } _ { let loc = trans_local_var(cx, def); ret lval_no_env(cx, loc.val, loc.kind); @@ -2326,6 +2358,7 @@ fn trans_rec_field(bcx: block, base: @ast::expr, let {bcx, val, ty} = autoderef(bcx, val, expr_ty(bcx, base)); let fields = alt ty::get(ty).struct { ty::ty_rec(fs) { fs } + ty::ty_class(did,_) { ty::class_items_as_fields(bcx.tcx(), did) } // Constraint? _ { bcx.tcx().sess.span_bug(base.span, "trans_rec_field:\ base expr has non-record type"); } @@ -2386,7 +2419,7 @@ fn expr_is_lval(bcx: block, e: @ast::expr) -> bool { fn trans_callee(bcx: block, e: @ast::expr) -> lval_maybe_callee { alt e.node { - ast::expr_path(_) { ret trans_path(bcx, e.id); } + ast::expr_path(path) { ret trans_path(bcx, e.id, path); } ast::expr_field(base, ident, _) { // Lval means this is a record field, so not a method if !expr_is_lval(bcx, e) { @@ -2412,8 +2445,8 @@ fn trans_callee(bcx: block, e: @ast::expr) -> lval_maybe_callee { // immediate). fn trans_lval(cx: block, e: @ast::expr) -> lval_result { alt e.node { - ast::expr_path(_) { - let v = trans_path(cx, e.id); + ast::expr_path(p) { + let v = trans_path(cx, e.id, p); ret lval_maybe_callee_to_lval(v, expr_ty(cx, e)); } ast::expr_field(base, ident, _) { @@ -3839,6 +3872,7 @@ fn mk_standard_basic_blocks(llfn: ValueRef) -> // - trans_args fn new_fn_ctxt_w_id(ccx: crate_ctxt, path: path, llfndecl: ValueRef, id: ast::node_id, + maybe_self_id: option<@ast::expr>, param_substs: option, sp: option) -> fn_ctxt { let llbbs = mk_standard_basic_blocks(llfndecl); @@ -3860,6 +3894,7 @@ fn new_fn_ctxt_w_id(ccx: crate_ctxt, path: path, mutable lltyparams: [], derived_tydescs: ty::new_ty_hash(), id: id, + self_id: maybe_self_id, param_substs: param_substs, span: sp, path: path, @@ -3868,7 +3903,7 @@ fn new_fn_ctxt_w_id(ccx: crate_ctxt, path: path, fn new_fn_ctxt(ccx: crate_ctxt, path: path, llfndecl: ValueRef, sp: option) -> fn_ctxt { - ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, none, sp); + ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, none, none, sp); } // NB: must keep 4 fns in sync: @@ -3991,12 +4026,13 @@ fn trans_closure(ccx: crate_ctxt, path: path, decl: ast::fn_decl, ty_self: self_arg, tps_bounds: [ty::param_bounds], param_substs: option, - id: ast::node_id, maybe_load_env: fn(fn_ctxt)) { + id: ast::node_id, maybe_self_id: option<@ast::expr>, + maybe_load_env: fn(fn_ctxt)) { set_uwtable(llfndecl); // Set up arguments to the function. - let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, param_substs, - some(body.span)); + let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, maybe_self_id, + param_substs, some(body.span)); create_llargs_for_fn_args(fcx, ty_self, decl.inputs, tps_bounds); // Create the first basic block in the function and keep a handle on it to @@ -4014,9 +4050,14 @@ fn trans_closure(ccx: crate_ctxt, path: path, decl: ast::fn_decl, // translation calls that don't have a return value (trans_crate, // trans_mod, trans_item, et cetera) and those that do // (trans_block, trans_expr, et cetera). - if option::is_none(body.node.expr) || + + if option::is_none(maybe_self_id) // hack -- + /* avoids the need for special cases to assign a type to + the constructor body (since it has no explicit return) */ + && + (option::is_none(body.node.expr) || ty::type_is_bot(block_ty) || - ty::type_is_nil(block_ty) { + ty::type_is_nil(block_ty)) { bcx = trans_block(bcx, body, ignore); } else { bcx = trans_block(bcx, body, save_in(fcx.llretptr)); @@ -4037,12 +4078,13 @@ fn trans_fn(ccx: crate_ctxt, ty_self: self_arg, tps_bounds: [ty::param_bounds], param_substs: option, - id: ast::node_id) { + id: ast::node_id, + maybe_self_id: option<@ast::expr>) { let do_time = ccx.sess.opts.stats; let start = if do_time { time::get_time() } else { {sec: 0u32, usec: 0u32} }; trans_closure(ccx, path, decl, body, llfndecl, ty_self, - tps_bounds, param_substs, id, {|fcx| + tps_bounds, param_substs, id, maybe_self_id, {|fcx| if ccx.sess.opts.extra_debuginfo { debuginfo::create_function(fcx); } @@ -4058,7 +4100,7 @@ fn trans_res_ctor(ccx: crate_ctxt, path: path, dtor: ast::fn_decl, param_substs: option, llfndecl: ValueRef) { // Create a function for the constructor let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, ctor_id, - param_substs, none); + none, param_substs, none); create_llargs_for_fn_args(fcx, no_self, dtor.inputs, tps_bounds); let bcx = top_scope_block(fcx, none), lltop = bcx.llbb; let fty = node_id_type(bcx, ctor_id); @@ -4100,7 +4142,7 @@ fn trans_enum_variant(ccx: crate_ctxt, enum_id: ast::node_id, ident: "arg" + uint::to_str(i, 10u), id: varg.id}]; } - let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, + let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, none, param_substs, none); create_llargs_for_fn_args(fcx, no_self, fn_args, param_bounds(ccx, ty_params)); @@ -4261,7 +4303,7 @@ fn trans_item(ccx: crate_ctxt, item: ast::item) { if decl.purity != ast::crust_fn { trans_fn(ccx, *path + [path_name(item.ident)], decl, body, llfndecl, no_self, param_bounds(ccx, tps), - none, item.id); + none, item.id, none); } else { native::trans_crust_fn(ccx, *path + [path_name(item.ident)], decl, body, llfndecl, item.id); @@ -4280,7 +4322,7 @@ fn trans_item(ccx: crate_ctxt, item: ast::item) { some(lldtor_decl) { trans_fn(ccx, *path + [path_name(item.ident)], decl, body, lldtor_decl, no_self, param_bounds(ccx, tps), - none, dtor_id); + none, dtor_id, none); } _ { ccx.sess.span_fatal(item.span, "unbound dtor in trans_item"); @@ -4311,6 +4353,83 @@ fn trans_item(ccx: crate_ctxt, item: ast::item) { }; native::trans_native_mod(ccx, native_mod, abi); } + ast::item_class(tps, items, ctor) { + alt ccx.item_ids.find(ctor.node.id) { + some(llctor_decl) { + // Translate the ctor + // First, add a preamble that + // generates a new name, obj: + // let obj = { ... } (uninit record fields) + let sess = ccx.sess; + let rslt_path_ = {global: false, + idents: ["obj"], + types: []}; // ?? + let rslt_path = @{node: rslt_path_, + span: ctor.node.body.span}; + let rslt_id : ast::node_id = sess.next_node_id(); + let rslt_pat : @ast::pat = + @{id: sess.next_node_id(), + node: ast::pat_ident(rslt_path, none), + span: ctor.node.body.span}; + // Set up obj's type + let rslt_ast_ty : @ast::ty = @{node: ast::ty_infer, + span: ctor.node.body.span}; + // kludgy + let ty_args = [], i = 0u; + for tp in tps { + ty_args += [ty::mk_param(ccx.tcx, i, + local_def(tps[i].id))]; + } + let rslt_ty = ty::mk_class(ccx.tcx, + local_def(item.id), + ty_args); + // Set up a local for obj + let rslt_loc_ : ast::local_ = {is_mutbl: true, + ty: rslt_ast_ty, // ??? + pat: rslt_pat, + init: none::, + id: rslt_id}; + // Register a type for obj + smallintmap::insert(*ccx.tcx.node_types, + rslt_loc_.id as uint, rslt_ty); + // Create the decl statement that initializers obj + let rslt_loc : @ast::local = + @{node: rslt_loc_, span: ctor.node.body.span}; + let rslt_decl_ : ast::decl_ = ast::decl_local([rslt_loc]); + let rslt_decl : @ast::decl + = @{node: rslt_decl_, span: ctor.node.body.span}; + let prologue : @ast::stmt = @{node: ast::stmt_decl(rslt_decl, + sess.next_node_id()), + span: ctor.node.body.span}; + let rslt_node_id = sess.next_node_id(); + ccx.tcx.def_map.insert(rslt_node_id, + ast::def_local(rslt_loc_.id, true)); + // And give the statement a type + smallintmap::insert(*ccx.tcx.node_types, + rslt_node_id as uint, rslt_ty); + // The result expression of the constructor is now a + // reference to obj + let rslt_expr : @ast::expr = + @{id: rslt_node_id, + node: ast::expr_path(rslt_path), + span: ctor.node.body.span}; + let ctor_body_new : ast::blk_ = {stmts: [prologue] + + ctor.node.body.node.stmts, + expr: some(rslt_expr) + with ctor.node.body.node}; + let ctor_body__ : ast::blk = {node: ctor_body_new + with ctor.node.body}; + trans_fn(ccx, *path + [path_name(item.ident)], ctor.node.dec, + ctor_body__, llctor_decl, no_self, + param_bounds(ccx, tps), none, ctor.node.id, + some(rslt_expr)); + // TODO: translate methods! + } + _ { + ccx.sess.span_bug(item.span, "unbound ctor in trans_item"); + } + } + } _ {/* fall through */ } } } @@ -4348,7 +4467,7 @@ fn trans_inlined_items(ccx: crate_ctxt, inline_map: inline_map) { let llfndecl = ccx.item_ids.get(m.id); trans_fn(ccx, m_path, m.decl, m.body, llfndecl, impl_self(impl_ty), m_bounds, - none, m.id); + none, m.id, none); } } } @@ -4605,6 +4724,12 @@ fn collect_item(ccx: crate_ctxt, abi: @mutable option, } } } + ast::item_class(tps,_,ctor) { + // Register the ctor + let t = ty::node_id_to_type(ccx.tcx, ctor.node.id); + register_fn_full(ccx, i.span, my_path, "ctor", + param_bounds(ccx, tps), ctor.node.id, t); + } _ { } } } diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index 4cd9eef01e36..6f85204ffe07 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -470,7 +470,7 @@ fn trans_expr_fn(bcx: block, ccx.tcx, id, proto, cap_clause); let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck, id); trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], - bcx.fcx.param_substs, id, {|fcx| + bcx.fcx.param_substs, id, none, {|fcx| load_environment(bcx, fcx, cdata_ty, cap_vars, ck); }); llbox @@ -482,7 +482,7 @@ fn trans_expr_fn(bcx: block, ast::proto_uniq { trans_closure_env(ty::ck_uniq) } ast::proto_bare { trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], none, - id, {|_fcx|}); + id, none, {|_fcx|}); C_null(T_opaque_box_ptr(ccx)) } }; diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index 4bc264e40983..7b42ca616990 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -196,6 +196,10 @@ type fn_ctxt = @{ // a user-defined function. id: ast::node_id, + // The expr for the "self" object (only if this function corresponds + // to a class constructor function) + self_id: option<@ast::expr>, + // If this function is being monomorphized, this contains the type // substitutions used. param_substs: option, diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index b3660e3f6728..e713a9979e4b 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -52,7 +52,7 @@ fn trans_impl(ccx: crate_ctxt, path: path, name: ast::ident, let m_bounds = param_bounds(ccx, tps + m.tps); trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body, llfn, impl_self(ty::node_id_to_type(ccx.tcx, id)), - m_bounds, none, m.id); + m_bounds, none, m.id, none); } _ { ccx.sess.bug("Unbound id in trans_impl"); diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 22791047ef91..9753ef6bd330 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -274,7 +274,8 @@ fn trans_crust_fn(ccx: crate_ctxt, path: ast_map::path, decl: ast::fn_decl, ccx, path + [ast_map::path_name("__rust_abi")]); let llty = type_of_fn_from_ty(ccx, t, []); let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty); - trans_fn(ccx, path, decl, body, llfndecl, no_self, [], none, id); + trans_fn(ccx, path, decl, body, llfndecl, no_self, [], none, id, + none); ret llfndecl; } diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index f7095be55ffe..e613fdf3cd9f 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -2,6 +2,9 @@ import common::*; import lib::llvm::{TypeRef}; import syntax::ast; import lib::llvm::llvm; +import driver::session::session; + +import ty::*; fn type_of_explicit_args(cx: crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { vec::map(inputs) {|arg| @@ -102,8 +105,25 @@ fn type_of(cx: crate_ctxt, t: ty::t) -> TypeRef { } ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) } ty::ty_constr(subt,_) { type_of(cx, subt) } - - _ { fail "type_of not implemented for this kind of type"; } + ty::ty_class(did, _) { + let tys: [TypeRef] = []; + // TODO: only handles local classes + let cls_items = lookup_class_items(cx.tcx, did); + for ci in cls_items { + // only instance vars are record fields at runtime + alt ci.node.decl { + ast::instance_var(_,_,_,_) { + let fty = type_of(cx, class_item_type(cx.tcx, ci)); + tys += [fty]; + } + _ {} + } + } + T_struct(tys) + } + ty::ty_self(_) { cx.tcx.sess.unimpl("type_of: ty_self \ + not implemented"); } + ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); } }; cx.lltypes.insert(t, llty); ret llty; diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs index 8a83f7dd7b4e..6c80234a54bc 100644 --- a/src/rustc/middle/tstate/pre_post_conditions.rs +++ b/src/rustc/middle/tstate/pre_post_conditions.rs @@ -56,7 +56,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) { ccx: ccx}; find_pre_post_fn(fcx, body); } - item_class(_,_,_,_,_) { + item_class(_,_,_) { fail "find_pre_post_item: implement item_class"; } item_impl(_, _, _, ms) { for m in ms { find_pre_post_method(ccx, m); } } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index a7e218e581bd..6895630f879a 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -18,6 +18,8 @@ export arg; export args_eq; export ast_constr_to_constr; export block_ty; +export class_item_type; +export class_items_as_fields; export constr; export constr_general; export constr_table; @@ -37,6 +39,7 @@ export fm_general; export get_element_type; export is_binopable; export is_pred_ty; +export lookup_class_items; export lookup_item_type; export method; export method_idx; @@ -628,7 +631,7 @@ fn type_is_bool(ty: t) -> bool { get(ty).struct == ty_bool } fn type_is_structural(ty: t) -> bool { alt get(ty).struct { - ty_rec(_) | ty_tup(_) | ty_enum(_, _) | ty_fn(_) | + ty_rec(_) | ty_class(_,_) | ty_tup(_) | ty_enum(_, _) | ty_fn(_) | ty_iface(_, _) | ty_res(_, _, _) { true } _ { false } } @@ -1228,7 +1231,10 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool { } fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t { - smallintmap::get(*cx.node_types, id as uint) + alt smallintmap::find(*cx.node_types, id as uint) { + some(t) { t } + none { cx.sess.bug(#fmt("node_id_to_type: unbound node ID %?", id)); } + } } fn node_id_to_type_params(cx: ctxt, id: ast::node_id) -> [t] { @@ -2292,6 +2298,54 @@ fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty { } } +// Look up the list of items for a given class (in the item map). +// Fails if the id is not bound to a class. +fn lookup_class_items(cx: ctxt, did: ast::def_id) -> [@class_item] { + alt cx.items.find(did.node) { + some(ast_map::node_item(i,_)) { + alt i.node { + ast::item_class(_, items, _) { + items + } + _ { cx.sess.bug("class ID bound to non-class"); } + } + } + _ { cx.sess.bug("class ID not bound to an item"); } + } +} + +// Return a list of fields corresponding to the class's items +// (as if the class was a record). trans uses this +fn class_items_as_fields(cx:ctxt, did: ast::def_id) -> [field] { + let rslt = []; + for ci in lookup_class_items(cx, did) { + rslt += [alt ci.node.decl { + instance_var(i, _, _, id) { + // consider all instance vars mutable, because the + // constructor may mutate all vars + {ident: i, mt: {ty: node_id_to_type(cx, id), + mutbl: m_mutbl}} + } + class_method(it) { + {ident:it.ident, mt: {ty: node_id_to_type(cx, it.id), + mutbl: m_const}} + } + }]; + } + rslt +} + +// Looks up the type for a given class item. Must be called +// post-typechecking. +fn class_item_type(cx: ctxt, ci: @ast::class_item) -> t { + alt ci.node.decl { + ast::instance_var(_,_,_,id) { node_id_to_type(cx, id) } + // TODO: only works for local classes + ast::class_method(it) { lookup_item_type(cx, + ast_util::local_def(it.id)).ty } + } +} + fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool { const tycat_other: int = 0; const tycat_bool: int = 1; diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index e1c56b9fc549..57d8fc295604 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -10,7 +10,7 @@ import pat_util::*; import middle::ty; import middle::ty::{node_id_to_type, arg, block_ty, expr_ty, field, node_type_table, mk_nil, - ty_param_bounds_and_ty}; + ty_param_bounds_and_ty, lookup_class_items}; import util::ppaux::ty_to_str; import middle::ty::unify::{ures_ok, ures_err, fix_ok, fix_err}; import std::smallintmap; @@ -375,7 +375,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { ast::def_class(class_id) { alt tcx.items.find(class_id.node) { some(ast_map::node_item( - @{node: ast::item_class(tps, _, _, _, _), _}, _)) { + @{node: ast::item_class(tps, _, _), _}, _)) { if vec::len(tps) != vec::len(path.node.types) { tcx.sess.span_err(ast_ty.span, "incorrect number of \ type parameters to object type"); @@ -492,7 +492,7 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item) tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } - ast::item_class(tps,_,_,_,_) { + ast::item_class(tps,_,_) { let {bounds,params} = mk_ty_params(tcx, tps); let t = ty::mk_class(tcx, local_def(it.id), params); let tpt = {bounds: bounds, ty: t}; @@ -944,7 +944,7 @@ mod collect { write_ty(tcx, it.id, tpt.ty); ensure_iface_methods(tcx, it.id); } - ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) { + ast::item_class(tps, members, ctor) { // Write the class type let {bounds,params} = mk_ty_params(tcx, tps); let class_ty = ty::mk_class(tcx, local_def(it.id), params); @@ -954,9 +954,9 @@ mod collect { // Write the ctor type let t_ctor = ty::mk_fn(tcx, ty_of_fn_decl(tcx, m_collect, - ast::proto_any, ctor_decl)); - write_ty(tcx, ctor_id, t_ctor); - tcx.tcache.insert(local_def(ctor_id), + ast::proto_any, ctor.node.dec)); + write_ty(tcx, ctor.node.id, t_ctor); + tcx.tcache.insert(local_def(ctor.node.id), {bounds: bounds, ty: t_ctor}); /* FIXME: check for proper public/privateness */ // Write the type of each of the members @@ -2549,19 +2549,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, // For now, this code assumes the class is defined in the local // crate // FIXME: handle field references to classes in external crate - let err = "Class ID is not bound to a class"; - let field_ty = alt fcx.ccx.tcx.items.find(base_id.node) { - some(ast_map::node_item(i,_)) { - alt i.node { - ast::item_class(_, items, _, _, _) { - lookup_field_ty(fcx.ccx.tcx, items, field, - expr.span) - } - _ { fcx.ccx.tcx.sess.span_bug(expr.span, err); } - } - } - _ { fcx.ccx.tcx.sess.span_bug(expr.span, err); } - }; + let cls_items = lookup_class_items(tcx, base_id); + let field_ty = lookup_field_ty(fcx.ccx.tcx, cls_items, field, + expr.span); // (2) look up what field's type is, and return it // FIXME: actually instantiate any type params write_ty(tcx, id, field_ty); @@ -3034,14 +3024,14 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) { for m in ms { check_method(ccx, m); } vec::pop(ccx.self_infos); } - ast::item_class(tps, members, ctor_id, ctor_decl, ctor_body) { + ast::item_class(tps, members, ctor) { let cid = some(it.id); let members_info = class_types(ccx, members); let class_ccx = @{enclosing_class_id:cid, enclosing_class:members_info with *ccx}; // typecheck the ctor - check_fn(class_ccx, ast::proto_bare, ctor_decl, ctor_body, ctor_id, - none); + check_fn(class_ccx, ast::proto_bare, ctor.node.dec, + ctor.node.body, ctor.node.id, none); // typecheck the members for m in members { check_class_member(class_ccx, m.node.decl); } } diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs index eea47191eef7..2f0c4bf78393 100644 --- a/src/rustc/syntax/ast.rs +++ b/src/rustc/syntax/ast.rs @@ -9,9 +9,6 @@ type ident = str; // Functions may or may not have names. type fn_ident = option; -// FIXME: with typestate constraint, could say -// idents and types are the same length, and are -// non-empty type path_ = {global: bool, idents: [ident], types: [@ty]}; type path = spanned; @@ -499,9 +496,7 @@ enum item_ { item_class([ty_param], /* ty params for class */ [@class_item], /* methods, etc. */ /* (not including ctor) */ - node_id, /* ctor id */ - fn_decl, /* ctor decl */ - blk /* ctor body */ + class_ctor ), item_iface([ty_param], [ty_method]), item_impl([ty_param], option<@ty> /* iface */, @@ -523,6 +518,11 @@ enum class_mutability { class_mutable, class_immutable } enum privacy { priv, pub } +type class_ctor = spanned; +type class_ctor_ = {id: node_id, + dec: fn_decl, + body: blk}; + type native_item = {ident: ident, attrs: [attribute], diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs index 7ceae5487694..d8088e39cb6d 100644 --- a/src/rustc/syntax/fold.rs +++ b/src/rustc/syntax/fold.rs @@ -269,12 +269,14 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { item_enum(vec::map(variants, fld.fold_variant), fold_ty_params(typms, fld)) } - item_class(typms, items, id, ctor_decl, ctor_body) { - item_class(fold_ty_params(typms, fld), + item_class(typms, items, ctor) { + let ctor_body = fld.fold_block(ctor.node.body); + let ctor_decl = fold_fn_decl(ctor.node.dec, fld); + item_class(typms, vec::map(items, fld.fold_class_item), - id, - fold_fn_decl(ctor_decl, fld), - fld.fold_block(ctor_body)) + {node: {body: ctor_body, + dec: ctor_decl with ctor.node} + with ctor}) } item_impl(tps, ifce, ty, methods) { item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty), diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs index 5837baf1ff90..e8df2f863055 100644 --- a/src/rustc/syntax/parse/parser.rs +++ b/src/rustc/syntax/parse/parser.rs @@ -1590,8 +1590,9 @@ fn parse_let(p: parser) -> @ast::decl { ret @spanned(lo, p.last_span.hi, ast::decl_local(locals)); } -fn parse_instance_var(p:parser) -> ast::class_member { +fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) { let is_mutbl = ast::class_immutable; + let lo = p.span.lo; expect_word(p, "let"); if eat_word(p, "mut") || eat_word(p, "mutable") { is_mutbl = ast::class_mutable; @@ -1602,7 +1603,8 @@ fn parse_instance_var(p:parser) -> ast::class_member { let name = parse_ident(p); expect(p, token::COLON); let ty = parse_ty(p, false); - ret ast::instance_var(name, ty, is_mutbl, p.get_id()); + ret (ast::instance_var(name, ty, is_mutbl, p.get_id()), + ast_util::mk_sp(lo, p.last_span.hi)); } fn parse_stmt(p: parser, first_item_attrs: [ast::attribute]) -> @ast::stmt { @@ -1976,27 +1978,33 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { expect(p, token::LBRACE); let items: [@ast::class_item] = []; let ctor_id = p.get_id(); - let the_ctor : option<(ast::fn_decl, ast::blk)> = none; + let the_ctor : option<(ast::fn_decl, ast::blk, codemap::span)> = none; while p.token != token::RBRACE { alt parse_class_item(p, class_path) { - ctor_decl(a_fn_decl, blk) { - the_ctor = some((a_fn_decl, blk)); + ctor_decl(a_fn_decl, blk, s) { + the_ctor = some((a_fn_decl, blk, s)); } - plain_decl(a_decl) { + plain_decl(a_decl, s) { items += [@{node: {privacy: ast::pub, decl: a_decl}, - span: p.last_span}]; + span: s}]; } priv_decls(some_decls) { - items += vec::map(some_decls, {|d| + items += vec::map(some_decls, {|p| + let (d, s) = p; @{node: {privacy: ast::priv, decl: d}, - span: p.last_span}}); + span: s}}); } } } p.bump(); alt the_ctor { - some((ct_d, ct_b)) { ret mk_item(p, lo, p.last_span.hi, class_name, - ast::item_class(ty_params, items, ctor_id, ct_d, ct_b), attrs); } + some((ct_d, ct_b, ct_s)) { ret mk_item(p, lo, p.last_span.hi, + class_name, + ast::item_class(ty_params, items, + {node: {id: ctor_id, + dec: ct_d, + body: ct_b}, + span: ct_s}), attrs); } /* Is it strange for the parser to check this? */ @@ -2007,16 +2015,17 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { // lets us identify the constructor declaration at // parse time // we don't really want just the fn_decl... -enum class_contents { ctor_decl(ast::fn_decl, ast::blk), +enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span), // assumed to be public - plain_decl(ast::class_member), + plain_decl(ast::class_member, codemap::span), // contents of a priv section -- // parse_class_item ensures that // none of these are a ctor decl - priv_decls([ast::class_member])} + priv_decls([(ast::class_member, codemap::span)])} fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents { if eat_word(p, "new") { + let lo = p.last_span.lo; // Can ctors have attrs? // result type is always the type of the class let decl_ = parse_fn_decl(p, ast::impure_fn); @@ -2024,7 +2033,7 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), span: decl_.output.span} with decl_}; let body = parse_block(p); - ret ctor_decl(decl, body); + ret ctor_decl(decl, body, ast_util::mk_sp(lo, p.last_span.hi)); } // FIXME: refactor else if eat_word(p, "priv") { @@ -2033,7 +2042,7 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), while p.token != token::RBRACE { alt parse_item(p, []) { some(i) { - results += [ast::class_method(i)]; + results += [(ast::class_method(i), i.span)]; } _ { let a_var = parse_instance_var(p); @@ -2049,12 +2058,12 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), // Probably need to parse attrs alt parse_item(p, []) { some(i) { - ret plain_decl(ast::class_method(i)); + ret plain_decl(ast::class_method(i), i.span); } _ { - let a_var = parse_instance_var(p); + let (a_var, a_span) = parse_instance_var(p); expect(p, token::SEMI); - ret plain_decl(a_var); + ret plain_decl(a_var, a_span); } } } diff --git a/src/rustc/syntax/print/pprust.rs b/src/rustc/syntax/print/pprust.rs index 5f92b5d5bebc..d74d5d92c5fd 100644 --- a/src/rustc/syntax/print/pprust.rs +++ b/src/rustc/syntax/print/pprust.rs @@ -471,22 +471,24 @@ fn print_item(s: ps, &&item: @ast::item) { bclose(s, item.span); } } - ast::item_class(tps,items,_,ctor_decl,ctor_body) { + ast::item_class(tps,items,ctor) { head(s, "class"); word_nbsp(s, item.ident); print_type_params(s, tps); bopen(s); hardbreak_if_not_bol(s); + maybe_print_comment(s, ctor.span.lo); head(s, "new"); - print_fn_args_and_ret(s, ctor_decl); + print_fn_args_and_ret(s, ctor.node.dec); space(s.s); - print_block(s, ctor_body); + print_block(s, ctor.node.body); for ci in items { /* FIXME: collect all private items and print them in a single "priv" section */ hardbreak_if_not_bol(s); + maybe_print_comment(s, ci.span.lo); alt ci.node.privacy { ast::priv { head(s, "priv"); @@ -516,6 +518,7 @@ fn print_item(s: ps, &&item: @ast::item) { _ {} } } + bclose(s, item.span); } ast::item_impl(tps, ifce, ty, methods) { head(s, "impl"); diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs index 55958abd7af6..dd1a53942fa3 100644 --- a/src/rustc/syntax/visit.rs +++ b/src/rustc/syntax/visit.rs @@ -133,13 +133,13 @@ fn visit_item(i: @item, e: E, v: vt) { visit_method_helper(m, e, v) } } - item_class(tps, members, _, ctor_decl, ctor_blk) { + item_class(tps, members, ctor) { v.visit_ty_params(tps, e, v); for m in members { v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v); } - visit_fn_decl(ctor_decl, e, v); - v.visit_block(ctor_blk, e, v); + visit_fn_decl(ctor.node.dec, e, v); + v.visit_block(ctor.node.body, e, v); } item_iface(tps, methods) { v.visit_ty_params(tps, e, v); diff --git a/src/test/run-pass/classes-simple.rs b/src/test/run-pass/classes-simple.rs index ecfe14b0e6f0..3b4df149fa58 100644 --- a/src/test/run-pass/classes-simple.rs +++ b/src/test/run-pass/classes-simple.rs @@ -1,4 +1,3 @@ -// xfail-test class cat { priv { let mutable meows : uint; @@ -12,6 +11,6 @@ class cat { fn main() { let nyan : cat = cat(52u, 99); let kitty = cat(1000u, 2); - log(debug, nyan.how_hungry); - log(debug, kitty.how_hungry); -} \ No newline at end of file + assert(nyan.how_hungry == 99); + assert(kitty.how_hungry == 2); +}