Skip to content

Commit 87d57e4

Browse files
committed
Don't treat all class fields as mutable, except in trans
Closes #2550
1 parent 75adeaa commit 87d57e4

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id,
776776
let args = [bcx.fcx.llretptr, self_arg];
777777
Call(bcx, dtor_addr, args);
778778
// Drop the fields
779-
for vec::eachi(ty::class_items_as_fields(bcx.tcx(), class_did, substs))
779+
for vec::eachi(ty::class_items_as_mutable_fields(bcx.tcx(), class_did,
780+
substs))
780781
{|i, fld|
781782
let llfld_a = GEPi(bcx, classptr, [0u, i]);
782783
bcx = drop_ty(bcx, llfld_a, fld.mt.ty);
@@ -1114,7 +1115,8 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
11141115
ret next_cx;
11151116
}
11161117
ty::ty_class(did, substs) {
1117-
for vec::eachi(ty::class_items_as_fields(cx.tcx(), did, substs))
1118+
for vec::eachi(ty::class_items_as_mutable_fields(cx.tcx(), did,
1119+
substs))
11181120
{|i, fld|
11191121
let llfld_a = GEPi(cx, av, [0u, i]);
11201122
cx = f(cx, llfld_a, fld.mt.ty);
@@ -2523,7 +2525,7 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
25232525
if option::is_some(ty::ty_dtor(bcx.tcx(), did)) {
25242526
deref = true;
25252527
}
2526-
ty::class_items_as_fields(bcx.tcx(), did, substs)
2528+
ty::class_items_as_mutable_fields(bcx.tcx(), did, substs)
25272529
}
25282530
// Constraint?
25292531
_ { 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,
48154817
else { selfptr };
48164818

48174819
// initialize fields to zero
4818-
let fields = ty::class_items_as_fields(bcx_top.tcx(), parent_id,
4820+
let fields = ty::class_items_as_mutable_fields(bcx_top.tcx(), parent_id,
48194821
dummy_substs(psubsts.tys));
48204822
let mut bcx = bcx_top;
48214823
// Initialize fields to zero so init assignments can validly

src/rustc/middle/trans/shape.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
351351
add_substr(s, shape_of(ccx, tp));
352352
}
353353
};
354-
for ty::class_items_as_fields(ccx.tcx, did, substs).each {|f|
354+
for ty::class_items_as_mutable_fields(ccx.tcx, did, substs).each {|f|
355355
sub += shape_of(ccx, f.mt.ty);
356356
}
357357
add_substr(s, sub);

src/rustc/middle/ty.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export arg;
2626
export args_eq;
2727
export ast_constr_to_constr;
2828
export block_ty;
29-
export class_items_as_fields;
29+
export class_items_as_fields, class_items_as_mutable_fields;
3030
export constr;
3131
export constr_general;
3232
export constr_table;
@@ -2864,15 +2864,34 @@ fn class_field_tys(items: [@class_member]) -> [field_ty] {
28642864
// Return a list of fields corresponding to the class's items
28652865
// (as if the class was a record). trans uses this
28662866
// Takes a list of substs with which to instantiate field types
2867+
// Keep in mind that this function reports that all fields are
2868+
// mutable, regardless of how they were declared. It's meant to
2869+
// be used in trans.
2870+
fn class_items_as_mutable_fields(cx:ctxt, did: ast::def_id,
2871+
substs: substs) -> [field] {
2872+
class_item_fields(cx, did, substs, {|_mt| m_mutbl})
2873+
}
2874+
2875+
// Same as class_items_as_mutable_fields, but doesn't change
2876+
// mutability.
28672877
fn class_items_as_fields(cx:ctxt, did: ast::def_id,
28682878
substs: substs) -> [field] {
2879+
class_item_fields(cx, did, substs, {|mt| alt mt {
2880+
class_mutable { m_mutbl }
2881+
class_immutable { m_imm }}})
2882+
}
2883+
2884+
2885+
fn class_item_fields(cx:ctxt, did: ast::def_id,
2886+
substs: substs, frob_mutability: fn(class_mutability) -> mutability)
2887+
-> [field] {
28692888
let mut rslt = [];
28702889
for lookup_class_fields(cx, did).each {|f|
28712890
// consider all instance vars mut, because the
28722891
// constructor may mutate all vars
28732892
rslt += [{ident: f.ident, mt:
28742893
{ty: lookup_field_type(cx, did, f.id, substs),
2875-
mutbl: m_mutbl}}];
2894+
mutbl: frob_mutability(f.mutability)}}];
28762895
}
28772896
rslt
28782897
}

src/test/run-pass/issue-2550.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class C {
2+
let x: uint;
3+
4+
new(x: uint) {
5+
self.x = x;
6+
}
7+
}
8+
9+
fn f<T:copy>(_x: T) {
10+
}
11+
12+
#[warn(err_non_implicitly_copyable_typarams)]
13+
fn main() {
14+
f(C(1u));
15+
}

0 commit comments

Comments
 (0)