From 87d57e4919a8f0d76a0d100a3003a26dffa4303a Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 8 Jun 2012 14:37:55 -0700 Subject: [PATCH] Don't treat all class fields as mutable, except in trans Closes #2550 --- src/rustc/middle/trans/base.rs | 10 ++++++---- src/rustc/middle/trans/shape.rs | 2 +- src/rustc/middle/ty.rs | 23 +++++++++++++++++++++-- src/test/run-pass/issue-2550.rs | 15 +++++++++++++++ 4 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/issue-2550.rs diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 84fd0f1947e..2a8e2720893 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -776,7 +776,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id, let args = [bcx.fcx.llretptr, self_arg]; Call(bcx, dtor_addr, args); // Drop the fields - for vec::eachi(ty::class_items_as_fields(bcx.tcx(), class_did, substs)) + for vec::eachi(ty::class_items_as_mutable_fields(bcx.tcx(), class_did, + substs)) {|i, fld| let llfld_a = GEPi(bcx, classptr, [0u, i]); bcx = drop_ty(bcx, llfld_a, fld.mt.ty); @@ -1114,7 +1115,8 @@ fn iter_variant(cx: block, a_tup: ValueRef, ret next_cx; } ty::ty_class(did, substs) { - for vec::eachi(ty::class_items_as_fields(cx.tcx(), did, substs)) + for vec::eachi(ty::class_items_as_mutable_fields(cx.tcx(), did, + substs)) {|i, fld| let llfld_a = GEPi(cx, av, [0u, i]); cx = f(cx, llfld_a, fld.mt.ty); @@ -2523,7 +2525,7 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t, if option::is_some(ty::ty_dtor(bcx.tcx(), did)) { deref = true; } - ty::class_items_as_fields(bcx.tcx(), did, substs) + ty::class_items_as_mutable_fields(bcx.tcx(), did, substs) } // Constraint? _ { bcx.tcx().sess.span_bug(sp, "trans_rec_field:\ @@ -4815,7 +4817,7 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl, else { selfptr }; // initialize fields to zero - let fields = ty::class_items_as_fields(bcx_top.tcx(), parent_id, + let fields = ty::class_items_as_mutable_fields(bcx_top.tcx(), parent_id, dummy_substs(psubsts.tys)); let mut bcx = bcx_top; // Initialize fields to zero so init assignments can validly diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index 7be5bfe2c68..7ac885422a1 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -351,7 +351,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] { add_substr(s, shape_of(ccx, tp)); } }; - for ty::class_items_as_fields(ccx.tcx, did, substs).each {|f| + for ty::class_items_as_mutable_fields(ccx.tcx, did, substs).each {|f| sub += shape_of(ccx, f.mt.ty); } add_substr(s, sub); diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 998e5a61666..bbbdafa6a7a 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -26,7 +26,7 @@ export args_eq; export ast_constr_to_constr; export block_ty; -export class_items_as_fields; +export class_items_as_fields, class_items_as_mutable_fields; export constr; export constr_general; export constr_table; @@ -2864,15 +2864,34 @@ fn class_field_tys(items: [@class_member]) -> [field_ty] { // Return a list of fields corresponding to the class's items // (as if the class was a record). trans uses this // Takes a list of substs with which to instantiate field types +// Keep in mind that this function reports that all fields are +// mutable, regardless of how they were declared. It's meant to +// be used in trans. +fn class_items_as_mutable_fields(cx:ctxt, did: ast::def_id, + substs: substs) -> [field] { + class_item_fields(cx, did, substs, {|_mt| m_mutbl}) +} + +// Same as class_items_as_mutable_fields, but doesn't change +// mutability. fn class_items_as_fields(cx:ctxt, did: ast::def_id, substs: substs) -> [field] { + class_item_fields(cx, did, substs, {|mt| alt mt { + class_mutable { m_mutbl } + class_immutable { m_imm }}}) +} + + +fn class_item_fields(cx:ctxt, did: ast::def_id, + substs: substs, frob_mutability: fn(class_mutability) -> mutability) + -> [field] { let mut rslt = []; for lookup_class_fields(cx, did).each {|f| // consider all instance vars mut, because the // constructor may mutate all vars rslt += [{ident: f.ident, mt: {ty: lookup_field_type(cx, did, f.id, substs), - mutbl: m_mutbl}}]; + mutbl: frob_mutability(f.mutability)}}]; } rslt } diff --git a/src/test/run-pass/issue-2550.rs b/src/test/run-pass/issue-2550.rs new file mode 100644 index 00000000000..103d8589f3b --- /dev/null +++ b/src/test/run-pass/issue-2550.rs @@ -0,0 +1,15 @@ +class C { + let x: uint; + + new(x: uint) { + self.x = x; + } +} + +fn f(_x: T) { +} + +#[warn(err_non_implicitly_copyable_typarams)] +fn main() { + f(C(1u)); +} -- GitLab