about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/rustc/middle/trans/base.rs10
-rw-r--r--src/rustc/middle/trans/shape.rs2
-rw-r--r--src/rustc/middle/ty.rs23
-rw-r--r--src/test/run-pass/issue-2550.rs15
4 files changed, 43 insertions, 7 deletions
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_structural_ty(cx: block, av: ValueRef, t: ty::t,
         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 arg;
 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<T:copy>(_x: T) {
+}
+
+#[warn(err_non_implicitly_copyable_typarams)]
+fn main() {
+    f(C(1u));
+}