diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 5bb00ccb8f1..25dfb050abc 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -63,12 +63,6 @@ enum dest {
     ignore,
 }
 
-// Heap selectors. Indicate which heap something should go on.
-enum heap {
-    heap_shared,
-    heap_exchange,
-}
-
 fn dest_str(ccx: @crate_ctxt, d: dest) -> str {
     alt d {
       by_val(v) { #fmt["by_val(%s)", val_str(ccx.tn, *v)] }
@@ -398,18 +392,16 @@ fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) ->
     ret {box: box, body: body};
 }
 
-fn malloc_boxed(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
-    malloc_general_dyn(bcx, t, heap_shared,
+fn malloc_general(bcx: block, t: ty::t, heap: heap) ->
+    {box: ValueRef, body: ValueRef} {
+    malloc_general_dyn(bcx, t, heap,
                        llsize_of(bcx.ccx(), type_of(bcx.ccx(), t)))
 }
+fn malloc_boxed(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
+    malloc_general(bcx, t, heap_shared)
+}
 fn malloc_unique(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
-    malloc_general_dyn(bcx, t, heap_exchange,
-                       llsize_of(bcx.ccx(), type_of(bcx.ccx(), t)))
-}
-
-fn malloc_unique_dyn(bcx: block, t: ty::t, size: ValueRef
-                    ) -> {box: ValueRef, body: ValueRef} {
-    malloc_general_dyn(bcx, t, heap_exchange, size)
+    malloc_general(bcx, t, heap_exchange)
 }
 
 // Type descriptor and type glue stuff
@@ -1487,6 +1479,19 @@ fn trans_lit(cx: block, e: @ast::expr, lit: ast::lit, dest: dest) -> block {
     }
 }
 
+
+fn trans_boxed_expr(bcx: block, contents: @ast::expr,
+                    t: ty::t, heap: heap,
+                    dest: dest) -> block {
+    let _icx = bcx.insn_ctxt("trans_boxed_expr");
+    let {box, body} = malloc_general(bcx, t, heap);
+    add_clean_free(bcx, box, heap);
+    let bcx = trans_expr_save_in(bcx, contents, body);
+    revoke_clean(bcx, box);
+    ret store_in_dest(bcx, box, dest);
+}
+
+
 fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
                un_expr: @ast::expr, dest: dest) -> block {
     let _icx = bcx.insn_ctxt("trans_unary");
@@ -1509,35 +1514,25 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
     alt op {
       ast::not {
         let {bcx, val} = trans_temp_expr(bcx, e);
-        ret store_in_dest(bcx, Not(bcx, val), dest);
+        store_in_dest(bcx, Not(bcx, val), dest)
       }
       ast::neg {
         let {bcx, val} = trans_temp_expr(bcx, e);
         let neg = if ty::type_is_fp(e_ty) {
             FNeg(bcx, val)
         } else { Neg(bcx, val) };
-        ret store_in_dest(bcx, neg, dest);
+        store_in_dest(bcx, neg, dest)
       }
       ast::box(_) {
-        let mut {box, body} = malloc_boxed(bcx, e_ty);
-        add_clean_free(bcx, box, false);
-        // Cast the body type to the type of the value. This is needed to
-        // make enums work, since enums have a different LLVM type depending
-        // on whether they're boxed or not
-        let ccx = bcx.ccx();
-        let llety = T_ptr(type_of(ccx, e_ty));
-        body = PointerCast(bcx, body, llety);
-        let bcx = trans_expr_save_in(bcx, e, body);
-        revoke_clean(bcx, box);
-        ret store_in_dest(bcx, box, dest);
+        trans_boxed_expr(bcx, e, e_ty, heap_shared, dest)
       }
       ast::uniq(_) {
-        ret uniq::trans_uniq(bcx, e, un_expr.id, dest);
+        trans_boxed_expr(bcx, e, e_ty, heap_exchange, dest)
       }
       ast::deref {
         bcx.sess().bug("deref expressions should have been \
                                translated using trans_lval(), not \
-                               trans_unary()");
+                               trans_unary()")
       }
     }
 }
diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs
index d97d535ed8b..49bfd53a797 100644
--- a/src/rustc/middle/trans/common.rs
+++ b/src/rustc/middle/trans/common.rs
@@ -201,6 +201,12 @@ fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
     }
 }
 
+// Heap selectors. Indicate which heap something should go on.
+enum heap {
+    heap_shared,
+    heap_exchange,
+}
+
 enum cleantype {
     normal_exit_only,
     normal_exit_and_unwind
@@ -274,9 +280,11 @@ fn add_clean_temp_mem(cx: block, val: ValueRef, ty: ty::t) {
         scope_clean_changed(info);
     }
 }
-fn add_clean_free(cx: block, ptr: ValueRef, shared: bool) {
-    let free_fn = if shared { {|a|base::trans_unique_free(a, ptr)} }
-    else { {|a|base::trans_free(a, ptr)} };
+fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
+    let free_fn = alt heap {
+      heap_shared { {|a|base::trans_free(a, ptr)} }
+      heap_exchange { {|a|base::trans_unique_free(a, ptr)} }
+    };
     in_scope_cx(cx) {|info|
         vec::push(info.cleanups, clean_temp(ptr, free_fn,
                                      normal_exit_and_unwind));
diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs
index b85abbaa183..c0ed90df264 100644
--- a/src/rustc/middle/trans/impl.rs
+++ b/src/rustc/middle/trans/impl.rs
@@ -285,7 +285,7 @@ fn trans_cast(bcx: block, val: @ast::expr, id: ast::node_id, dest: dest)
     let ccx = bcx.ccx();
     let v_ty = expr_ty(bcx, val);
     let {box, body} = malloc_boxed(bcx, v_ty);
-    add_clean_free(bcx, box, false);
+    add_clean_free(bcx, box, heap_shared);
     let bcx = trans_expr_save_in(bcx, val, body);
     revoke_clean(bcx, box);
     let result = get_dest_addr(dest);
diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs
index 7bc0ca50608..4a471bd0059 100644
--- a/src/rustc/middle/trans/tvec.rs
+++ b/src/rustc/middle/trans/tvec.rs
@@ -5,8 +5,7 @@ import back::abi;
 import base::{call_memmove,
               INIT, copy_val, load_if_immediate, get_tydesc,
               sub_block, do_spill_noroot,
-              dest, bcx_icx, non_gc_box_cast,
-              heap, heap_exchange, heap_shared};
+              dest, bcx_icx, non_gc_box_cast};
 import syntax::codemap::span;
 import shape::llsize_of;
 import build::*;
@@ -167,14 +166,14 @@ fn trans_evec(bcx: block, args: [@ast::expr]/~,
           ast::vstore_uniq {
             let {bcx, val} = alloc_vec(bcx, unit_ty, args.len(),
                                        heap_exchange);
-            add_clean_free(bcx, val, true);
+            add_clean_free(bcx, val, heap_exchange);
             let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val));
             {bcx: bcx, val: val, dataptr: dataptr}
           }
           ast::vstore_box {
             let {bcx, val} = alloc_vec(bcx, unit_ty, args.len(),
                                        heap_shared);
-            add_clean_free(bcx, val, true);
+            add_clean_free(bcx, val, heap_shared);
             let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val));
             {bcx: bcx, val: val, dataptr: dataptr}
           }
diff --git a/src/rustc/middle/trans/uniq.rs b/src/rustc/middle/trans/uniq.rs
index ec4fd7680ba..e0440147f16 100644
--- a/src/rustc/middle/trans/uniq.rs
+++ b/src/rustc/middle/trans/uniq.rs
@@ -5,19 +5,7 @@ import build::*;
 import base::*;
 import shape::llsize_of;
 
-export trans_uniq, make_free_glue, autoderef, duplicate;
-
-fn trans_uniq(bcx: block, contents: @ast::expr,
-              node_id: ast::node_id, dest: dest) -> block {
-    let _icx = bcx.insn_ctxt("uniq::trans_uniq");
-    let uniq_ty = node_id_type(bcx, node_id);
-    let contents_ty = content_ty(uniq_ty);
-    let {box, body} = malloc_unique(bcx, contents_ty);
-    add_clean_free(bcx, box, true);
-    let bcx = trans_expr_save_in(bcx, contents, body);
-    revoke_clean(bcx, box);
-    ret store_in_dest(bcx, box, dest);
-}
+export make_free_glue, autoderef, duplicate;
 
 fn make_free_glue(bcx: block, vptr: ValueRef, t: ty::t)
     -> block {
@@ -64,4 +52,4 @@ fn duplicate(bcx: block, v: ValueRef, t: ty::t) -> result {
     Store(bcx, td, dst_tydesc_ptr);
 
     ret rslt(bcx, dst_box);
-}
\ No newline at end of file
+}