about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-09-03 15:56:57 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-09-03 15:59:10 -0700
commit5573ad723fc73197889f5890dc9846ba107757d9 (patch)
treead26e83a045d6948f568961e8e1979f469fe5948 /src
parente767011b77c654d0a926e752de216661bc5b2c22 (diff)
rustc: Fix an LLVM assertion that tripped when borrowing a by-val method receiver.
In certain lvalue code paths, the type of the borrowed value was not
being used to generate temporary spills. I'm a bit surprised we didn't
hit this sooner.
Diffstat (limited to 'src')
-rw-r--r--src/rustc/middle/trans/base.rs14
-rw-r--r--src/test/run-pass/borrow-by-val-method-receiver.rs13
2 files changed, 20 insertions, 7 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 49d626cce96..43895577132 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -3112,24 +3112,24 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
 
           ast::by_copy | ast::by_move => {
             // Ensure that an owned copy of the value is in memory:
-            let alloc = alloc_ty(bcx, arg.ty);
+            let alloc = alloc_ty(bcx, e_ty);
             let move_out = arg_mode == ast::by_move ||
                 ccx.maps.last_use_map.contains_key(e.id);
             if lv.kind == lv_temporary { revoke_clean(bcx, val); }
-            if lv.kind == lv_owned || !ty::type_is_immediate(arg.ty) {
-                memmove_ty(bcx, alloc, val, arg.ty);
-                if move_out && ty::type_needs_drop(ccx.tcx, arg.ty) {
-                    bcx = zero_mem(bcx, val, arg.ty);
+            if lv.kind == lv_owned || !ty::type_is_immediate(e_ty) {
+                memmove_ty(bcx, alloc, val, e_ty);
+                if move_out && ty::type_needs_drop(ccx.tcx, e_ty) {
+                    bcx = zero_mem(bcx, val, e_ty);
                 }
             } else { Store(bcx, val, alloc); }
             val = alloc;
             if lv.kind != lv_temporary && !move_out {
-                bcx = take_ty(bcx, val, arg.ty);
+                bcx = take_ty(bcx, val, e_ty);
             }
 
             // In the event that failure occurs before the call actually
             // happens, have to cleanup this copy:
-            add_clean_temp_mem(bcx, val, arg.ty);
+            add_clean_temp_mem(bcx, val, e_ty);
             vec::push(temp_cleanups, val);
           }
         }
diff --git a/src/test/run-pass/borrow-by-val-method-receiver.rs b/src/test/run-pass/borrow-by-val-method-receiver.rs
new file mode 100644
index 00000000000..dbfb0d1ddc0
--- /dev/null
+++ b/src/test/run-pass/borrow-by-val-method-receiver.rs
@@ -0,0 +1,13 @@
+trait Foo {
+    fn foo(self);
+}
+
+impl &[int]: Foo {
+    fn foo(self) {}
+}
+
+fn main() {
+    let items = ~[ 3, 5, 1, 2, 4 ];
+    items.foo();
+}
+