about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-06 05:46:38 -0700
committerbors <bors@rust-lang.org>2014-04-06 05:46:38 -0700
commit4af69f204e2365da0dc9f32bbd0eb3201dc9a9e0 (patch)
tree203192e4ad78551953590942bb0df3b45c37d27a
parentf1f50565a1fda0dfd60d89fea65e2328f42cc5e0 (diff)
parent2d22243b0c582574394da7e3d8aaf8b2abf2c147 (diff)
downloadrust-4af69f204e2365da0dc9f32bbd0eb3201dc9a9e0.tar.gz
rust-4af69f204e2365da0dc9f32bbd0eb3201dc9a9e0.zip
auto merge of #13344 : eddyb/rust/kill-unboxed-vec, r=cmr
Removes the special `ty_unboxed_vec` type from the type system.
It was previously used only during translating `~[T]`/`~str` allocation and drop glue.
-rw-r--r--src/librustc/metadata/tydecode.rs1
-rw-r--r--src/librustc/metadata/tyencode.rs1
-rw-r--r--src/librustc/middle/check_match.rs8
-rw-r--r--src/librustc/middle/trans/_match.rs7
-rw-r--r--src/librustc/middle/trans/base.rs151
-rw-r--r--src/librustc/middle/trans/cleanup.rs15
-rw-r--r--src/librustc/middle/trans/closure.rs7
-rw-r--r--src/librustc/middle/trans/common.rs8
-rw-r--r--src/librustc/middle/trans/expr.rs121
-rw-r--r--src/librustc/middle/trans/glue.rs11
-rw-r--r--src/librustc/middle/trans/reflect.rs5
-rw-r--r--src/librustc/middle/trans/tvec.rs159
-rw-r--r--src/librustc/middle/trans/type_of.rs7
-rw-r--r--src/librustc/middle/ty.rs35
-rw-r--r--src/librustc/middle/ty_fold.rs3
-rw-r--r--src/librustc/middle/typeck/check/_match.rs3
-rw-r--r--src/librustc/middle/typeck/check/method.rs2
-rw-r--r--src/librustc/middle/typeck/coherence.rs7
-rw-r--r--src/librustc/middle/typeck/variance.rs2
-rw-r--r--src/librustc/util/ppaux.rs3
-rw-r--r--src/libstd/intrinsics.rs2
-rw-r--r--src/libstd/reflect.rs14
-rw-r--r--src/libstd/repr.rs9
-rw-r--r--src/test/run-pass/reflect-visit-type.rs2
24 files changed, 208 insertions, 375 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 409957b8625..73fc089d930 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -349,7 +349,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         let mt = parse_mt(st, |x,y| conv(x,y));
         return ty::mk_rptr(st.tcx, r, mt);
       }
-      'U' => return ty::mk_unboxed_vec(st.tcx, parse_mt(st, |x,y| conv(x,y))),
       'V' => {
         let mt = parse_mt(st, |x,y| conv(x,y));
         let v = parse_vstore(st, |x,y| conv(x,y));
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 4053db72a28..384c6907aed 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -298,7 +298,6 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
             mywrite!(w, "v");
             enc_vstore(w, cx, v);
         }
-        ty::ty_unboxed_vec(mt) => { mywrite!(w, "U"); enc_mt(w, cx, mt); }
         ty::ty_closure(ref f) => {
             mywrite!(w, "f");
             enc_closure_ty(w, cx, *f);
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index c4cb76620bf..e18f8f530ee 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -191,7 +191,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, pats: Vec<@Pat> ) {
                         }
                     }
                 }
-                ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
+                ty::ty_vec(..) => {
                     match *ctor {
                         vec(n) => Some(format!("vectors of length {}", n)),
                         _ => None
@@ -282,7 +282,7 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
               ty::ty_vec(_, ty::vstore_fixed(n)) => {
                 is_useful_specialized(cx, m, v, vec(n), n, left_ty)
               }
-              ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
+              ty::ty_vec(..) => {
                 let max_len = m.iter().rev().fold(0, |max_len, r| {
                   match r.get(0).node {
                     PatVec(ref before, _, ref after) => {
@@ -464,7 +464,7 @@ fn missing_ctor(cx: &MatchCheckCtxt,
           _         => None
         }
       }
-      ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
+      ty::ty_vec(..) => {
 
         // Find the lengths and slices of all vector patterns.
         let mut vec_pat_lens = m.iter().filter_map(|r| {
@@ -529,7 +529,7 @@ fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
         }
       }
       ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
-      ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
+      ty::ty_vec(..) => {
         match *ctor {
           vec(n) => n,
           _ => 0u
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index b27c46dae8c..c4fe5a3ebbb 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -1088,7 +1088,8 @@ fn extract_vec_elems<'a>(
     let _icx = push_ctxt("match::extract_vec_elems");
     let vec_datum = match_datum(bcx, val, pat_id);
     let (base, len) = vec_datum.get_vec_base_and_len(bcx);
-    let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
+    let vec_ty = node_id_type(bcx, pat_id);
+    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
 
     let mut elems = Vec::from_fn(elem_count, |i| {
         match slice {
@@ -1681,8 +1682,8 @@ fn compile_submatch_continue<'r,
                 kind = compare;
             },
             vec_len(..) => {
-                let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
-                let (_, len) = tvec::get_base_and_len(bcx, val, vt.vec_ty);
+                let vec_ty = node_id_type(bcx, pat_id);
+                let (_, len) = tvec::get_base_and_len(bcx, val, vec_ty);
                 test_val = len;
                 kind = compare_vec_len;
             }
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 8b176330a89..e48b8fc9db4 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -37,7 +37,6 @@ use lib;
 use metadata::{csearch, encoder};
 use middle::astencode;
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
-use middle::lang_items::{MallocFnLangItem, ClosureExchangeMallocFnLangItem};
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::build::*;
@@ -336,111 +335,64 @@ pub fn at_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef) -> ValueRef {
     GEPi(bcx, boxptr, [0u, abi::box_field_body])
 }
 
-// malloc_raw_dyn: allocates a box to contain a given type, but with a
-// potentially dynamic size.
-pub fn malloc_raw_dyn<'a>(
-                      bcx: &'a Block<'a>,
-                      t: ty::t,
-                      heap: heap,
-                      size: ValueRef)
-                      -> Result<'a> {
-    let _icx = push_ctxt("malloc_raw");
-    let ccx = bcx.ccx();
-
-    fn require_alloc_fn(bcx: &Block, t: ty::t, it: LangItem) -> ast::DefId {
-        let li = &bcx.tcx().lang_items;
-        match li.require(it) {
-            Ok(id) => id,
-            Err(s) => {
-                bcx.sess().fatal(format!("allocation of `{}` {}",
-                                         bcx.ty_to_str(t), s));
-            }
+fn require_alloc_fn(bcx: &Block, info_ty: ty::t, it: LangItem) -> ast::DefId {
+    match bcx.tcx().lang_items.require(it) {
+        Ok(id) => id,
+        Err(s) => {
+            bcx.sess().fatal(format!("allocation of `{}` {}",
+                                     bcx.ty_to_str(info_ty), s));
         }
     }
+}
 
-    if heap == heap_exchange {
-        let llty_value = type_of::type_of(ccx, t);
-
-        // Allocate space:
-        let r = callee::trans_lang_call(
-            bcx,
-            require_alloc_fn(bcx, t, ExchangeMallocFnLangItem),
-            [size],
-            None);
-        rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to()))
-    } else {
-        // we treat ~fn as @ here, which isn't ideal
-        let langcall = match heap {
-            heap_managed => {
-                require_alloc_fn(bcx, t, MallocFnLangItem)
-            }
-            heap_exchange_closure => {
-                require_alloc_fn(bcx, t, ClosureExchangeMallocFnLangItem)
-            }
-            _ => fail!("heap_exchange already handled")
-        };
+// The following malloc_raw_dyn* functions allocate a box to contain
+// a given type, but with a potentially dynamic size.
 
-        // Grab the TypeRef type of box_ptr_ty.
-        let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
-        let llty = type_of(ccx, box_ptr_ty);
-        let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);
-
-        // Allocate space:
-        let drop_glue = glue::get_drop_glue(ccx, t);
-        let r = callee::trans_lang_call(
-            bcx,
-            langcall,
-            [
-                PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
-                size,
-                llalign
-            ],
-            None);
-        rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
-    }
-}
-
-// malloc_raw: expects an unboxed type and returns a pointer to
-// enough space for a box of that type.  This includes a rust_opaque_box
-// header.
-pub fn malloc_raw<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap)
-                  -> Result<'a> {
-    let ty = type_of(bcx.ccx(), t);
-    let size = llsize_of(bcx.ccx(), ty);
-    malloc_raw_dyn(bcx, t, heap, size)
-}
-
-pub struct MallocResult<'a> {
-    pub bcx: &'a Block<'a>,
-    pub smart_ptr: ValueRef,
-    pub body: ValueRef
-}
-
-// malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a smart
-// pointer, and pulls out the body
-pub fn malloc_general_dyn<'a>(
-                          bcx: &'a Block<'a>,
-                          t: ty::t,
-                          heap: heap,
+pub fn malloc_raw_dyn<'a>(bcx: &'a Block<'a>,
+                          ptr_ty: ty::t,
                           size: ValueRef)
-                          -> MallocResult<'a> {
-    assert!(heap != heap_exchange);
-    let _icx = push_ctxt("malloc_general");
-    let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
-    let body = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+                          -> Result<'a> {
+    let _icx = push_ctxt("malloc_raw_exchange");
+    let ccx = bcx.ccx();
 
-    MallocResult {
-        bcx: bcx,
-        smart_ptr: llbox,
-        body: body,
-    }
+    // Allocate space:
+    let r = callee::trans_lang_call(bcx,
+        require_alloc_fn(bcx, ptr_ty, ExchangeMallocFnLangItem),
+        [size],
+        None);
+
+    let llty_ptr = type_of::type_of(ccx, ptr_ty);
+    rslt(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
 }
 
-pub fn malloc_general<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap)
-                      -> MallocResult<'a> {
-    let ty = type_of(bcx.ccx(), t);
-    assert!(heap != heap_exchange);
-    malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
+pub fn malloc_raw_dyn_managed<'a>(
+                      bcx: &'a Block<'a>,
+                      t: ty::t,
+                      alloc_fn: LangItem,
+                      size: ValueRef)
+                      -> Result<'a> {
+    let _icx = push_ctxt("malloc_raw_managed");
+    let ccx = bcx.ccx();
+
+    let langcall = require_alloc_fn(bcx, t, alloc_fn);
+
+    // Grab the TypeRef type of box_ptr_ty.
+    let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
+    let llty = type_of(ccx, box_ptr_ty);
+    let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);
+
+    // Allocate space:
+    let drop_glue = glue::get_drop_glue(ccx, t);
+    let r = callee::trans_lang_call(
+        bcx,
+        langcall,
+        [
+            PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
+            size,
+            llalign
+        ],
+        None);
+    rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
 }
 
 // Type descriptor and type glue stuff
@@ -708,7 +660,8 @@ pub fn iter_structural_ty<'r,
       ty::ty_str(ty::vstore_fixed(_)) |
       ty::ty_vec(_, ty::vstore_fixed(_)) => {
         let (base, len) = tvec::get_base_and_byte_len(cx, av, t);
-        cx = tvec::iter_vec_raw(cx, base, t, len, f);
+        let unit_ty = ty::sequence_element_type(cx.tcx(), t);
+        cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
       }
       ty::ty_tup(ref args) => {
           let repr = adt::represent_type(cx.ccx(), t);
diff --git a/src/librustc/middle/trans/cleanup.rs b/src/librustc/middle/trans/cleanup.rs
index 06869d50fc4..1672e1f74eb 100644
--- a/src/librustc/middle/trans/cleanup.rs
+++ b/src/librustc/middle/trans/cleanup.rs
@@ -278,7 +278,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
     fn schedule_free_value(&self,
                            cleanup_scope: ScopeId,
                            val: ValueRef,
-                           heap: common::heap) {
+                           heap: Heap) {
         /*!
          * Schedules a call to `free(val)`. Note that this is a shallow
          * operation.
@@ -814,9 +814,14 @@ impl Cleanup for DropValue {
     }
 }
 
+pub enum Heap {
+    HeapManaged,
+    HeapExchange
+}
+
 pub struct FreeValue {
     ptr: ValueRef,
-    heap: common::heap,
+    heap: Heap,
 }
 
 impl Cleanup for FreeValue {
@@ -826,10 +831,10 @@ impl Cleanup for FreeValue {
 
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
         match self.heap {
-            common::heap_managed => {
+            HeapManaged => {
                 glue::trans_free(bcx, self.ptr)
             }
-            common::heap_exchange | common::heap_exchange_closure => {
+            HeapExchange => {
                 glue::trans_exchange_free(bcx, self.ptr)
             }
         }
@@ -901,7 +906,7 @@ pub trait CleanupMethods<'a> {
     fn schedule_free_value(&self,
                            cleanup_scope: ScopeId,
                            val: ValueRef,
-                           heap: common::heap);
+                           heap: Heap);
     fn schedule_clean(&self,
                       cleanup_scope: ScopeId,
                       cleanup: ~Cleanup);
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 4671e21170e..8fbaa238754 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -13,6 +13,7 @@ use back::abi;
 use back::link::mangle_internal_name_by_path_and_seq;
 use driver::session::FullDebugInfo;
 use lib::llvm::ValueRef;
+use middle::lang_items::ClosureExchangeMallocFnLangItem;
 use middle::moves;
 use middle::trans::base::*;
 use middle::trans::build::*;
@@ -20,6 +21,7 @@ use middle::trans::common::*;
 use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
 use middle::trans::debuginfo;
 use middle::trans::expr;
+use middle::trans::machine::llsize_of;
 use middle::trans::type_of::*;
 use middle::trans::type_::Type;
 use middle::ty;
@@ -168,7 +170,10 @@ fn allocate_cbox<'a>(bcx: &'a Block<'a>,
             tcx.sess.bug("trying to trans allocation of @fn")
         }
         ast::OwnedSigil => {
-            malloc_raw(bcx, cdata_ty, heap_exchange_closure)
+            let ty = type_of(bcx.ccx(), cdata_ty);
+            let size = llsize_of(bcx.ccx(), ty);
+            // we treat proc as @ here, which isn't ideal
+            malloc_raw_dyn_managed(bcx, cdata_ty, ClosureExchangeMallocFnLangItem, size)
         }
         ast::BorrowedSigil => {
             let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index fc50e57f2c9..d03b13b1b8f 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -386,14 +386,6 @@ impl<'a> FunctionContext<'a> {
     }
 }
 
-// Heap selectors. Indicate which heap something should go on.
-#[deriving(Eq)]
-pub enum heap {
-    heap_managed,
-    heap_exchange,
-    heap_exchange_closure
-}
-
 // Basic block context.  We create a block context for each basic block
 // (single-entry, single-exit sequence of instructions) we generate from Rust
 // code.  Each basic block we generate is attached to a function, typically
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 49a4a3ed25c..95bf2a7f275 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -37,6 +37,7 @@ use back::abi;
 use lib::llvm::{ValueRef, llvm};
 use lib;
 use metadata::csearch;
+use middle::lang_items::MallocFnLangItem;
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::asm;
@@ -426,8 +427,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
             // `trans_rvalue_dps_unadjusted`.)
             let box_ty = expr_ty(bcx, expr);
             let contents_ty = expr_ty(bcx, contents);
-            let heap = heap_exchange;
-            return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
+            trans_uniq_expr(bcx, box_ty, contents, contents_ty)
         }
         ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()),
         ast::ExprBinary(op, lhs, rhs) => {
@@ -504,7 +504,7 @@ fn trans_index<'a>(bcx: &'a Block<'a>,
         }
     };
 
-    let vt = tvec::vec_types(bcx, base_datum.ty);
+    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), base_datum.ty));
     base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
 
     let (base, len) = base_datum.get_vec_base_and_len(bcx);
@@ -1175,10 +1175,10 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
             immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock()
         }
         ast::UnBox => {
-            trans_boxed_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr), heap_managed)
+            trans_managed_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr))
         }
         ast::UnUniq => {
-            trans_boxed_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr), heap_exchange)
+            trans_uniq_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr))
         }
         ast::UnDeref => {
             let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
@@ -1187,42 +1187,52 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
     }
 }
 
-fn trans_boxed_expr<'a>(bcx: &'a Block<'a>,
-                        box_ty: ty::t,
-                        contents: &ast::Expr,
-                        contents_ty: ty::t,
-                        heap: heap)
+fn trans_uniq_expr<'a>(bcx: &'a Block<'a>,
+                       box_ty: ty::t,
+                       contents: &ast::Expr,
+                       contents_ty: ty::t)
                         -> DatumBlock<'a, Expr> {
-    let _icx = push_ctxt("trans_boxed_expr");
+    let _icx = push_ctxt("trans_uniq_expr");
     let fcx = bcx.fcx;
-    if heap == heap_exchange {
-        let llty = type_of::type_of(bcx.ccx(), contents_ty);
-        let size = llsize_of(bcx.ccx(), llty);
-        let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
-                                                           heap_exchange, size);
-        // Unique boxes do not allocate for zero-size types. The standard library may assume
-        // that `free` is never called on the pointer returned for `~ZeroSizeType`.
-        if llsize_of_alloc(bcx.ccx(), llty) == 0 {
-            let bcx = trans_into(bcx, contents, SaveIn(val));
-            immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
-        } else {
-            let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
-            fcx.schedule_free_value(cleanup::CustomScope(custom_cleanup_scope),
-                                    val, heap_exchange);
-            let bcx = trans_into(bcx, contents, SaveIn(val));
-            fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
-            immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
-        }
+    let llty = type_of::type_of(bcx.ccx(), contents_ty);
+    let size = llsize_of(bcx.ccx(), llty);
+    // We need to a make a pointer type because box_ty is ty_bot
+    // if content_ty is, e.g. ~fail!().
+    let real_box_ty = ty::mk_uniq(bcx.tcx(), contents_ty);
+    let Result { bcx, val } = malloc_raw_dyn(bcx, real_box_ty, size);
+    // Unique boxes do not allocate for zero-size types. The standard library may assume
+    // that `free` is never called on the pointer returned for `~ZeroSizeType`.
+    let bcx = if llsize_of_alloc(bcx.ccx(), llty) == 0 {
+        trans_into(bcx, contents, SaveIn(val))
     } else {
-        let base::MallocResult { bcx, smart_ptr: bx, body } =
-            base::malloc_general(bcx, contents_ty, heap);
         let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
         fcx.schedule_free_value(cleanup::CustomScope(custom_cleanup_scope),
-                                bx, heap);
-        let bcx = trans_into(bcx, contents, SaveIn(body));
+                                val, cleanup::HeapExchange);
+        let bcx = trans_into(bcx, contents, SaveIn(val));
         fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
-        immediate_rvalue_bcx(bcx, bx, box_ty).to_expr_datumblock()
-    }
+        bcx
+    };
+    immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
+}
+
+fn trans_managed_expr<'a>(bcx: &'a Block<'a>,
+                          box_ty: ty::t,
+                          contents: &ast::Expr,
+                          contents_ty: ty::t)
+                          -> DatumBlock<'a, Expr> {
+    let _icx = push_ctxt("trans_managed_expr");
+    let fcx = bcx.fcx;
+    let ty = type_of::type_of(bcx.ccx(), contents_ty);
+    let Result {bcx, val: bx} = malloc_raw_dyn_managed(bcx, contents_ty, MallocFnLangItem,
+                                                        llsize_of(bcx.ccx(), ty));
+    let body = GEPi(bcx, bx, [0u, abi::box_field_body]);
+
+    let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
+    fcx.schedule_free_value(cleanup::CustomScope(custom_cleanup_scope),
+                            bx, cleanup::HeapManaged);
+    let bcx = trans_into(bcx, contents, SaveIn(body));
+    fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
+    immediate_rvalue_bcx(bcx, bx, box_ty).to_expr_datumblock()
 }
 
 fn trans_addr_of<'a>(bcx: &'a Block<'a>,
@@ -1243,31 +1253,22 @@ fn trans_gc<'a>(mut bcx: &'a Block<'a>,
                 -> &'a Block<'a> {
     let contents_ty = expr_ty(bcx, contents);
     let box_ty = ty::mk_box(bcx.tcx(), contents_ty);
-    let expr_ty = expr_ty(bcx, expr);
 
-    let addr = match dest {
-        Ignore => {
-            return trans_boxed_expr(bcx,
-                                    box_ty,
-                                    contents,
-                                    contents_ty,
-                                    heap_managed).bcx
-        }
-        SaveIn(addr) => addr,
-    };
+    let contents_datum = unpack_datum!(bcx, trans_managed_expr(bcx,
+                                                               box_ty,
+                                                               contents,
+                                                               contents_ty));
 
-    let repr = adt::represent_type(bcx.ccx(), expr_ty);
-    adt::trans_start_init(bcx, repr, addr, 0);
-    let field_dest = adt::trans_field_ptr(bcx, repr, addr, 0, 0);
-    let contents_datum = unpack_datum!(bcx, trans_boxed_expr(bcx,
-                                                             box_ty,
-                                                             contents,
-                                                             contents_ty,
-                                                             heap_managed));
-    bcx = contents_datum.store_to(bcx, field_dest);
-
-    // Next, wrap it up in the struct.
-    bcx
+    match dest {
+        Ignore => bcx,
+        SaveIn(addr) => {
+            let expr_ty = expr_ty(bcx, expr);
+            let repr = adt::represent_type(bcx.ccx(), expr_ty);
+            adt::trans_start_init(bcx, repr, addr, 0);
+            let field_dest = adt::trans_field_ptr(bcx, repr, addr, 0, 0);
+            contents_datum.store_to(bcx, field_dest)
+        }
+    }
 }
 
 // Important to get types for both lhs and rhs, because one might be _|_
@@ -1801,11 +1802,11 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
             RvalueExpr(Rvalue { mode: ByRef }) => {
                 let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
                 let ptr = Load(bcx, datum.val);
-                bcx.fcx.schedule_free_value(scope, ptr, heap_exchange);
+                bcx.fcx.schedule_free_value(scope, ptr, cleanup::HeapExchange);
             }
             RvalueExpr(Rvalue { mode: ByValue }) => {
                 let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
-                bcx.fcx.schedule_free_value(scope, datum.val, heap_exchange);
+                bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange);
             }
             LvalueExpr => { }
         }
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 3ed7a4caf70..5aee8b64848 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -290,10 +290,13 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
             })
         }
         ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
-            make_drop_glue(bcx, v0, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
-        }
-        ty::ty_unboxed_vec(_) => {
-            tvec::make_drop_glue_unboxed(bcx, v0, t)
+            let llbox = Load(bcx, v0);
+            let not_null = IsNotNull(bcx, llbox);
+            with_cond(bcx, not_null, |bcx| {
+                let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
+                let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, unit_ty);
+                trans_exchange_free(bcx, llbox)
+            })
         }
         ty::ty_struct(did, ref substs) => {
             let tcx = bcx.tcx();
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 3f1fde8f7a9..0cfa4f5f6d5 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -163,11 +163,6 @@ impl<'a> Reflector<'a> {
           ty::ty_float(ast::TyF32) => self.leaf("f32"),
           ty::ty_float(ast::TyF64) => self.leaf("f64"),
 
-          ty::ty_unboxed_vec(ref mt) => {
-              let values = self.c_mt(mt);
-              self.visit("vec", values.as_slice())
-          }
-
           // Should rename to str_*/vec_*.
           ty::ty_str(vst) => {
               let (name, extra) = self.vstore_name_and_extra(t, vst);
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index b47f509aeee..1f2147b02e5 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -34,22 +34,6 @@ use util::ppaux::ty_to_str;
 use syntax::ast;
 use syntax::parse::token::InternedString;
 
-// Boxed vector types are in some sense currently a "shorthand" for a box
-// containing an unboxed vector. This expands a boxed vector type into such an
-// expanded type. It doesn't respect mutability, but that doesn't matter at
-// this point.
-pub fn expand_boxed_vec_ty(tcx: &ty::ctxt, t: ty::t) -> ty::t {
-    let unit_ty = ty::sequence_element_type(tcx, t);
-    let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty);
-    match ty::get(t).sty {
-        ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) => {
-            ty::mk_uniq(tcx, unboxed_vec_ty)
-        }
-        _ => tcx.sess.bug("non boxed-vec type \
-                           in tvec::expand_boxed_vec_ty")
-    }
-}
-
 pub fn get_fill(bcx: &Block, vptr: ValueRef) -> ValueRef {
     let _icx = push_ctxt("tvec::get_fill");
     Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]))
@@ -67,66 +51,21 @@ pub fn pointer_add_byte(bcx: &Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef
     return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
 }
 
-pub fn alloc_raw<'a>(
-                 bcx: &'a Block<'a>,
-                 unit_ty: ty::t,
-                 fill: ValueRef,
-                 alloc: ValueRef,
-                 heap: heap)
-                 -> Result<'a> {
-    let _icx = push_ctxt("tvec::alloc_uniq");
-    let ccx = bcx.ccx();
-
-    let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
-    let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type));
-
-    if heap == heap_exchange {
-        let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, vecbodyty, heap_exchange, vecsize);
-        Store(bcx, fill, GEPi(bcx, val, [0u, abi::vec_elt_fill]));
-        Store(bcx, alloc, GEPi(bcx, val, [0u, abi::vec_elt_alloc]));
-        return rslt(bcx, val);
-    } else {
-        let base::MallocResult {bcx, smart_ptr: bx, body} =
-            base::malloc_general_dyn(bcx, vecbodyty, heap, vecsize);
-        Store(bcx, fill, GEPi(bcx, body, [0u, abi::vec_elt_fill]));
-        Store(bcx, alloc, GEPi(bcx, body, [0u, abi::vec_elt_alloc]));
-        return rslt(bcx, bx);
-    }
-}
-
-pub fn alloc_uniq_vec<'a>(
-                 bcx: &'a Block<'a>,
-                 unit_ty: ty::t,
-                 elts: uint)
-                 -> Result<'a> {
-    let _icx = push_ctxt("tvec::alloc_uniq");
-    let ccx = bcx.ccx();
-    let llunitty = type_of::type_of(ccx, unit_ty);
-    let unit_sz = nonzero_llsize_of(ccx, llunitty);
-
-    let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
-    let alloc = if elts < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
-                else { fill };
-    let Result {bcx: bcx, val: vptr} =
-        alloc_raw(bcx, unit_ty, fill, alloc, heap_exchange);
-    return rslt(bcx, vptr);
-}
-
 pub fn make_drop_glue_unboxed<'a>(
                               bcx: &'a Block<'a>,
                               vptr: ValueRef,
-                              vec_ty: ty::t)
+                              unit_ty: ty::t)
                               -> &'a Block<'a> {
     let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
     let tcx = bcx.tcx();
-    let unit_ty = ty::sequence_element_type(tcx, vec_ty);
     if ty::type_needs_drop(tcx, unit_ty) {
-        iter_vec_unboxed(bcx, vptr, vec_ty, glue::drop_ty)
+        let fill = get_fill(bcx, vptr);
+        let dataptr = get_dataptr(bcx, vptr);
+        iter_vec_raw(bcx, dataptr, unit_ty, fill, glue::drop_ty)
     } else { bcx }
 }
 
 pub struct VecTypes {
-    pub vec_ty: ty::t,
     pub unit_ty: ty::t,
     pub llunit_ty: Type,
     pub llunit_size: ValueRef,
@@ -135,9 +74,8 @@ pub struct VecTypes {
 
 impl VecTypes {
     pub fn to_str(&self, ccx: &CrateContext) -> ~str {
-        format!("VecTypes \\{vec_ty={}, unit_ty={}, llunit_ty={}, llunit_size={}, \
+        format!("VecTypes \\{unit_ty={}, llunit_ty={}, llunit_size={}, \
                  llunit_alloc_size={}\\}",
-             ty_to_str(ccx.tcx(), self.vec_ty),
              ty_to_str(ccx.tcx(), self.unit_ty),
              ccx.tn.type_to_str(self.llunit_ty),
              ccx.tn.val_to_str(self.llunit_size),
@@ -296,17 +234,16 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
 
     debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_str(vstore_expr));
     let fcx = bcx.fcx;
+    let ccx = fcx.ccx;
 
     // Handle ~"".
     match content_expr.node {
         ast::ExprLit(lit) => {
             match lit.node {
                 ast::LitStr(ref s, _) => {
-                    let llptrval = C_cstr(bcx.ccx(), (*s).clone(), false);
-                    let llptrval = PointerCast(bcx,
-                                               llptrval,
-                                               Type::i8p(bcx.ccx()));
-                    let llsizeval = C_uint(bcx.ccx(), s.get().len());
+                    let llptrval = C_cstr(ccx, (*s).clone(), false);
+                    let llptrval = PointerCast(bcx, llptrval, Type::i8p(ccx));
+                    let llsizeval = C_uint(ccx, s.get().len());
                     let typ = ty::mk_str(bcx.tcx(), ty::vstore_uniq);
                     let lldestval = rvalue_scratch_datum(bcx,
                                                          typ,
@@ -328,15 +265,28 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
         _ => {}
     }
 
-    let vt = vec_types_from_expr(bcx, vstore_expr);
+    let vec_ty = node_id_type(bcx, vstore_expr.id);
+    let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
     let count = elements_required(bcx, content_expr);
 
-    let Result {bcx, val} = alloc_uniq_vec(bcx, vt.unit_ty, count);
+    let llunitty = type_of::type_of(ccx, vt.unit_ty);
+    let unit_sz = nonzero_llsize_of(ccx, llunitty);
+
+    let fill = Mul(bcx, C_uint(ccx, count), unit_sz);
+    let alloc = if count < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
+    else { fill };
+
+    let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type));
+
+    let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, vec_ty, vecsize);
+    Store(bcx, fill, GEPi(bcx, val, [0u, abi::vec_elt_fill]));
+    Store(bcx, alloc, GEPi(bcx, val, [0u, abi::vec_elt_alloc]));
 
     // Create a temporary scope lest execution should fail while
     // constructing the vector.
     let temp_scope = fcx.push_custom_cleanup_scope();
-    fcx.schedule_free_value(cleanup::CustomScope(temp_scope), val, heap_exchange);
+    fcx.schedule_free_value(cleanup::CustomScope(temp_scope),
+                            val, cleanup::HeapExchange);
 
     let dataptr = get_dataptr(bcx, val);
 
@@ -348,7 +298,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
 
     fcx.pop_custom_cleanup_scope(temp_scope);
 
-    return immediate_rvalue_bcx(bcx, val, vt.vec_ty).to_expr_datumblock();
+    immediate_rvalue_bcx(bcx, val, vec_ty).to_expr_datumblock()
 }
 
 pub fn write_content<'a>(
@@ -456,21 +406,21 @@ pub fn write_content<'a>(
 
 pub fn vec_types_from_expr(bcx: &Block, vec_expr: &ast::Expr) -> VecTypes {
     let vec_ty = node_id_type(bcx, vec_expr.id);
-    vec_types(bcx, vec_ty)
+    vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty))
 }
 
-pub fn vec_types(bcx: &Block, vec_ty: ty::t) -> VecTypes {
+pub fn vec_types(bcx: &Block, unit_ty: ty::t) -> VecTypes {
     let ccx = bcx.ccx();
-    let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
     let llunit_ty = type_of::type_of(ccx, unit_ty);
     let llunit_size = nonzero_llsize_of(ccx, llunit_ty);
     let llunit_alloc_size = llsize_of_alloc(ccx, llunit_ty);
 
-    VecTypes {vec_ty: vec_ty,
-              unit_ty: unit_ty,
-              llunit_ty: llunit_ty,
-              llunit_size: llunit_size,
-              llunit_alloc_size: llunit_alloc_size}
+    VecTypes {
+        unit_ty: unit_ty,
+        llunit_ty: llunit_ty,
+        llunit_size: llunit_size,
+        llunit_alloc_size: llunit_alloc_size
+    }
 }
 
 pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint {
@@ -507,11 +457,11 @@ pub fn get_base_and_byte_len(bcx: &Block,
      */
 
     let ccx = bcx.ccx();
-    let vt = vec_types(bcx, vec_ty);
+    let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
 
-    let vstore = match ty::get(vt.vec_ty).sty {
-      ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
-      _ => ty::vstore_uniq
+    let vstore = match ty::get(vec_ty).sty {
+        ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
+        _ => ty::vstore_uniq
     };
 
     match vstore {
@@ -521,14 +471,14 @@ pub fn get_base_and_byte_len(bcx: &Block,
             (base, len)
         }
         ty::vstore_slice(_) => {
-            assert!(!type_is_immediate(bcx.ccx(), vt.vec_ty));
+            assert!(!type_is_immediate(bcx.ccx(), vec_ty));
             let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
             let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
             let len = Mul(bcx, count, vt.llunit_size);
             (base, len)
         }
         ty::vstore_uniq => {
-            assert!(type_is_immediate(bcx.ccx(), vt.vec_ty));
+            assert!(type_is_immediate(bcx.ccx(), vec_ty));
             let body = Load(bcx, llval);
             (get_dataptr(bcx, body), get_fill(bcx, body))
         }
@@ -548,11 +498,11 @@ pub fn get_base_and_len(bcx: &Block,
      */
 
     let ccx = bcx.ccx();
-    let vt = vec_types(bcx, vec_ty);
+    let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
 
-    let vstore = match ty::get(vt.vec_ty).sty {
-      ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
-      _ => ty::vstore_uniq
+    let vstore = match ty::get(vec_ty).sty {
+        ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
+        _ => ty::vstore_uniq
     };
 
     match vstore {
@@ -561,13 +511,13 @@ pub fn get_base_and_len(bcx: &Block,
             (base, C_uint(ccx, n))
         }
         ty::vstore_slice(_) => {
-            assert!(!type_is_immediate(bcx.ccx(), vt.vec_ty));
+            assert!(!type_is_immediate(bcx.ccx(), vec_ty));
             let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
             let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
             (base, count)
         }
         ty::vstore_uniq => {
-            assert!(type_is_immediate(bcx.ccx(), vt.vec_ty));
+            assert!(type_is_immediate(bcx.ccx(), vec_ty));
             let body = Load(bcx, llval);
             (get_dataptr(bcx, body), UDiv(bcx, get_fill(bcx, body), vt.llunit_size))
         }
@@ -639,14 +589,14 @@ pub fn iter_vec_raw<'r,
                     'b>(
                     bcx: &'b Block<'b>,
                     data_ptr: ValueRef,
-                    vec_ty: ty::t,
+                    unit_ty: ty::t,
                     fill: ValueRef,
                     f: iter_vec_block<'r,'b>)
                     -> &'b Block<'b> {
     let _icx = push_ctxt("tvec::iter_vec_raw");
     let fcx = bcx.fcx;
 
-    let vt = vec_types(bcx, vec_ty);
+    let vt = vec_types(bcx, unit_ty);
     if vt.llunit_alloc_size == 0 {
         // Special-case vectors with elements of size 0  so they don't go out of bounds (#9890)
         iter_vec_loop(bcx, data_ptr, &vt, fill, f)
@@ -675,16 +625,3 @@ pub fn iter_vec_raw<'r,
         next_bcx
     }
 }
-
-pub fn iter_vec_unboxed<'r,
-                        'b>(
-                        bcx: &'b Block<'b>,
-                        body_ptr: ValueRef,
-                        vec_ty: ty::t,
-                        f: iter_vec_block<'r,'b>)
-                        -> &'b Block<'b> {
-    let _icx = push_ctxt("tvec::iter_vec_unboxed");
-    let fill = get_fill(bcx, body_ptr);
-    let dataptr = get_dataptr(bcx, body_ptr);
-    return iter_vec_raw(bcx, dataptr, vec_ty, fill, f);
-}
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index f45ef457204..5a4cb1a33ef 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -137,10 +137,6 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
             Type::array(&sizing_type_of(cx, mt.ty), size as u64)
         }
 
-        ty::ty_unboxed_vec(mt) => {
-            Type::vec(cx, &sizing_type_of(cx, mt.ty))
-        }
-
         ty::ty_tup(..) | ty::ty_enum(..) => {
             let repr = adt::represent_type(cx, t);
             adt::sizing_type_of(cx, repr)
@@ -224,9 +220,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
       ty::ty_vec(ref mt, ty::vstore_uniq) => {
           Type::vec(cx, &type_of(cx, mt.ty)).ptr_to()
       }
-      ty::ty_unboxed_vec(ref mt) => {
-          Type::vec(cx, &type_of(cx, mt.ty))
-      }
       ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),
       ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(),
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 4aefa3b9edc..a250c6c298b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -750,9 +750,6 @@ pub enum sty {
     ty_err, // Also only used during inference/typeck, to represent
             // the type of an erroneous expression (helps cut down
             // on non-useful type error messages)
-
-    // "Fake" types, used for trans purposes
-    ty_unboxed_vec(mt),
 }
 
 #[deriving(Clone, Eq, TotalEq, Hash)]
@@ -1214,8 +1211,7 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
       &ty_box(tt) | &ty_uniq(tt) => {
         flags |= get(tt).flags
       }
-      &ty_vec(ref m, _) | &ty_ptr(ref m) |
-      &ty_unboxed_vec(ref m) => {
+      &ty_vec(ref m, _) | &ty_ptr(ref m) => {
         flags |= get(m.ty).flags;
       }
       &ty_rptr(r, ref m) => {
@@ -1384,13 +1380,6 @@ pub fn mk_vec(cx: &ctxt, tm: mt, t: vstore) -> t {
     mk_t(cx, ty_vec(tm, t))
 }
 
-pub fn mk_unboxed_vec(cx: &ctxt, tm: mt) -> t {
-    mk_t(cx, ty_unboxed_vec(tm))
-}
-pub fn mk_mut_unboxed_vec(cx: &ctxt, ty: t) -> t {
-    mk_t(cx, ty_unboxed_vec(mt {ty: ty, mutbl: ast::MutImmutable}))
-}
-
 pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
 
 pub fn mk_closure(cx: &ctxt, fty: ClosureTy) -> t {
@@ -1470,8 +1459,7 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
         ty_str(_) | ty_self(_) |
         ty_infer(_) | ty_param(_) | ty_err => {}
         ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
-        ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
-        ty_rptr(_, ref tm) => {
+        ty_vec(ref tm, _) | ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
             maybe_walk_ty(tm.ty, f);
         }
         ty_enum(_, ref substs) | ty_struct(_, ref substs) |
@@ -1625,9 +1613,9 @@ pub fn type_is_simd(cx: &ctxt, ty: t) -> bool {
 
 pub fn sequence_element_type(cx: &ctxt, ty: t) -> t {
     match get(ty).sty {
-      ty_str(_) => return mk_mach_uint(ast::TyU8),
-      ty_vec(mt, _) | ty_unboxed_vec(mt) => return mt.ty,
-      _ => cx.sess.bug("sequence_element_type called on non-sequence value"),
+        ty_str(_) => mk_mach_uint(ast::TyU8),
+        ty_vec(mt, _) => mt.ty,
+        _ => cx.sess.bug("sequence_element_type called on non-sequence value"),
     }
 }
 
@@ -1913,6 +1901,10 @@ impl TypeContents {
         self.intersects(TC::InteriorUnsafe)
     }
 
+    pub fn interior_unsized(&self) -> bool {
+        self.intersects(TC::InteriorUnsized)
+    }
+
     pub fn moves_by_default(&self, _: &ctxt) -> bool {
         self.intersects(TC::Moves)
     }
@@ -2167,7 +2159,6 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                 // times.
                 TC::All
             }
-            ty_unboxed_vec(mt) => TC::InteriorUnsized | tc_mt(cx, mt, cache),
 
             ty_err => {
                 cx.sess.bug("asked to compute contents of error type");
@@ -2354,8 +2345,7 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
             ty_err |
             ty_param(_) |
             ty_self(_) |
-            ty_vec(_, _) |
-            ty_unboxed_vec(_) => {
+            ty_vec(_, _) => {
                 false
             }
             ty_box(typ) | ty_uniq(typ) => {
@@ -3313,7 +3303,6 @@ pub fn ty_sort_str(cx: &ctxt, t: t) -> ~str {
         ty_box(_) => ~"@-ptr",
         ty_uniq(_) => ~"~-ptr",
         ty_vec(_, _) => ~"vector",
-        ty_unboxed_vec(_) => ~"unboxed vector",
         ty_ptr(_) => ~"*-ptr",
         ty_rptr(_, _) => ~"&-ptr",
         ty_bare_fn(_) => ~"extern fn",
@@ -4719,10 +4708,6 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             }
             ty_infer(_) => unreachable!(),
             ty_err => byte!(23),
-            ty_unboxed_vec(m) => {
-                byte!(24);
-                mt(&mut state, m);
-            }
         }
     });
 
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 02c4ffe68c1..686452a5e44 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -148,9 +148,6 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_ptr(ref tm) => {
             ty::ty_ptr(this.fold_mt(tm))
         }
-        ty::ty_unboxed_vec(ref tm) => {
-            ty::ty_unboxed_vec(this.fold_mt(tm))
-        }
         ty::ty_vec(ref tm, vst) => {
             ty::ty_vec(this.fold_mt(tm), this.fold_vstore(vst))
         }
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index b6f81d94418..bcad3a87582 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -637,9 +637,6 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
             };
             (mt, region_var)
           }
-          ty::ty_unboxed_vec(mt) => {
-            (mt, default_region_var)
-          },
           _ => {
               for &elt in before.iter() {
                   check_pat(pcx, elt, ty::mk_err());
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index dce4e7fb06b..991e21ffab8 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -910,7 +910,7 @@ impl<'a> LookupContext<'a> {
 
             ty_err => None,
 
-            ty_unboxed_vec(_) | ty_infer(TyVar(_)) => {
+            ty_infer(TyVar(_)) => {
                 self.bug(format!("unexpected type: {}",
                               self.ty_to_str(self_ty)));
             }
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 284e0108a6b..73e1bc78641 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -24,7 +24,7 @@ use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil};
 use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr};
 use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_uint, ty_uniq, ty_bare_fn, ty_closure};
-use middle::ty::{ty_unboxed_vec, type_is_ty_var};
+use middle::ty::type_is_ty_var;
 use middle::subst::Subst;
 use middle::ty;
 use middle::ty::{Impl, Method};
@@ -81,9 +81,8 @@ fn get_base_type(inference_context: &InferCtxt,
 
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
         ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
-        ty_infer(..) | ty_param(..) | ty_self(..) |
-        ty_unboxed_vec(..) | ty_err | ty_box(_) |
-        ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => {
+        ty_infer(..) | ty_param(..) | ty_self(..) | ty_err |
+        ty_box(_) | ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => {
             debug!("(getting base type) no base type; found {:?}",
                    get(original_type).sty);
             None
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index baa4e1c1db1..91d9b264a88 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -707,7 +707,7 @@ impl<'a> ConstraintContext<'a> {
                 self.add_constraints_from_sig(sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err | ty::ty_unboxed_vec(..) => {
+            ty::ty_infer(..) | ty::ty_err => {
                 self.tcx().sess.bug(
                     format!("unexpected type encountered in \
                             variance inference: {}",
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 4a1be783d9d..155ceadf0d8 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -19,7 +19,7 @@ use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
 use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_self, ty_tup};
-use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
+use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
 use middle::typeck;
 
@@ -397,7 +397,6 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
       ty_rptr(r, ref tm) => {
         region_ptr_to_str(cx, r) + mt_to_str(cx, tm)
       }
-      ty_unboxed_vec(ref tm) => { format!("unboxed_vec<{}>", mt_to_str(cx, tm)) }
       ty_tup(ref elems) => {
         let strs: Vec<~str> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
         ~"(" + strs.connect(",") + ")"
diff --git a/src/libstd/intrinsics.rs b/src/libstd/intrinsics.rs
index 6fe6b3c3639..896ebcd6fb5 100644
--- a/src/libstd/intrinsics.rs
+++ b/src/libstd/intrinsics.rs
@@ -108,8 +108,6 @@ pub trait TyVisitor {
     fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
     fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
 
-    fn visit_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
-    fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
     fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
     fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
     fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index 997b65c2e1f..e64a6b86d02 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -18,7 +18,6 @@ Runtime type reflection
 
 use intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
 use mem;
-use raw;
 
 /**
  * Trait for visitor that wishes to reflect on data. To use this, create a
@@ -239,19 +238,6 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
         true
     }
 
-    fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.align_to::<raw::Vec<()>>();
-        if ! self.inner.visit_vec(mtbl, inner) { return false; }
-        true
-    }
-
-    fn visit_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.align_to::<~[u8]>();
-        if ! self.inner.visit_vec(mtbl, inner) { return false; }
-        self.bump_past::<~[u8]>();
-        true
-    }
-
     fn visit_evec_box(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool {
         true
     }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 9d1d406e803..a1fa7cb225f 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -341,15 +341,6 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
         })
     }
 
-    // Type no longer exists, vestigial function.
-    fn visit_vec(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { fail!(); }
-
-    fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.get::<raw::Vec<()>>(|this, b| {
-            this.write_unboxed_vec_repr(mtbl, b, inner)
-        })
-    }
-
     fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
         self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
             try!(this, this.writer.write(['@' as u8]));
diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs
index 36049bc0a18..ca0b5fd0703 100644
--- a/src/test/run-pass/reflect-visit-type.rs
+++ b/src/test/run-pass/reflect-visit-type.rs
@@ -73,8 +73,6 @@ impl TyVisitor for MyVisitor {
     fn visit_ptr(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
     fn visit_rptr(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
 
-    fn visit_vec(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
-    fn visit_unboxed_vec(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
     fn visit_evec_box(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
     fn visit_evec_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
         self.types.push(~"[");