diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4b9454942935..3740557b7f8f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -137,7 +137,7 @@ enum def { @def, // closed over def node_id, // expr node that creates the closure node_id), // id for the block/body of the closure expr - def_class(def_id, bool /* has constructor */), + def_class(def_id), def_typaram_binder(node_id), /* class, impl or trait that has ty params */ def_region(node_id), def_label(node_id) @@ -238,9 +238,9 @@ impl def : cmp::Eq { _ => false } } - def_class(e0a, e1a) => { + def_class(e0a) => { match (*other) { - def_class(e0b, e1b) => e0a == e0b && e1a == e1b, + def_class(e0b) => e0a == e0b, _ => false } } @@ -1465,8 +1465,6 @@ type struct_def = { fields: ~[@struct_field], /* fields */ methods: ~[@method], /* methods */ /* (not including ctor or dtor) */ - /* ctor is optional, and will soon go away */ - ctor: Option, /* dtor is optional */ dtor: Option }; @@ -1566,7 +1564,6 @@ enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), ii_foreign(@foreign_item), - ii_ctor(class_ctor, ident, ~[ty_param], def_id /* parent id */), ii_dtor(class_dtor, ident, ~[ty_param], def_id /* parent id */) } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index d05c6eadaf6a..8555ceed2dbd 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -71,9 +71,6 @@ enum ast_node { // order they are introduced. node_arg(arg, uint), node_local(uint), - // Constructor for a class - // def_id is parent id - node_ctor(ident, ~[ty_param], @class_ctor, def_id, @path), // Destructor for a class node_dtor(~[ty_param], @class_dtor, def_id, @path), node_block(blk), @@ -132,7 +129,7 @@ fn map_decoded_item(diag: span_handler, // don't decode and instantiate the impl, but just the method, we have to // add it to the table now: match ii { - ii_item(*) | ii_ctor(*) | ii_dtor(*) => { /* fallthrough */ } + ii_item(*) | ii_dtor(*) => { /* fallthrough */ } ii_foreign(i) => { cx.map.insert(i.id, node_foreign_item(i, foreign_abi_rust_intrinsic, @path)); @@ -155,18 +152,6 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, cx.local_id += 1u; } match fk { - visit::fk_ctor(nm, attrs, tps, self_id, parent_id) => { - let ct = @{node: {id: id, - attrs: attrs, - self_id: self_id, - dec: /* FIXME (#2543) */ copy decl, - body: /* FIXME (#2543) */ copy body}, - span: sp}; - cx.map.insert(id, node_ctor(/* FIXME (#2543) */ copy nm, - /* FIXME (#2543) */ copy tps, - ct, parent_id, - @/* FIXME (#2543) */ copy cx.path)); - } visit::fk_dtor(tps, attrs, self_id, parent_id) => { let dt = @{node: {id: id, attrs: attrs, self_id: self_id, body: /* FIXME (#2543) */ copy body}, span: sp}; @@ -382,9 +367,6 @@ fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { Some(node_local(_)) => { // add more info here fmt!("local (id=%?)", id) } - Some(node_ctor(*)) => { // add more info here - fmt!("node_ctor (id=%?)", id) - } Some(node_dtor(*)) => { // add more info here fmt!("node_dtor (id=%?)", id) } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 35b9e8d40c01..4c18b6b8ecac 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -57,7 +57,7 @@ pure fn def_id_of_def(d: def) -> def_id { def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) | def_foreign_mod(id) | def_const(id) | def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | - def_use(id) | def_class(id, _) => { + def_use(id) | def_class(id) => { id } def_arg(id, _) | def_local(id, _) | def_self(id) | @@ -338,7 +338,6 @@ impl inlined_item: inlined_item_utils { ii_item(i) => /* FIXME (#2543) */ copy i.ident, ii_foreign(i) => /* FIXME (#2543) */ copy i.ident, ii_method(_, m) => /* FIXME (#2543) */ copy m.ident, - ii_ctor(_, nm, _, _) => /* FIXME (#2543) */ copy nm, ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm } } @@ -348,7 +347,6 @@ impl inlined_item: inlined_item_utils { ii_item(i) => i.id, ii_foreign(i) => i.id, ii_method(_, m) => m.id, - ii_ctor(ctor, _, _, _) => ctor.node.id, ii_dtor(dtor, _, _, _) => dtor.node.id } } @@ -358,9 +356,6 @@ impl inlined_item: inlined_item_utils { ii_item(i) => v.visit_item(i, e, v), ii_foreign(i) => v.visit_foreign_item(i, e, v), ii_method(_, m) => visit::visit_method_helper(m, e, v), - ii_ctor(ctor, nm, tps, parent_id) => { - visit::visit_class_ctor_helper(ctor, nm, tps, parent_id, e, v); - } ii_dtor(dtor, _, tps, parent_id) => { visit::visit_class_dtor_helper(dtor, tps, parent_id, e, v); } @@ -494,12 +489,6 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(id); match fk { - visit::fk_ctor(_, _, tps, self_id, parent_id) => { - for vec::each(tps) |tp| { vfn(tp.id); } - vfn(id); - vfn(self_id); - vfn(parent_id.node); - } visit::fk_dtor(tps, _, self_id, parent_id) => { for vec::each(tps) |tp| { vfn(tp.id); } vfn(id); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 088df01985ee..68d9cd80430d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -271,23 +271,6 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) -> @ast::struct_def { - let resulting_optional_constructor; - match struct_def.ctor { - None => { - resulting_optional_constructor = None; - } - Some(constructor) => { - resulting_optional_constructor = Some({ - node: { - body: fld.fold_block(constructor.node.body), - dec: fold_fn_decl(constructor.node.dec, fld), - id: fld.new_id(constructor.node.id), - .. constructor.node - }, - .. constructor - }); - } - } let dtor = do option::map(&struct_def.dtor) |dtor| { let dtor_body = fld.fold_block(dtor.node.body); let dtor_id = fld.new_id(dtor.node.id); @@ -298,7 +281,6 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) traits: vec::map(struct_def.traits, |p| fold_trait_ref(*p, fld)), 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 }; } @@ -585,7 +567,6 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { |f| fld.fold_struct_field(*f)), methods: vec::map(struct_def.methods, |m| fld.fold_method(*m)), - ctor: None, dtor: dtor }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4457c64a68c0..973822ddff9b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -115,8 +115,7 @@ enum class_member { So that we can distinguish a class ctor or dtor from other class members */ -enum class_contents { ctor_decl(fn_decl, ~[attribute], blk, codemap::span), - dtor_decl(blk, ~[attribute], codemap::span), +enum class_contents { dtor_decl(blk, ~[attribute], codemap::span), members(~[@class_member]) } type arg_or_capture_item = Either; @@ -2683,30 +2682,13 @@ impl parser { let mut fields: ~[@struct_field]; let mut methods: ~[@method] = ~[]; - let mut the_ctor: Option<(fn_decl, ~[attribute], blk, codemap::span)> - = None; let mut the_dtor: Option<(blk, ~[attribute], codemap::span)> = None; - let ctor_id = self.get_id(); if self.eat(token::LBRACE) { // It's a record-like struct. fields = ~[]; while self.token != token::RBRACE { match self.parse_class_item() { - ctor_decl(a_fn_decl, attrs, blk, s) => { - match the_ctor { - Some((_, _, _, s_first)) => { - self.span_note(s, fmt!("Duplicate constructor \ - declaration for class %s", - *self.interner.get(class_name))); - self.span_fatal(copy s_first, ~"First constructor \ - declared here"); - } - None => { - the_ctor = Some((a_fn_decl, attrs, blk, s)); - } - } - } dtor_decl(blk, attrs, s) => { match the_dtor { Some((_, _, s_first)) => { @@ -2764,36 +2746,14 @@ impl parser { self_id: self.get_id(), body: d_body}, span: d_s}}; - match the_ctor { - Some((ct_d, ct_attrs, ct_b, ct_s)) => { - (class_name, - item_class(@{ - traits: traits, - fields: move fields, - methods: move methods, - ctor: Some({ - node: {id: ctor_id, - attrs: ct_attrs, - self_id: self.get_id(), - dec: ct_d, - body: ct_b}, - span: ct_s}), - dtor: actual_dtor - }, ty_params), - None) - } - None => { - (class_name, - item_class(@{ - traits: traits, - fields: move fields, - methods: move methods, - ctor: None, - dtor: actual_dtor - }, ty_params), - None) - } - } + (class_name, + item_class(@{ + traits: traits, + fields: move fields, + methods: move methods, + dtor: actual_dtor + }, ty_params), + None) } fn token_is_pound_or_doc_comment(++tok: token::token) -> bool { @@ -3097,12 +3057,6 @@ impl parser { let mut methods: ~[@method] = ~[]; while self.token != token::RBRACE { match self.parse_class_item() { - ctor_decl(*) => { - self.span_fatal(copy self.span, - ~"deprecated explicit \ - constructors are not allowed \ - here"); - } dtor_decl(blk, attrs, s) => { match the_dtor { Some((_, _, s_first)) => { @@ -3143,7 +3097,6 @@ impl parser { traits: ~[], fields: move fields, methods: move methods, - ctor: None, dtor: actual_dtor }; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bff356e5cb72..b98014f421bb 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -653,18 +653,6 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], } bopen(s); hardbreak_if_not_bol(s); - do struct_def.ctor.iter |ctor| { - maybe_print_comment(s, ctor.span.lo); - print_outer_attributes(s, ctor.node.attrs); - // Doesn't call head because there shouldn't be a space after new. - cbox(s, indent_unit); - ibox(s, 4); - word(s.s, ~"new("); - print_fn_args(s, ctor.node.dec, ~[], None); - word(s.s, ~")"); - space(s.s); - print_block(s, ctor.node.body); - } do struct_def.dtor.iter |dtor| { hardbreak_if_not_bol(s); maybe_print_comment(s, dtor.span.lo); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index e6fd65eb458a..50fbd21f7b8d 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -17,8 +17,6 @@ enum fn_kind { fk_method(ident, ~[ty_param], @method), fk_anon(proto, capture_clause), //< an anonymous function like fn@(...) fk_fn_block(capture_clause), //< a block {||...} - fk_ctor(ident, ~[attribute], ~[ty_param], node_id /* self id */, - def_id /* parent class id */), // class constructor fk_dtor(~[ty_param], ~[attribute], node_id /* self id */, def_id /* parent class id */) // class destructor @@ -26,8 +24,9 @@ enum fn_kind { fn name_of_fn(fk: fn_kind) -> ident { match fk { - fk_item_fn(name, _, _) | fk_method(name, _, _) - | fk_ctor(name, _, _, _, _) => /* FIXME (#2543) */ copy name, + fk_item_fn(name, _, _) | fk_method(name, _, _) => { + /* FIXME (#2543) */ copy name + } fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon, fk_dtor(*) => parse::token::special_idents::dtor } @@ -35,11 +34,11 @@ fn name_of_fn(fk: fn_kind) -> ident { fn tps_of_fn(fk: fn_kind) -> ~[ty_param] { match fk { - fk_item_fn(_, tps, _) | fk_method(_, tps, _) - | fk_ctor(_, _, tps, _, _) | fk_dtor(tps, _, _, _) => { - /* FIXME (#2543) */ copy tps - } - fk_anon(*) | fk_fn_block(*) => ~[] + fk_item_fn(_, tps, _) | fk_method(_, tps, _) | + fk_dtor(tps, _, _, _) => { + /* FIXME (#2543) */ copy tps + } + fk_anon(*) | fk_fn_block(*) => ~[] } } @@ -291,17 +290,6 @@ fn visit_method_helper(m: @method, e: E, v: vt) { m.decl, m.body, m.span, m.id, e, v); } -// Similar logic to the comment on visit_method_helper - Tim -fn visit_class_ctor_helper(ctor: class_ctor, nm: ident, tps: ~[ty_param], - parent_id: def_id, e: E, v: vt) { - v.visit_fn(fk_ctor(/* FIXME (#2543) */ copy nm, - ctor.node.attrs, - /* FIXME (#2543) */ copy tps, - ctor.node.self_id, parent_id), - ctor.node.dec, ctor.node.body, ctor.span, ctor.node.id, e, v) - -} - fn visit_class_dtor_helper(dtor: class_dtor, tps: ~[ty_param], parent_id: def_id, e: E, v: vt) { v.visit_fn(fk_dtor(/* FIXME (#2543) */ copy tps, dtor.node.attrs, @@ -330,7 +318,7 @@ fn visit_trait_method(m: trait_method, e: E, v: vt) { } } -fn visit_struct_def(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], +fn visit_struct_def(sd: @struct_def, _nm: ast::ident, tps: ~[ty_param], id: node_id, e: E, v: vt) { for sd.fields.each |f| { v.visit_struct_field(*f, e, v); @@ -341,9 +329,6 @@ fn visit_struct_def(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], for sd.traits.each |p| { visit_path(p.path, e, v); } - do option::iter(&sd.ctor) |ctor| { - visit_class_ctor_helper(*ctor, nm, tps, ast_util::local_def(id), e, v); - }; do option::iter(&sd.dtor) |dtor| { visit_class_dtor_helper(*dtor, tps, ast_util::local_def(id), e, v) }; diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 38838120a103..e639449a8573 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -124,7 +124,6 @@ enum Family { Variant, // v Impl, // i Trait, // I - Class, // C Struct, // S PublicField, // g PrivateField, // j @@ -157,7 +156,6 @@ fn item_family(item: ebml::Doc) -> Family { 'v' => Variant, 'i' => Impl, 'I' => Trait, - 'C' => Class, 'S' => Struct, 'g' => PublicField, 'j' => PrivateField, @@ -308,8 +306,7 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) let fam = item_family(item); match fam { Const => dl_def(ast::def_const(did)), - Class => dl_def(ast::def_class(did, true)), - Struct => dl_def(ast::def_class(did, false)), + Struct => dl_def(ast::def_class(did)), UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)), Fn => dl_def(ast::def_fn(did, ast::impure_fn)), PureFn => dl_def(ast::def_fn(did, ast::pure_fn)), @@ -832,7 +829,6 @@ fn item_family_to_str(fam: Family) -> ~str { Variant => ~"variant", Impl => ~"impl", Trait => ~"trait", - Class => ~"class", Struct => ~"struct", PublicField => ~"public field", PrivateField => ~"private field", diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 63a7ce1ac74c..2fdd39a2ca48 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -635,12 +635,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer, /* Now, make an item for the class itself */ ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - - match struct_def.ctor { - None => encode_family(ebml_w, 'S'), - Some(_) => encode_family(ebml_w, 'C') - } - + encode_family(ebml_w, 'S'); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ecx, ebml_w, item.ident); @@ -699,21 +694,6 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer, let bkts = create_index(idx); encode_index(ebml_w, bkts, write_int); ebml_w.end_tag(); - - /* Encode the constructor */ - for struct_def.ctor.each |ctor| { - debug!("encoding info for ctor %s %d", - ecx.tcx.sess.str_of(item.ident), ctor.node.id); - index.push({ - val: ctor.node.id, - pos: ebml_w.writer.tell() - }); - encode_info_for_ctor(ecx, ebml_w, ctor.node.id, item.ident, - path, if tps.len() > 0u { - Some(ii_ctor(*ctor, item.ident, tps, - local_def(item.id))) } - else { None }, tps); - } } item_impl(tps, opt_trait, _, methods) => { add_to_index(); diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 15b20c41b674..d1f766dd8672 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -261,13 +261,6 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item { ast::ii_foreign(i) => { ast::ii_foreign(fld.fold_foreign_item(i)) } - ast::ii_ctor(ctor, nm, tps, parent_id) => { - let ctor_body = fld.fold_block(ctor.node.body); - let ctor_decl = fold::fold_fn_decl(ctor.node.dec, fld); - ast::ii_ctor({node: {body: ctor_body, dec: ctor_decl, - .. ctor.node}, - .. ctor}, nm, tps, parent_id) - } ast::ii_dtor(dtor, nm, tps, parent_id) => { let dtor_body = fld.fold_block(dtor.node.body); ast::ii_dtor({node: {body: dtor_body, @@ -301,18 +294,6 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item) ast::ii_foreign(i) => { ast::ii_foreign(fld.fold_foreign_item(i)) } - ast::ii_ctor(ctor, nm, tps, parent_id) => { - let ctor_body = fld.fold_block(ctor.node.body); - let ctor_attrs = fld.fold_attributes(ctor.node.attrs); - let ctor_decl = fold::fold_fn_decl(ctor.node.dec, fld); - let new_params = fold::fold_ty_params(tps, fld); - let ctor_id = fld.new_id(ctor.node.id); - let new_parent = xcx.tr_def_id(parent_id); - ast::ii_ctor({node: {body: ctor_body, attrs: ctor_attrs, - dec: ctor_decl, id: ctor_id, - .. ctor.node}, - .. ctor}, nm, new_params, new_parent) - } ast::ii_dtor(dtor, nm, tps, parent_id) => { let dtor_body = fld.fold_block(dtor.node.body); let dtor_attrs = fld.fold_attributes(dtor.node.attrs); @@ -368,8 +349,8 @@ impl ast::def: tr { xcx.tr_id(nid2), xcx.tr_id(nid3)) } - ast::def_class(did, has_constructor) => { - ast::def_class(did.tr(xcx), has_constructor) + ast::def_class(did) => { + ast::def_class(did.tr(xcx)) } ast::def_region(nid) => ast::def_region(xcx.tr_id(nid)), ast::def_typaram_binder(nid) => { diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index cc8d89a8ace7..6a9195b45096 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -17,10 +17,6 @@ enum check_loan_ctxt = @{ reported: HashMap, - // Keep track of whether we're inside a ctor, so as to - // allow mutating immutable fields in the same class if - // we are in a ctor, we track the self id - mut in_ctor: bool, mut declared_purity: ast::purity, mut fn_args: @~[ast::node_id] }; @@ -62,7 +58,6 @@ fn check_loans(bccx: borrowck_ctxt, let clcx = check_loan_ctxt(@{bccx: bccx, req_maps: req_maps, reported: HashMap(), - mut in_ctor: false, mut declared_purity: ast::impure_fn, mut fn_args: @~[]}); let vt = visit::mk_vt(@{visit_expr: check_loans_in_expr, @@ -320,10 +315,7 @@ impl check_loan_ctxt { debug!("check_assignment(cmt=%s)", self.bccx.cmt_to_repr(cmt)); - if self.in_ctor && self.is_self_field(cmt) - && at.checked_by_liveness() { - // assigning to self.foo in a ctor is always allowed. - } else if self.is_local_variable(cmt) && at.checked_by_liveness() { + if self.is_local_variable(cmt) && at.checked_by_liveness() { // liveness guarantees that immutable local variables // are only assigned once } else { @@ -542,42 +534,28 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, visitor: visit::vt) { debug!("purity on entry=%?", copy self.declared_purity); - do save_and_restore(&mut(self.in_ctor)) { - do save_and_restore(&mut(self.declared_purity)) { - do save_and_restore(&mut(self.fn_args)) { - let is_stack_closure = self.is_stack_closure(id); - let fty = ty::node_id_to_type(self.tcx(), id); - self.declared_purity = ty::determine_inherited_purity( - copy self.declared_purity, - ty::ty_fn_purity(fty), - ty::ty_fn_proto(fty)); + do save_and_restore(&mut(self.declared_purity)) { + do save_and_restore(&mut(self.fn_args)) { + let is_stack_closure = self.is_stack_closure(id); + let fty = ty::node_id_to_type(self.tcx(), id); + self.declared_purity = ty::determine_inherited_purity( + copy self.declared_purity, + ty::ty_fn_purity(fty), + ty::ty_fn_proto(fty)); - // In principle, we could consider fk_anon(*) or - // fk_fn_block(*) to be in a ctor, I suppose, but the - // purpose of the in_ctor flag is to allow modifications - // of otherwise immutable fields and typestate wouldn't be - // able to "see" into those functions anyway, so it - // wouldn't be very helpful. - match fk { - visit::fk_ctor(*) => { - self.in_ctor = true; - self.fn_args = @decl.inputs.map(|i| i.id ); - } - visit::fk_anon(*) | - visit::fk_fn_block(*) if is_stack_closure => { - self.in_ctor = false; + match fk { + visit::fk_anon(*) | + visit::fk_fn_block(*) if is_stack_closure => { // inherits the fn_args from enclosing ctxt - } - visit::fk_anon(*) | visit::fk_fn_block(*) | - visit::fk_method(*) | visit::fk_item_fn(*) | - visit::fk_dtor(*) => { - self.in_ctor = false; - self.fn_args = @decl.inputs.map(|i| i.id ); - } } - - visit::visit_fn(fk, decl, body, sp, id, self, visitor); + visit::fk_anon(*) | visit::fk_fn_block(*) | + visit::fk_method(*) | visit::fk_item_fn(*) | + visit::fk_dtor(*) => { + self.fn_args = @decl.inputs.map(|i| i.id ); + } } + + visit::visit_fn(fk, decl, body, sp, id, self, visitor); } } debug!("purity on exit=%?", copy self.declared_purity); diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index 2030984ae704..a2c8f1850713 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -71,11 +71,11 @@ fn req_loans_in_fn(fk: visit::fn_kind, self.root_ub = body.node.id; match fk { - visit::fk_anon(*) | visit::fk_fn_block(*) => {} - visit::fk_item_fn(*) | visit::fk_method(*) | - visit::fk_ctor(*) | visit::fk_dtor(*) => { - self.item_ub = body.node.id; - } + visit::fk_anon(*) | visit::fk_fn_block(*) => {} + visit::fk_item_fn(*) | visit::fk_method(*) | + visit::fk_dtor(*) => { + self.item_ub = body.node.id; + } } visit::visit_fn(fk, decl, body, sp, id, self, v); diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index e2b85441a8fd..7b473cedb4c5 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -181,9 +181,9 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span, // variables. This list is used below to avoid checking and reporting // on a given variable twice. let cap_clause = match fk { - visit::fk_anon(_, cc) | visit::fk_fn_block(cc) => cc, - visit::fk_item_fn(*) | visit::fk_method(*) | - visit::fk_ctor(*) | visit::fk_dtor(*) => @~[] + visit::fk_anon(_, cc) | visit::fk_fn_block(cc) => cc, + visit::fk_item_fn(*) | visit::fk_method(*) | + visit::fk_dtor(*) => @~[] }; let captured_vars = do (*cap_clause).map |cap_item| { let cap_def = cx.tcx.def_map.get(cap_item.id); diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index 9ef54eedcf5b..5ead871a661f 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -35,12 +35,6 @@ * Any use of the variable where the variable is dead afterwards is a * last use. * - * # Extension to handle constructors - * - * Each field is assigned an index just as with local variables. A use of - * `self` is considered a use of all fields. A use of `self.f` is just a use - * of `f`. - * * # Implementation details * * The actual implementation contains two (nested) walks over the AST. @@ -96,8 +90,6 @@ * - `no_ret_var`: a synthetic variable that is only 'read' from, the * fallthrough node. This allows us to detect functions where we fail * to return explicitly. - * - * - `self_var`: a variable representing 'self' */ use dvec::DVec; @@ -230,9 +222,11 @@ impl LiveNode { fn invalid_node() -> LiveNode { LiveNode(uint::max_value) } -enum RelevantDef { RelevantVar(node_id), RelevantSelf } - -type CaptureInfo = {ln: LiveNode, is_move: bool, rv: RelevantDef}; +struct CaptureInfo { + ln: LiveNode, + is_move: bool, + var_nid: node_id +} enum LocalKind { FromMatch(binding_mode), @@ -250,18 +244,15 @@ struct LocalInfo { enum VarKind { Arg(node_id, ident, rmode), Local(LocalInfo), - Field(ident), Self, ImplicitRet } -fn relevant_def(def: def) -> Option { +fn relevant_def(def: def) -> Option { match def { - def_self(_) => Some(RelevantSelf), - def_binding(nid, _) | def_arg(nid, _) | - def_local(nid, _) => Some(RelevantVar(nid)), + def_local(nid, _) => Some(nid), _ => None } @@ -276,7 +267,6 @@ struct IrMaps { mut num_vars: uint, live_node_map: HashMap, variable_map: HashMap, - field_map: HashMap, capture_map: HashMap, mut var_kinds: ~[VarKind], mut lnks: ~[LiveNodeKind], @@ -293,7 +283,6 @@ fn IrMaps(tcx: ty::ctxt, method_map: typeck::method_map, live_node_map: HashMap(), variable_map: HashMap(), capture_map: HashMap(), - field_map: HashMap(), var_kinds: ~[], lnks: ~[] } @@ -323,15 +312,12 @@ impl IrMaps { self.num_vars += 1u; match vk { - Local(LocalInfo {id:node_id, _}) | - Arg(node_id, _, _) => { - self.variable_map.insert(node_id, v); - } - Field(name) => { - self.field_map.insert(name, v); - } - Self | ImplicitRet => { - } + Local(LocalInfo {id:node_id, _}) | + Arg(node_id, _, _) => { + self.variable_map.insert(node_id, v); + } + Self | ImplicitRet => { + } } debug!("%s is %?", v.to_str(), vk); @@ -351,11 +337,10 @@ impl IrMaps { fn variable_name(var: Variable) -> ~str { match copy self.var_kinds[*var] { - Local(LocalInfo {ident: nm, _}) | - Arg(_, nm, _) => self.tcx.sess.str_of(nm), - Field(nm) => ~"self." + self.tcx.sess.str_of(nm), - Self => ~"self", - ImplicitRet => ~"" + Local(LocalInfo {ident: nm, _}) | + Arg(_, nm, _) => self.tcx.sess.str_of(nm), + Self => ~"self", + ImplicitRet => ~"" } } @@ -399,7 +384,7 @@ impl IrMaps { (*v).push(id); } Arg(_, _, by_ref) | - Arg(_, _, by_val) | Self | Field(_) | ImplicitRet | + Arg(_, _, by_val) | Self | ImplicitRet | Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => { debug!("--but it is not owned"); } @@ -428,13 +413,6 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, // and so forth: visit::visit_fn(fk, decl, body, sp, id, fn_maps, v); - match fk { - visit::fk_ctor(_, _, _, _, class_did) => { - add_class_fields(fn_maps, class_did); - } - _ => {} - } - // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or fail // - implicit_ret_var is a pseudo-variable that represents @@ -442,8 +420,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, let specials = { exit_ln: (*fn_maps).add_live_node(ExitNode), fallthrough_ln: (*fn_maps).add_live_node(ExitNode), - no_ret_var: (*fn_maps).add_variable(ImplicitRet), - self_var: (*fn_maps).add_variable(Self) + no_ret_var: (*fn_maps).add_variable(ImplicitRet) }; // compute liveness @@ -460,18 +437,9 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, }); check_vt.visit_block(body, lsets, check_vt); lsets.check_ret(id, sp, fk, entry_ln); - lsets.check_fields(sp, entry_ln); lsets.warn_about_unused_args(sp, decl, entry_ln); } -fn add_class_fields(self: @IrMaps, did: def_id) { - for ty::lookup_class_fields(self.tcx, did).each |field_ty| { - assert field_ty.id.crate == local_crate; - let var = self.add_variable(Field(field_ty.ident)); - self.field_map.insert(field_ty.ident, var); - } -} - fn visit_local(local: @local, &&self: @IrMaps, vt: vt<@IrMaps>) { let def_map = self.tcx.def_map; do pat_util::pat_bindings(def_map, local.node.pat) |_bm, p_id, sp, path| { @@ -540,7 +508,9 @@ fn visit_expr(expr: @expr, &&self: @IrMaps, vt: vt<@IrMaps>) { cap_move | cap_drop => true, // var must be dead afterwards cap_copy | cap_ref => false // var can still be used }; - call_caps.push({ln: cv_ln, is_move: is_move, rv: rv}); + call_caps.push(CaptureInfo {ln: cv_ln, + is_move: is_move, + var_nid: rv}); } None => {} } @@ -595,8 +565,7 @@ fn invalid_users() -> users { type Specials = { exit_ln: LiveNode, fallthrough_ln: LiveNode, - no_ret_var: Variable, - self_var: Variable + no_ret_var: Variable }; const ACC_READ: uint = 1u; @@ -647,19 +616,12 @@ impl Liveness { } } - fn variable_from_rdef(rv: RelevantDef, span: span) -> Variable { - match rv { - RelevantSelf => self.s.self_var, - RelevantVar(nid) => self.variable(nid, span) - } - } - fn variable_from_path(expr: @expr) -> Option { match expr.node { expr_path(_) => { let def = self.tcx.def_map.get(expr.id); relevant_def(def).map( - |rdef| self.variable_from_rdef(*rdef, expr.span) + |rdef| self.variable(*rdef, expr.span) ) } _ => None @@ -675,7 +637,7 @@ impl Liveness { match self.tcx.def_map.find(node_id) { Some(def) => { relevant_def(def).map( - |rdef| self.variable_from_rdef(*rdef, span) + |rdef| self.variable(*rdef, span) ) } None => { @@ -934,14 +896,6 @@ impl Liveness { } } - // as above, the "self" variable is a non-owned variable - self.acc(self.s.exit_ln, self.s.self_var, ACC_READ); - - // in a ctor, there is an implicit use of self.f for all fields f: - for self.ir.field_map.each_value |var| { - self.acc(self.s.exit_ln, var, ACC_READ|ACC_USE); - } - // the fallthrough exit is only for those cases where we do not // explicitly return: self.init_from_succ(self.s.fallthrough_ln, self.s.exit_ln); @@ -1023,24 +977,11 @@ impl Liveness { // Interesting cases with control flow or which gen/kill expr_path(_) => { - self.access_path(expr, succ, ACC_READ | ACC_USE) + self.access_path(expr, succ, ACC_READ | ACC_USE) } - expr_field(e, nm, _) => { - // If this is a reference to `self.f` inside of a ctor, - // then we treat it as a read of that variable. - // Otherwise, we ignore it and just propagate down to - // process `e`. - match self.as_self_field(e, nm) { - Some((ln, var)) => { - self.init_from_succ(ln, succ); - self.acc(ln, var, ACC_READ | ACC_USE); - ln - } - None => { - self.propagate_through_expr(e, succ) - } - } + expr_field(e, _, _) => { + self.propagate_through_expr(e, succ) } expr_fn(*) | expr_fn_block(*) => { @@ -1049,7 +990,7 @@ impl Liveness { let caps = (*self.ir).captures(expr); do (*caps).foldr(succ) |cap, succ| { self.init_from_succ(cap.ln, succ); - let var = self.variable_from_rdef(cap.rv, expr.span); + let var = self.variable(cap.var_nid, expr.span); self.acc(cap.ln, var, ACC_READ | ACC_USE); cap.ln } @@ -1269,8 +1210,8 @@ impl Liveness { // In general, the full flow graph structure for an // assignment/move/etc can be handled in one of two ways, // depending on whether what is being assigned is a "tracked - // value" or not. A tracked value is basically a local variable - // or argument, or a self-field (`self.f`) in a ctor. + // value" or not. A tracked value is basically a local + // variable or argument. // // The two kinds of graphs are: // @@ -1293,12 +1234,11 @@ impl Liveness { // // # Tracked lvalues // - // A tracked lvalue is either a local variable/argument `x` or - // else it is a self-field `self.f` in a constructor. In + // A tracked lvalue is a local variable/argument `x`. In // these cases, the link_node where the write occurs is linked - // to node id of `x` or `self`, respectively. The - // `write_lvalue()` routine generates the contents of this - // node. There are no subcomponents to consider. + // to node id of `x`. The `write_lvalue()` routine generates + // the contents of this node. There are no subcomponents to + // consider. // // # Non-tracked lvalues // @@ -1315,12 +1255,9 @@ impl Liveness { // just ignore such cases and treat them as reads. match expr.node { - expr_path(_) => succ, - expr_field(e, nm, _) => match self.as_self_field(e, nm) { - Some(_) => succ, - None => self.propagate_through_expr(e, succ) - }, - _ => self.propagate_through_expr(expr, succ) + expr_path(_) => succ, + expr_field(e, _, _) => self.propagate_through_expr(e, succ), + _ => self.propagate_through_expr(expr, succ) } } @@ -1330,14 +1267,6 @@ impl Liveness { acc: uint) -> LiveNode { match expr.node { expr_path(_) => self.access_path(expr, succ, acc), - expr_field(e, nm, _) => match self.as_self_field(e, nm) { - Some((ln, var)) => { - self.init_from_succ(ln, succ); - self.acc(ln, var, acc); - ln - } - None => succ - }, // We do not track other lvalues, so just propagate through // to their subcomponents. Also, it may happen that @@ -1350,27 +1279,7 @@ impl Liveness { fn access_path(expr: @expr, succ: LiveNode, acc: uint) -> LiveNode { let def = self.tcx.def_map.get(expr.id); match relevant_def(def) { - Some(RelevantSelf) => { - // Accessing `self` is like accessing every field of - // the current object. This allows something like - // `self = ...;` (it will be considered a write to - // every field, sensibly enough), though the borrowck - // pass will reject it later on. - // - // Also, note that, within a ctor at least, an - // expression like `self.f` is "shortcircuiting" - // before it reaches this point by the code for - // expr_field. - let ln = self.live_node(expr.id, expr.span); - if acc != 0u { - self.init_from_succ(ln, succ); - for self.ir.field_map.each_value |var| { - self.acc(ln, var, acc); - } - } - ln - } - Some(RelevantVar(nid)) => { + Some(nid) => { let ln = self.live_node(expr.id, expr.span); if acc != 0u { self.init_from_succ(ln, succ); @@ -1383,29 +1292,6 @@ impl Liveness { } } - fn as_self_field(expr: @expr, - fld: ident) -> Option<(LiveNode,Variable)> { - // If we checking a constructor, then we treat self.f as a - // variable. we use the live_node id that will be assigned to - // the reference to self but the variable id for `f`. - match expr.node { - expr_path(_) => { - let def = self.tcx.def_map.get(expr.id); - match def { - def_self(_) => { - // Note: the field_map is empty unless we are in a ctor - return self.ir.field_map.find(fld).map(|var| { - let ln = self.live_node(expr.id, expr.span); - (ln, *var) - }); - } - _ => return None - } - } - _ => return None - } - } - fn propagate_through_loop(expr: @expr, cond: Option<@expr>, body: blk, @@ -1533,7 +1419,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { expr_fn(*) | expr_fn_block(*) => { let caps = (*self.ir).captures(expr); for (*caps).each |cap| { - let var = self.variable_from_rdef(cap.rv, expr.span); + let var = self.variable(cap.var_nid, expr.span); self.consider_last_use(expr, cap.ln, var); if cap.is_move { self.check_move_from_var(expr.span, cap.ln, var); @@ -1613,24 +1499,7 @@ enum ReadKind { } impl @Liveness { - fn check_fields(sp: span, entry_ln: LiveNode) { - for self.ir.field_map.each |nm, var| { - match self.live_on_entry(entry_ln, var) { - None => { /* ok */ } - Some(ExitNode) => { - self.tcx.sess.span_err( - sp, fmt!("field `self.%s` is never initialized", - self.tcx.sess.str_of(nm))); - } - Some(lnk) => { - self.report_illegal_read( - sp, lnk, var, PossiblyUninitializedField); - } - } - } - } - - fn check_ret(id: node_id, sp: span, fk: visit::fn_kind, + fn check_ret(id: node_id, sp: span, _fk: visit::fn_kind, entry_ln: LiveNode) { if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { // if no_ret_var is live, then we fall off the end of the @@ -1644,15 +1513,8 @@ impl @Liveness { self.tcx.sess.span_err( sp, ~"some control paths may return"); } else { - match fk { - visit::fk_ctor(*) => { - // ctors are written as though they are unit. - } - _ => { - self.tcx.sess.span_err( - sp, ~"not all control paths return a value"); - } - } + self.tcx.sess.span_err( + sp, ~"not all control paths return a value"); } } } @@ -1732,12 +1594,11 @@ impl @Liveness { } def => { match relevant_def(def) { - Some(RelevantVar(nid)) => { + Some(nid) => { let ln = self.live_node(expr.id, expr.span); let var = self.variable(nid, expr.span); self.warn_about_dead_assign(expr.span, ln, var); } - Some(RelevantSelf) => {} None => {} } } @@ -1796,13 +1657,6 @@ impl @Liveness { copy or move mode", self.tcx.sess.str_of(name))); return; } - Field(name) => { - self.tcx.sess.span_err( - move_span, - fmt!("illegal move from field `%s`", - self.tcx.sess.str_of(name))); - return; - } Self => { self.tcx.sess.span_err( move_span, diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index ff708b7f4efa..eb0bf8796f07 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -305,16 +305,16 @@ fn resolve_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, visitor: visit::vt) { let fn_cx = match fk { - visit::fk_item_fn(*) | visit::fk_method(*) | - visit::fk_ctor(*) | visit::fk_dtor(*) => { - // Top-level functions are a root scope. - ctxt {parent: Some(id),.. cx} - } + visit::fk_item_fn(*) | visit::fk_method(*) | + visit::fk_dtor(*) => { + // Top-level functions are a root scope. + ctxt {parent: Some(id),.. cx} + } - visit::fk_anon(*) | visit::fk_fn_block(*) => { - // Closures continue with the inherited scope. - cx - } + visit::fk_anon(*) | visit::fk_fn_block(*) => { + // Closures continue with the inherited scope. + cx + } }; debug!("visiting fn with body %d. cx.parent: %? \ @@ -641,7 +641,7 @@ fn determine_rp_in_ty(ty: @ast::ty, match ty.node { ast::ty_path(path, id) => { match cx.def_map.get(id) { - ast::def_ty(did) | ast::def_class(did, _) => { + ast::def_ty(did) | ast::def_class(did) => { if did.crate == ast::local_crate { if cx.opt_region_is_relevant(path.rp) { cx.add_dep(did.node); diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 314dea1b5763..045905bbe07b 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -757,7 +757,7 @@ struct Resolver { unused_import_lint_level: level, trait_info: HashMap>, - structs: HashMap, + structs: HashMap, // The number of imports that are currently unresolved. mut unresolved_imports: uint, @@ -1069,36 +1069,15 @@ impl Resolver { } // These items live in both the type and value namespaces. - item_class(struct_definition, _) => { - let new_parent = - match struct_definition.ctor { - None => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ~[TypeNS], sp); + item_class(*) => { + let (name_bindings, new_parent) = + self.add_child(ident, parent, ~[TypeNS], sp); - (*name_bindings).define_type - (privacy, def_ty(local_def(item.id)), sp); - new_parent - } - Some(ctor) => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ~[ValueNS, TypeNS], - sp); - - (*name_bindings).define_type - (privacy, def_ty(local_def(item.id)), sp); - - let purity = impure_fn; - let ctor_def = def_fn(local_def(ctor.node.id), - purity); - (*name_bindings).define_value(privacy, ctor_def, sp); - new_parent - } - }; + (*name_bindings).define_type + (privacy, def_ty(local_def(item.id)), sp); // Record the def ID of this struct. - self.structs.insert(local_def(item.id), - struct_definition.ctor.is_some()); + self.structs.insert(local_def(item.id), ()); visit_item(item, new_parent, visitor); } @@ -1184,7 +1163,7 @@ impl Resolver { def_variant(item_id, local_def(variant.node.id)), variant.span); - self.structs.insert(local_def(variant.node.id), false); + self.structs.insert(local_def(variant.node.id), ()); } enum_variant_kind(enum_definition) => { (*child).define_type(privacy, @@ -1521,18 +1500,12 @@ impl Resolver { child_name_bindings.define_type(Public, def, dummy_sp()); } - def_class(def_id, has_constructor) => { + def_class(def_id) => { debug!("(building reduced graph for external \ - crate) building type %s (value? %d)", - final_ident, - if has_constructor { 1 } else { 0 }); + crate) building type %s", + final_ident); child_name_bindings.define_type(Public, def, dummy_sp()); - - if has_constructor { - child_name_bindings.define_value(Public, def, dummy_sp()); - } - - self.structs.insert(def_id, has_constructor); + self.structs.insert(def_id, ()); } def_self(*) | def_arg(*) | def_local(*) | def_prim_ty(*) | def_ty_param(*) | def_binding(*) | @@ -3307,7 +3280,6 @@ impl Resolver { struct_def.traits, struct_def.fields, struct_def.methods, - struct_def.ctor, struct_def.dtor, visitor); } @@ -3549,7 +3521,6 @@ impl Resolver { traits: ~[@trait_ref], fields: ~[@struct_field], methods: ~[@method], - optional_constructor: Option, optional_destructor: Option, visitor: ResolveVisitor) { @@ -3601,23 +3572,6 @@ impl Resolver { self.resolve_type(field.node.ty, visitor); } - // Resolve the constructor, if applicable. - match optional_constructor { - None => { - // Nothing to do. - } - Some(constructor) => { - self.resolve_function(NormalRibKind, - Some(@constructor.node.dec), - NoTypeParameters, - constructor.node.body, - HasSelfBinding(constructor.node. - self_id), - NoCaptureClause, - visitor); - } - } - // Resolve the destructor, if applicable. match optional_destructor { None => { @@ -4090,9 +4044,7 @@ impl Resolver { match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) if self.structs.contains_key(class_id) => { - let has_constructor = self.structs.get(class_id); - let class_def = def_class(class_id, - has_constructor); + let class_def = def_class(class_id); self.record_def(pattern.id, class_def); } Some(definition @ def_variant(_, variant_id)) @@ -4560,10 +4512,9 @@ impl Resolver { // let bar = Bar { ... } // no type parameters match self.resolve_path(path, TypeNS, false, visitor) { - Some(def_ty(class_id)) | Some(def_class(class_id, _)) + Some(def_ty(class_id)) | Some(def_class(class_id)) if self.structs.contains_key(class_id) => { - let has_constructor = self.structs.get(class_id); - let class_def = def_class(class_id, has_constructor); + let class_def = def_class(class_id); self.record_def(expr.id, class_def); } Some(definition @ def_variant(_, class_id)) diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index aa0f11922dd0..06d5b2f239e3 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1596,18 +1596,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 !ccx.class_ctors.contains_key(id) // hack -- - /* avoids the need for special cases to assign a type to - the constructor body (since it has no explicit return) */ - && - (body.node.expr.is_none() || - ty::type_is_bot(block_ty) || - ty::type_is_nil(block_ty)) { + if body.node.expr.is_none() || ty::type_is_bot(block_ty) || + ty::type_is_nil(block_ty) + { bcx = controlflow::trans_block(bcx, body, expr::Ignore); } else { bcx = controlflow::trans_block(bcx, body, expr::SaveIn(fcx.llretptr)); } + finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); @@ -1698,60 +1694,6 @@ fn trans_enum_variant(ccx: @crate_ctxt, finish_fn(fcx, lltop); } -fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl, - body: ast::blk, llctor_decl: ValueRef, - psubsts: param_substs, ctor_id: ast::node_id, - parent_id: ast::def_id, sp: span) { - // Add ctor to the ctor map - ccx.class_ctors.insert(ctor_id, parent_id); - - // Translate the ctor - - // Set up the type for the result of the ctor - // kludgy -- this wouldn't be necessary if the typechecker - // special-cased constructors, then we could just look up - // the ctor's return type. - let rslt_ty = ty::mk_class(ccx.tcx, parent_id, - dummy_substs(psubsts.tys)); - - // Make the fn context - let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, - Some(psubsts), Some(sp)); - let raw_llargs = create_llargs_for_fn_args(fcx, no_self, decl.inputs); - let mut bcx_top = top_scope_block(fcx, body.info()); - let lltop = bcx_top.llbb; - let arg_tys = ty::ty_fn_args(node_id_type(bcx_top, ctor_id)); - bcx_top = copy_args_to_allocas(fcx, bcx_top, decl.inputs, - raw_llargs, arg_tys); - - // Create a temporary for `self` that we will return at the end - let selfdatum = datum::scratch_datum(bcx_top, rslt_ty, true); - - // Initialize dtor flag (if any) to 1 - if ty::ty_dtor(bcx_top.tcx(), parent_id).is_some() { - let flag = GEPi(bcx_top, selfdatum.val, [0, 1]); - Store(bcx_top, C_u8(1), flag); - } - - // initialize fields to zero - let mut bcx = bcx_top; - - // note we don't want to take *or* drop self. - fcx.llself = Some(ValSelfData {v: selfdatum.val, - t: rslt_ty, - is_owned: false}); - - // Translate the body of the ctor - bcx = controlflow::trans_block(bcx, body, expr::Ignore); - - // Generate the return expression - bcx = selfdatum.move_to(bcx, datum::INIT, fcx.llretptr); - - cleanup_and_leave(bcx, None, Some(fcx.llreturn)); - Unreachable(bcx); - finish_fn(fcx, lltop); -} - fn trans_class_dtor(ccx: @crate_ctxt, path: path, body: ast::blk, dtor_id: ast::node_id, psubsts: Option, @@ -1921,14 +1863,6 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def, tps: ~[ast::ty_param], path: @ast_map::path, ident: ast::ident, id: ast::node_id) { if tps.len() == 0u { - let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps), - vtables: None, - bounds: @~[]}; - do option::iter(&struct_def.ctor) |ctor| { - trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body, - get_item_val(ccx, ctor.node.id), psubsts, - ctor.node.id, local_def(id), ctor.span); - } do option::iter(&struct_def.dtor) |dtor| { trans_class_dtor(ccx, *path, dtor.node.body, dtor.node.id, None, None, local_def(id)); @@ -2184,10 +2118,6 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { } } } - ast_map::node_ctor(nm, _, ctor, _, pt) => { - let my_path = vec::append(*pt, ~[path_name(nm)]); - register_fn(ccx, ctor.span, my_path, ctor.node.id) - } ast_map::node_dtor(_, dt, parent_id, pt) => { /* Don't just call register_fn, since we don't want to add @@ -2712,7 +2642,6 @@ fn trans_crate(sess: session::session, crate_map: crate_map, mut uses_gc: false, dbg_cx: dbg_cx, - class_ctors: HashMap(), mut do_not_commit_warning_issued: false}; diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index 68e957bfe709..b87d690a1c34 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -170,11 +170,6 @@ type crate_ctxt = { // is not emitted by LLVM's GC pass when no functions use GC. mut uses_gc: bool, dbg_cx: Option, - // Mapping from class constructors to parent class -- - // used in base::trans_closure - // parent_class must be a def_id because ctors can be - // inlined, so the parent may be in a different crate - class_ctors: HashMap, mut do_not_commit_warning_issued: bool}; // Types used for llself. diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 6cd4b49fa3b3..068ec49d6c7e 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -732,10 +732,6 @@ fn create_function(fcx: fn_ctxt) -> @metadata { ast_map::node_method(method, _, _) => { (method.ident, method.decl.output, method.id) } - ast_map::node_ctor(nm, _, ctor, _, _) => { - // FIXME: output type may be wrong (#2194) - (nm, ctor.node.dec.output, ctor.node.id) - } ast_map::node_expr(expr) => { match expr.node { ast::expr_fn(_, decl, _, _) => { diff --git a/src/rustc/middle/trans/inline.rs b/src/rustc/middle/trans/inline.rs index 76888471bf97..ce9088d4b55c 100644 --- a/src/rustc/middle/trans/inline.rs +++ b/src/rustc/middle/trans/inline.rs @@ -34,10 +34,6 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) trans_item(ccx, *item); local_def(item.id) } - csearch::found(ast::ii_ctor(ctor, _, _, _)) => { - ccx.external.insert(fn_id, Some(ctor.node.id)); - local_def(ctor.node.id) - } csearch::found(ast::ii_foreign(item)) => { ccx.external.insert(fn_id, Some(item.id)); local_def(item.id) diff --git a/src/rustc/middle/trans/monomorphize.rs b/src/rustc/middle/trans/monomorphize.rs index 87c073d567d7..914b733df198 100644 --- a/src/rustc/middle/trans/monomorphize.rs +++ b/src/rustc/middle/trans/monomorphize.rs @@ -5,7 +5,7 @@ use syntax::ast_map::{path, path_mod, path_name}; use base::{trans_item, get_item_val, no_self, self_arg, trans_fn, impl_self, decl_internal_cdecl_fn, set_inline_hint_if_appr, set_inline_hint, - trans_enum_variant, trans_class_ctor, trans_class_dtor, + trans_enum_variant, trans_class_dtor, get_insn_ctxt}; use syntax::parse::token::special_idents; use type_of::type_of_fn_from_ty; @@ -71,7 +71,6 @@ fn monomorphic_fn(ccx: @crate_ctxt, return {val: get_item_val(ccx, fn_id.node), must_cast: true}; } - ast_map::node_ctor(nm, _, ct, _, pt) => (pt, nm, ct.span), ast_map::node_dtor(_, dtor, _, pt) => (pt, special_idents::dtor, dtor.span), ast_map::node_trait_method(*) => { @@ -162,16 +161,6 @@ fn monomorphic_fn(ccx: @crate_ctxt, meth::trans_method(ccx, pt, mth, psubsts, None, d); d } - ast_map::node_ctor(_, tps, ctor, parent_id, _) => { - // ctors don't have attrs, at least not right now - let d = mk_lldecl(); - let tp_tys = ty::ty_params_to_tys(ccx.tcx, tps); - trans_class_ctor(ccx, pt, ctor.node.dec, ctor.node.body, d, - option::get_default(&psubsts, - {tys:tp_tys, vtables: None, bounds: @~[]}), - fn_id.node, parent_id, ctor.span); - d - } ast_map::node_dtor(_, dtor, _, pt) => { let parent_id = match ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx, dtor.node.self_id)) { diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 3c4439c918fb..bfb8de76a6c5 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -59,10 +59,6 @@ fn traverse_def_id(cx: ctx, did: def_id) { cx.rmap.insert(item.id, ()); } ast_map::node_variant(v, _, _) => { cx.rmap.insert(v.node.id, ()); } - // If it's a ctor, consider the parent reachable - ast_map::node_ctor(_, _, _, parent_id, _) => { - traverse_def_id(cx, parent_id); - } _ => () } } @@ -104,13 +100,6 @@ fn traverse_public_item(cx: ctx, item: @item) { } } item_class(struct_def, tps) => { - do option::iter(&struct_def.ctor) |ctor| { - cx.rmap.insert(ctor.node.id, ()); - if tps.len() > 0u || attr::find_inline_attr(ctor.node.attrs) - != attr::ia_none { - traverse_inline_body(cx, ctor.node.body); - } - } do option::iter(&struct_def.dtor) |dtor| { cx.rmap.insert(dtor.node.id, ()); if tps.len() > 0u || attr::find_inline_attr(dtor.node.attrs) diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index ee247eb5db79..1f9ad20dd03e 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -109,9 +109,6 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;} } } - ast_map::node_ctor(_, _, ctor, _, _) => { - handle_body(cx, ctor.node.body); - } ast_map::node_dtor(_, dtor, _, _) => { handle_body(cx, dtor.node.body); } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index c1195d473aa5..cc132a431a33 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -3318,7 +3318,7 @@ fn note_and_explain_type_err(cx: ctxt, err: &type_err) { fn def_has_ty_params(def: ast::def) -> bool { match def { - ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_, _) + ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_) => true, _ => false } @@ -3492,9 +3492,6 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { ast_map::path_name(variant.node.name)) } - ast_map::node_ctor(nm, _, _, _, path) => { - vec::append_one(*path, ast_map::path_name(nm)) - } ast_map::node_dtor(_, _, _, path) => { vec::append_one(*path, ast_map::path_name( syntax::parse::token::special_idents::literally_dtor)) diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 14797fcdd6bb..389c1adb016b 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -323,7 +323,7 @@ fn ast_ty_to_ty( Some(d) => d }; match a_def { - ast::def_ty(did) | ast::def_class(did, _) => { + ast::def_ty(did) | ast::def_class(did) => { ast_path_to_ty(self, rscope, did, path, id).ty } ast::def_prim_ty(nty) => { diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index bf0ca36dddf4..2bf124526ac8 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -451,18 +451,6 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def, let tcx = ccx.tcx; let self_ty = ty::node_id_to_type(tcx, id); - do option::iter(&struct_def.ctor) |ctor| { - let class_t = {self_ty: self_ty, - self_id: ctor.node.self_id, - def_id: local_def(id), - explicit_self: {node: ast::sty_by_ref, - span: ast_util::dummy_sp()}}; - // typecheck the ctor - check_bare_fn(ccx, ctor.node.dec, - ctor.node.body, ctor.node.id, - Some(class_t)); - } - do option::iter(&struct_def.dtor) |dtor| { let class_t = {self_ty: self_ty, self_id: dtor.node.self_id, @@ -1925,7 +1913,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, // Resolve the path. let class_id; match tcx.def_map.find(id) { - Some(ast::def_class(type_def_id, _)) => { + Some(ast::def_class(type_def_id)) => { class_id = type_def_id; } _ => { @@ -2411,7 +2399,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> ast::def_fn(id, _) | ast::def_static_method(id, _, _) | ast::def_const(id) | ast::def_variant(_, id) | - ast::def_class(id, _) => { + ast::def_class(id) => { return ty::lookup_item_type(fcx.ccx.tcx, id); } ast::def_upvar(_, inner, _, _) => { diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index 0b2e9c8ab3dd..24bcc2281fb9 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -325,7 +325,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { // Check to ensure that the struct is the one specified. match tcx.def_map.get(pat.id) { - ast::def_class(supplied_def_id, _) + ast::def_class(supplied_def_id) if supplied_def_id == class_id => { // OK. } diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 0a2643f6d0fe..a38e69effdff 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -497,30 +497,6 @@ fn convert_struct(ccx: @crate_ctxt, tpt: ty::ty_param_bounds_and_ty, id: ast::node_id) { let tcx = ccx.tcx; - do option::iter(&struct_def.ctor) |ctor| { - // Write the ctor type - let t_args = ctor.node.dec.inputs.map( - |a| ty_of_arg(ccx, type_rscope(rp), *a, None) ); - let t_res = ty::mk_class( - tcx, local_def(id), - {self_r: rscope::bound_self_region(rp), - self_ty: None, - tps: ty::ty_params_to_tys(tcx, tps)}); - let proto = ty::proto_vstore(ty::vstore_slice(ty::re_static)); - let t_ctor = ty::mk_fn(tcx, FnTyBase { - meta: FnMeta {purity: ast::impure_fn, - proto: proto, - bounds: @~[], - ret_style: ast::return_val}, - sig: FnSig {inputs: t_args, - output: t_res} - }); - write_ty_to_tcx(tcx, ctor.node.id, t_ctor); - tcx.tcache.insert(local_def(ctor.node.id), - {bounds: tpt.bounds, - region_param: rp, - ty: t_ctor}); - } do option::iter(&struct_def.dtor) |dtor| { // Write the dtor type diff --git a/src/test/compile-fail/cap-clause-use-after-move.rs b/src/test/compile-fail/cap-clause-use-after-move.rs index 7fb06ba5a23a..a19dfc9e9f4a 100644 --- a/src/test/compile-fail/cap-clause-use-after-move.rs +++ b/src/test/compile-fail/cap-clause-use-after-move.rs @@ -1,7 +1,5 @@ -// error-pattern:Unsatisfied precondition constraint - fn main() { let x = 5; - let _y = fn~(move x) { }; - let _z = x; //< error: Unsatisfied precondition constraint + let _y = fn~(move x) { }; //~ WARNING captured variable `x` not used in closure + let _z = x; //~ ERROR use of moved variable: `x` } diff --git a/src/test/compile-fail/issue-2590.rs b/src/test/compile-fail/issue-2590.rs index f4ccd901fb3a..0f4a4804c751 100644 --- a/src/test/compile-fail/issue-2590.rs +++ b/src/test/compile-fail/issue-2590.rs @@ -10,7 +10,7 @@ trait parse { impl parser: parse { fn parse() -> ~[int] { - dvec::unwrap(move self.tokens) //~ ERROR illegal move from self + dvec::unwrap(move self.tokens) //~ ERROR moving out of immutable field } } diff --git a/src/test/compile-fail/regions-glb-free-free.rs b/src/test/compile-fail/regions-glb-free-free.rs index 223665381da1..e4913f7056e8 100644 --- a/src/test/compile-fail/regions-glb-free-free.rs +++ b/src/test/compile-fail/regions-glb-free-free.rs @@ -19,7 +19,7 @@ mod argparse { fn set_desc(self, s: &str) -> Flag { Flag { //~ ERROR cannot infer an appropriate lifetime name: self.name, - desc: s, + desc: s, //~ ERROR cannot infer an appropriate lifetime max_count: self.max_count, value: self.value }