about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-21 20:06:44 -0700
committerbors <bors@rust-lang.org>2014-03-21 20:06:44 -0700
commitf5357cf3cee42d12249006a42dfa835f96ab5422 (patch)
treeab8bd94140ba08a70796786a6e5c63529a545f34
parentbbf8cdc43feea08111abc5a59dc49a7f479d3103 (diff)
parente33676b7936b12bb68f47857ab3f8ea9b757d0d5 (diff)
downloadrust-f5357cf3cee42d12249006a42dfa835f96ab5422.tar.gz
rust-f5357cf3cee42d12249006a42dfa835f96ab5422.zip
auto merge of #13016 : huonw/rust/new-opt-vec, r=cmr
Replace syntax::opt_vec with syntax::owned_slice

The `owned_slice::OwnedSlice` is  `(*T, uint)` (i.e. a direct equivalent to DSTs `~[T]`).

This shaves two words off the old OptVec type; and also makes substituting in other implementations easy, by removing all the mutation methods. (And also everything that's very rarely/never used.)
-rw-r--r--src/librustc/front/std_inject.rs6
-rw-r--r--src/librustc/front/test.rs6
-rw-r--r--src/librustc/metadata/tydecode.rs6
-rw-r--r--src/librustc/middle/borrowck/move_data.rs8
-rw-r--r--src/librustc/middle/cfg/construct.rs6
-rw-r--r--src/librustc/middle/cfg/mod.rs3
-rw-r--r--src/librustc/middle/kind.rs4
-rw-r--r--src/librustc/middle/privacy.rs4
-rw-r--r--src/librustc/middle/resolve.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs9
-rw-r--r--src/librustc/middle/subst.rs6
-rw-r--r--src/librustc/middle/trans/cleanup.rs16
-rw-r--r--src/librustc/middle/trans/debuginfo.rs5
-rw-r--r--src/librustc/middle/trans/type_of.rs4
-rw-r--r--src/librustc/middle/ty.rs22
-rw-r--r--src/librustc/middle/typeck/astconv.rs7
-rw-r--r--src/librustc/middle/typeck/check/method.rs7
-rw-r--r--src/librustc/middle/typeck/check/mod.rs13
-rw-r--r--src/librustc/middle/typeck/collect.rs12
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs6
-rw-r--r--src/librustc/middle/typeck/infer/error_reporting.rs18
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs4
-rw-r--r--src/librustc/middle/typeck/infer/region_inference/mod.rs16
-rw-r--r--src/librustc/middle/typeck/rscope.rs4
-rw-r--r--src/librustc/middle/typeck/variance.rs31
-rw-r--r--src/librustc/util/ppaux.rs10
-rw-r--r--src/librustdoc/clean.rs7
-rw-r--r--src/libstd/vec.rs13
-rw-r--r--src/libsyntax/ast.rs12
-rw-r--r--src/libsyntax/ast_util.rs10
-rw-r--r--src/libsyntax/ext/build.rs33
-rw-r--r--src/libsyntax/ext/concat_idents.rs4
-rw-r--r--src/libsyntax/ext/deriving/generic.rs29
-rw-r--r--src/libsyntax/ext/deriving/ty.rs19
-rw-r--r--src/libsyntax/fold.rs10
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/opt_vec.rs217
-rw-r--r--src/libsyntax/owned_slice.rs142
-rw-r--r--src/libsyntax/parse/mod.rs22
-rw-r--r--src/libsyntax/parse/parser.rs39
-rw-r--r--src/libsyntax/print/pprust.rs17
-rw-r--r--src/libsyntax/visit.rs7
42 files changed, 369 insertions, 451 deletions
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index a78f90cbe87..9a0c06c0955 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -18,7 +18,7 @@ use syntax::codemap::DUMMY_SP;
 use syntax::codemap;
 use syntax::fold::Folder;
 use syntax::fold;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::util::small_vector::SmallVector;
@@ -156,12 +156,12 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
                 ast::PathSegment {
                     identifier: token::str_to_ident("std"),
                     lifetimes: Vec::new(),
-                    types: opt_vec::Empty,
+                    types: OwnedSlice::empty(),
                 },
                 ast::PathSegment {
                     identifier: token::str_to_ident("prelude"),
                     lifetimes: Vec::new(),
-                    types: opt_vec::Empty,
+                    types: OwnedSlice::empty(),
                 }),
         };
 
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index 2b71b0919c6..be9e9ea0bf6 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -31,7 +31,7 @@ use syntax::ext::base::ExtCtxt;
 use syntax::ext::expand::ExpansionConfig;
 use syntax::fold::Folder;
 use syntax::fold;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::print::pprust;
@@ -377,7 +377,7 @@ fn path_node(ids: Vec<ast::Ident> ) -> ast::Path {
         segments: ids.move_iter().map(|identifier| ast::PathSegment {
             identifier: identifier,
             lifetimes: Vec::new(),
-            types: opt_vec::Empty,
+            types: OwnedSlice::empty(),
         }).collect()
     }
 }
@@ -389,7 +389,7 @@ fn path_node_global(ids: Vec<ast::Ident> ) -> ast::Path {
         segments: ids.move_iter().map(|identifier| ast::PathSegment {
             identifier: identifier,
             lifetimes: Vec::new(),
-            types: opt_vec::Empty,
+            types: OwnedSlice::empty(),
         }).collect()
     }
 }
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 1e9b98073fa..c8ab6818697 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -24,7 +24,7 @@ use syntax::abi::AbiSet;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast::*;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 
 // Compact string representation for ty::t values. API ty_str &
@@ -192,13 +192,13 @@ fn parse_region_substs(st: &mut PState, conv: conv_did) -> ty::RegionSubsts {
     match next(st) {
         'e' => ty::ErasedRegions,
         'n' => {
-            let mut regions = opt_vec::Empty;
+            let mut regions = vec!();
             while peek(st) != '.' {
                 let r = parse_region(st, |x,y| conv(x,y));
                 regions.push(r);
             }
             assert_eq!(next(st), '.');
-            ty::NonerasedRegions(regions)
+            ty::NonerasedRegions(OwnedSlice::from_vec(regions))
         }
         _ => fail!("parse_bound_region: bad input")
     }
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index de4059142e4..93a1ba309c2 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -26,8 +26,6 @@ use middle::typeck;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
-use syntax::opt_vec::OptVec;
-use syntax::opt_vec;
 use util::ppaux::Repr;
 
 pub struct MoveData {
@@ -316,15 +314,15 @@ impl MoveData {
 
     fn existing_base_paths(&self,
                            lp: @LoanPath)
-                           -> OptVec<MovePathIndex> {
-        let mut result = opt_vec::Empty;
+                           -> Vec<MovePathIndex> {
+        let mut result = vec!();
         self.add_existing_base_paths(lp, &mut result);
         result
     }
 
     fn add_existing_base_paths(&self,
                                lp: @LoanPath,
-                               result: &mut OptVec<MovePathIndex>) {
+                               result: &mut Vec<MovePathIndex>) {
         /*!
          * Adds any existing move path indices for `lp` and any base
          * paths of `lp` to `result`, but does not add new move paths
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index a742ff336b2..b84e923f77d 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -14,7 +14,6 @@ use middle::typeck;
 use middle::ty;
 use syntax::ast;
 use syntax::ast_util;
-use syntax::opt_vec;
 use util::nodemap::NodeMap;
 
 struct CFGBuilder<'a> {
@@ -470,7 +469,7 @@ impl<'a> CFGBuilder<'a> {
     fn add_contained_edge(&mut self,
                           source: CFGIndex,
                           target: CFGIndex) {
-        let data = CFGEdgeData {exiting_scopes: opt_vec::Empty};
+        let data = CFGEdgeData {exiting_scopes: vec!() };
         self.graph.add_edge(source, target, data);
     }
 
@@ -479,9 +478,10 @@ impl<'a> CFGBuilder<'a> {
                         from_index: CFGIndex,
                         to_loop: LoopScope,
                         to_index: CFGIndex) {
-        let mut data = CFGEdgeData {exiting_scopes: opt_vec::Empty};
+        let mut data = CFGEdgeData {exiting_scopes: vec!() };
         let mut scope_id = from_expr.id;
         while scope_id != to_loop.loop_id {
+
             data.exiting_scopes.push(scope_id);
             scope_id = self.tcx.region_maps.encl_scope(scope_id);
         }
diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs
index 5b4a5f89ea9..9c2dcd74351 100644
--- a/src/librustc/middle/cfg/mod.rs
+++ b/src/librustc/middle/cfg/mod.rs
@@ -19,7 +19,6 @@ use middle::graph;
 use middle::ty;
 use middle::typeck;
 use syntax::ast;
-use syntax::opt_vec::OptVec;
 use util::nodemap::NodeMap;
 
 mod construct;
@@ -36,7 +35,7 @@ pub struct CFGNodeData {
 }
 
 pub struct CFGEdgeData {
-    exiting_scopes: OptVec<ast::NodeId>
+    exiting_scopes: Vec<ast::NodeId>
 }
 
 pub type CFGIndex = graph::NodeIndex;
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index d9843ba36cc..9d8f35eb980 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -19,7 +19,7 @@ use util::ppaux::UserString;
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::print::pprust::expr_to_str;
 use syntax::{visit,ast_util};
 use syntax::visit::Visitor;
@@ -92,7 +92,7 @@ fn check_struct_safe_for_destructor(cx: &mut Context,
     let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did);
     if !struct_tpt.generics.has_type_params() {
         let struct_ty = ty::mk_struct(cx.tcx, struct_did, ty::substs {
-            regions: ty::NonerasedRegions(opt_vec::Empty),
+            regions: ty::NonerasedRegions(OwnedSlice::empty()),
             self_ty: None,
             tps: Vec::new()
         });
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 6dd4eb360f2..360d010ed67 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -28,7 +28,7 @@ use syntax::ast_util::{is_local, def_id_of_def, local_def};
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::parse::token;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -842,7 +842,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
                                 let seg = ast::PathSegment {
                                     identifier: pid.node.name,
                                     lifetimes: Vec::new(),
-                                    types: opt_vec::Empty,
+                                    types: OwnedSlice::empty(),
                                 };
                                 let segs = vec!(seg);
                                 let path = ast::Path {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 86180a04297..47f5e05fb8a 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -27,7 +27,7 @@ use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::print::pprust::path_to_str;
 use syntax::codemap::{Span, DUMMY_SP, Pos};
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -3969,7 +3969,7 @@ impl<'a> Resolver<'a> {
     }
 
     fn resolve_type_parameters(&mut self,
-                                   type_parameters: &OptVec<TyParam>) {
+                                   type_parameters: &OwnedSlice<TyParam>) {
         for type_parameter in type_parameters.iter() {
             for bound in type_parameter.bounds.iter() {
                 self.resolve_type_parameter_bound(type_parameter.id, bound);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 49d8c5acb17..40a7bdff11f 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -21,8 +21,7 @@ use driver::session::Session;
 use util::nodemap::NodeMap;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::opt_vec;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::print::pprust::{lifetime_to_str};
@@ -413,7 +412,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
         .collect()
 }
 
-pub fn free_lifetimes(ty_params: &OptVec<ast::TyParam>) -> OptVec<ast::Name> {
+pub fn free_lifetimes(ty_params: &OwnedSlice<ast::TyParam>) -> Vec<ast::Name> {
     /*!
      * Gathers up and returns the names of any lifetimes that appear
      * free in `ty_params`. Of course, right now, all lifetimes appear
@@ -421,14 +420,14 @@ pub fn free_lifetimes(ty_params: &OptVec<ast::TyParam>) -> OptVec<ast::Name> {
      * declarations; just being forwards compatible with future extensions.
      */
 
-    let mut collector = FreeLifetimeCollector { names: opt_vec::Empty };
+    let mut collector = FreeLifetimeCollector { names: vec!() };
     for ty_param in ty_params.iter() {
         visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds, ());
     }
     return collector.names;
 
     struct FreeLifetimeCollector {
-        names: OptVec<ast::Name>,
+        names: Vec<ast::Name>,
     }
 
     impl Visitor<()> for FreeLifetimeCollector {
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 43a6b2c46a5..0dd5c2ee10e 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -17,7 +17,7 @@ use util::ppaux::Repr;
 
 use std::rc::Rc;
 use syntax::codemap::Span;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 
 ///////////////////////////////////////////////////////////////////////////
 // Public trait `Subst`
@@ -145,10 +145,10 @@ impl<T:Subst> Subst for Rc<T> {
     }
 }
 
-impl<T:Subst> Subst for OptVec<T> {
+impl<T:Subst> Subst for OwnedSlice<T> {
     fn subst_spanned(&self, tcx: &ty::ctxt,
                      substs: &ty::substs,
-                     span: Option<Span>) -> OptVec<T> {
+                     span: Option<Span>) -> OwnedSlice<T> {
         self.map(|t| t.subst_spanned(tcx, substs, span))
     }
 }
diff --git a/src/librustc/middle/trans/cleanup.rs b/src/librustc/middle/trans/cleanup.rs
index 1acc746b197..75f236d5028 100644
--- a/src/librustc/middle/trans/cleanup.rs
+++ b/src/librustc/middle/trans/cleanup.rs
@@ -24,8 +24,6 @@ use middle::trans::glue;
 use middle::trans::type_::Type;
 use middle::ty;
 use syntax::ast;
-use syntax::opt_vec;
-use syntax::opt_vec::OptVec;
 use util::ppaux::Repr;
 
 pub struct CleanupScope<'a> {
@@ -37,9 +35,9 @@ pub struct CleanupScope<'a> {
     kind: CleanupScopeKind<'a>,
 
     // Cleanups to run upon scope exit.
-    cleanups: OptVec<~Cleanup>,
+    cleanups: Vec<~Cleanup>,
 
-    cached_early_exits: OptVec<CachedEarlyExit>,
+    cached_early_exits: Vec<CachedEarlyExit>,
     cached_landing_pad: Option<BasicBlockRef>,
 }
 
@@ -379,7 +377,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
         assert!(orig_scopes_len > 0);
 
         // Remove any scopes that do not have cleanups on failure:
-        let mut popped_scopes = opt_vec::Empty;
+        let mut popped_scopes = vec!();
         while !self.top_scope(|s| s.needs_invoke()) {
             debug!("top scope does not need invoke");
             popped_scopes.push(self.pop_scope());
@@ -510,7 +508,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
 
         let orig_scopes_len = self.scopes_len();
         let mut prev_llbb;
-        let mut popped_scopes = opt_vec::Empty;
+        let mut popped_scopes = vec!();
 
         // First we pop off all the cleanup stacks that are
         // traversed until the exit is reached, pushing them
@@ -708,14 +706,14 @@ impl<'a> CleanupScope<'a> {
     fn new(kind: CleanupScopeKind<'a>) -> CleanupScope<'a> {
         CleanupScope {
             kind: kind,
-            cleanups: opt_vec::Empty,
-            cached_early_exits: opt_vec::Empty,
+            cleanups: vec!(),
+            cached_early_exits: vec!(),
             cached_landing_pad: None,
         }
     }
 
     fn clear_cached_exits(&mut self) {
-        self.cached_early_exits = opt_vec::Empty;
+        self.cached_early_exits = vec!();
         self.cached_landing_pad = None;
     }
 
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 313ee8b592b..dce7e85742d 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -150,7 +150,8 @@ use std::ptr;
 use std::sync::atomics;
 use std::slice;
 use syntax::codemap::{Span, Pos};
-use syntax::{abi, ast, codemap, ast_util, ast_map, opt_vec};
+use syntax::{abi, ast, codemap, ast_util, ast_map};
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::parse::token::special_idents;
 
@@ -539,7 +540,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
         return FunctionWithoutDebugInfo;
     }
 
-    let empty_generics = ast::Generics { lifetimes: Vec::new(), ty_params: opt_vec::Empty };
+    let empty_generics = ast::Generics { lifetimes: Vec::new(), ty_params: OwnedSlice::empty() };
 
     let fnitem = cx.tcx.map.get(fn_ast_id);
 
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 6b02339577e..dad254e2dc7 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -20,7 +20,7 @@ use util::ppaux::Repr;
 use middle::trans::type_::Type;
 
 use syntax::ast;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 
 pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: ty::t) -> bool {
     !type_is_immediate(ccx, arg_ty)
@@ -324,7 +324,7 @@ pub fn llvm_type_name(cx: &CrateContext,
         an_enum => { "enum" }
     };
     let tstr = ppaux::parameterized(cx.tcx(), ty::item_path_str(cx.tcx(), did),
-                                    &ty::NonerasedRegions(opt_vec::Empty),
+                                    &ty::NonerasedRegions(OwnedSlice::empty()),
                                     tps, did, false);
     if did.krate == 0 {
         format!("{}.{}", name, tstr)
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 86cb4e9b010..61cadfea253 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -51,8 +51,7 @@ use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::parse::token::InternedString;
 use syntax::{ast, ast_map};
-use syntax::opt_vec::OptVec;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::abi::AbiSet;
 use syntax;
 use collections::enum_set::{EnumSet, CLike};
@@ -192,8 +191,8 @@ pub enum ast_ty_to_ty_cache_entry {
 #[deriving(Clone, Eq, Decodable, Encodable)]
 pub struct ItemVariances {
     self_param: Option<Variance>,
-    type_params: OptVec<Variance>,
-    region_params: OptVec<Variance>
+    type_params: OwnedSlice<Variance>,
+    region_params: OwnedSlice<Variance>
 }
 
 #[deriving(Clone, Eq, Decodable, Encodable, Show)]
@@ -646,7 +645,7 @@ pub enum BoundRegion {
 #[deriving(Clone, Eq, Hash)]
 pub enum RegionSubsts {
     ErasedRegions,
-    NonerasedRegions(OptVec<ty::Region>)
+    NonerasedRegions(OwnedSlice<ty::Region>)
 }
 
 /**
@@ -4658,7 +4657,7 @@ pub fn visitor_object_ty(tcx: &ctxt,
         Err(s) => { return Err(s); }
     };
     let substs = substs {
-        regions: ty::NonerasedRegions(opt_vec::Empty),
+        regions: ty::NonerasedRegions(OwnedSlice::empty()),
         self_ty: None,
         tps: Vec::new()
     };
@@ -5072,11 +5071,10 @@ pub fn construct_parameter_environment(
 
     // map bound 'a => free 'a
     let region_params = {
-        fn push_region_params(accum: OptVec<ty::Region>,
+        fn push_region_params(mut accum: Vec<ty::Region>,
                               free_id: ast::NodeId,
                               region_params: &[RegionParameterDef])
-                              -> OptVec<ty::Region> {
-            let mut accum = accum;
+                              -> Vec<ty::Region> {
             for r in region_params.iter() {
                 accum.push(
                     ty::ReFree(ty::FreeRegion {
@@ -5086,14 +5084,14 @@ pub fn construct_parameter_environment(
             accum
         }
 
-        let t = push_region_params(opt_vec::Empty, free_id, item_region_params);
+        let t = push_region_params(vec!(), free_id, item_region_params);
         push_region_params(t, free_id, method_region_params)
     };
 
     let free_substs = substs {
         self_ty: self_ty,
         tps: type_params,
-        regions: ty::NonerasedRegions(region_params)
+        regions: ty::NonerasedRegions(OwnedSlice::from_vec(region_params))
     };
 
     //
@@ -5131,7 +5129,7 @@ impl substs {
         substs {
             self_ty: None,
             tps: Vec::new(),
-            regions: NonerasedRegions(opt_vec::Empty)
+            regions: NonerasedRegions(OwnedSlice::empty())
         }
     }
 }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index be7668eaf40..d28ad74e49b 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -63,8 +63,7 @@ use util::ppaux::Repr;
 use syntax::abi::AbiSet;
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
-use syntax::opt_vec::OptVec;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::print::pprust::{lifetime_to_str, path_to_str};
 
 pub trait AstConv {
@@ -229,7 +228,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
                             .collect();
 
     let mut substs = substs {
-        regions: ty::NonerasedRegions(opt_vec::from(regions)),
+        regions: ty::NonerasedRegions(OwnedSlice::from_vec(regions)),
         self_ty: self_ty,
         tps: tps
     };
@@ -816,7 +815,7 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
     }
 }
 
-fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OptVec<ast::TyParamBound>>,
+fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        store: ty::TraitStore)
                        -> ty::BuiltinBounds {
     //! Converts a list of bounds from the AST into a `BuiltinBounds`
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 055a996e8ec..fc577f12f6a 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -104,6 +104,7 @@ use syntax::ast::{MutMutable, MutImmutable};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token;
+use syntax::owned_slice::OwnedSlice;
 
 #[deriving(Eq)]
 pub enum CheckTraitsFlag {
@@ -1102,8 +1103,8 @@ impl<'a> LookupContext<'a> {
 
         // Determine values for the early-bound lifetime parameters.
         // FIXME -- permit users to manually specify lifetimes
-        let mut all_regions = match candidate.rcvr_substs.regions {
-            NonerasedRegions(ref v) => v.clone(),
+        let mut all_regions: Vec<Region> = match candidate.rcvr_substs.regions {
+            NonerasedRegions(ref v) => v.iter().map(|r| r.clone()).collect(),
             ErasedRegions => tcx.sess.span_bug(self.span, "ErasedRegions")
         };
         let m_regions =
@@ -1119,7 +1120,7 @@ impl<'a> LookupContext<'a> {
         let all_substs = substs {
             tps: vec::append(candidate.rcvr_substs.tps.clone(),
                                 m_substs.as_slice()),
-            regions: NonerasedRegions(all_regions),
+            regions: NonerasedRegions(OwnedSlice::from_vec(all_regions)),
             self_ty: candidate.rcvr_substs.self_ty,
         };
 
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 13808d6df13..ff98d5196ad 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -129,8 +129,7 @@ use syntax::ast_util;
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::codemap;
-use syntax::opt_vec::OptVec;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::visit;
@@ -903,7 +902,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
         impl_m.generics.type_param_defs().iter().enumerate().
         map(|(i,t)| ty::mk_param(tcx, i + impl_tps, t.def_id)).
         collect();
-    let dummy_impl_regions: OptVec<ty::Region> =
+    let dummy_impl_regions: OwnedSlice<ty::Region> =
         impl_generics.region_param_defs().iter().
         map(|l| ty::ReFree(ty::FreeRegion {
                 scope_id: impl_m_body_id,
@@ -2631,7 +2630,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                                       }
                                   };
                               let regions =
-                                  ty::NonerasedRegions(opt_vec::Empty);
+                                  ty::NonerasedRegions(OwnedSlice::empty());
                               let sty = ty::mk_struct(tcx,
                                                       gc_struct_id,
                                                       substs {
@@ -3706,7 +3705,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
     let num_expected_regions = tpt.generics.region_param_defs().len();
     let num_supplied_regions = pth.segments.last().unwrap().lifetimes.len();
     let regions = if num_expected_regions == num_supplied_regions {
-        opt_vec::from(pth.segments.last().unwrap().lifetimes.map(
+        OwnedSlice::from_vec(pth.segments.last().unwrap().lifetimes.map(
             |l| ast_region_to_region(fcx.tcx(), l)))
     } else {
         if num_supplied_regions != 0 {
@@ -3971,7 +3970,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: ast::P<ast::Block>) -> bool
 
 pub fn check_bounds_are_used(ccx: &CrateCtxt,
                              span: Span,
-                             tps: &OptVec<ast::TyParam>,
+                             tps: &OwnedSlice<ast::TyParam>,
                              ty: ty::t) {
     debug!("check_bounds_are_used(n_tps={}, ty={})",
            tps.len(), ppaux::ty_to_str(ccx.tcx, ty));
@@ -4087,7 +4086,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                     Ok(did) => (1u, Vec::new(), ty::mk_struct(ccx.tcx, did, substs {
                                                  self_ty: None,
                                                  tps: Vec::new(),
-                                                 regions: ty::NonerasedRegions(opt_vec::Empty)
+                                                 regions: ty::NonerasedRegions(OwnedSlice::empty())
                                                  }) ),
                     Err(msg) => { tcx.sess.span_fatal(it.span, msg); }
                 }
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index ec460f8c6b5..4eeae31d0a4 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -60,7 +60,7 @@ use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::print::pprust::{path_to_str};
 use syntax::visit;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 
 struct CollectItemTypesVisitor<'a> {
     ccx: &'a CrateCtxt<'a>
@@ -987,14 +987,14 @@ pub fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
 
 pub fn ty_generics(ccx: &CrateCtxt,
                    lifetimes: &Vec<ast::Lifetime>,
-                   ty_params: &OptVec<ast::TyParam>,
+                   ty_params: &OwnedSlice<ast::TyParam>,
                    base_index: uint) -> ty::Generics {
     return ty::Generics {
         region_param_defs: Rc::new(lifetimes.iter().map(|l| {
                 ty::RegionParameterDef { name: l.name,
                                          def_id: local_def(l.id) }
             }).collect()),
-        type_param_defs: Rc::new(ty_params.mapi_to_vec(|offset, param| {
+        type_param_defs: Rc::new(ty_params.iter().enumerate().map(|(offset, param)| {
             let existing_def_opt = {
                 let ty_param_defs = ccx.tcx.ty_param_defs.borrow();
                 ty_param_defs.get().find(&param.id).map(|&def| def)
@@ -1015,13 +1015,13 @@ pub fn ty_generics(ccx: &CrateCtxt,
                 ty_param_defs.get().insert(param.id, def);
                 def
             })
-        }).move_iter().collect()),
+        }).collect()),
     };
 
     fn compute_bounds(
         ccx: &CrateCtxt,
         param_ty: ty::param_ty,
-        ast_bounds: &OptVec<ast::TyParamBound>) -> ty::ParamBounds
+        ast_bounds: &OwnedSlice<ast::TyParamBound>) -> ty::ParamBounds
     {
         /*!
          * Translate the AST's notion of ty param bounds (which are an
@@ -1113,7 +1113,7 @@ pub fn mk_item_substs(ccx: &CrateCtxt,
         ty_generics.type_param_defs().iter().enumerate().map(
             |(i, t)| ty::mk_param(ccx.tcx, i, t.def_id)).collect();
 
-    let regions: OptVec<ty::Region> =
+    let regions: OwnedSlice<ty::Region> =
         ty_generics.region_param_defs().iter().enumerate().map(
             |(i, l)| ty::ReEarlyBound(l.def_id.node, i, l.name)).collect();
 
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 2af6ed0266a..1516a7bec34 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -66,7 +66,7 @@ use std::result;
 
 use syntax::ast::{Onceness, Purity};
 use syntax::ast;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::abi::AbiSet;
 
 pub trait Combine {
@@ -160,7 +160,7 @@ pub trait Combine {
 
                     assert_eq!(num_region_params, a_rs.len());
                     assert_eq!(num_region_params, b_rs.len());
-                    let mut rs = opt_vec::Empty;
+                    let mut rs = vec!();
                     for i in range(0, num_region_params) {
                         let a_r = *a_rs.get(i);
                         let b_r = *b_rs.get(i);
@@ -176,7 +176,7 @@ pub trait Combine {
                         };
                         rs.push(if_ok!(r));
                     }
-                    Ok(ty::NonerasedRegions(rs))
+                    Ok(ty::NonerasedRegions(OwnedSlice::from_vec(rs)))
                 }
             }
         }
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs
index 53c39068fb9..4cd9d46ff7a 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/typeck/infer/error_reporting.rs
@@ -80,8 +80,6 @@ use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
 use syntax::ast_util::name_to_dummy_lifetime;
-use syntax::opt_vec;
-use syntax::opt_vec::OptVec;
 use syntax::parse::token;
 use syntax::print::pprust;
 use util::ppaux::UserString;
@@ -90,10 +88,10 @@ use util::ppaux::note_and_explain_region;
 
 pub trait ErrorReporting {
     fn report_region_errors(&self,
-                            errors: &OptVec<RegionResolutionError>);
+                            errors: &Vec<RegionResolutionError>);
 
-    fn process_errors(&self, errors: &OptVec<RegionResolutionError>)
-                      -> OptVec<RegionResolutionError>;
+    fn process_errors(&self, errors: &Vec<RegionResolutionError>)
+                      -> Vec<RegionResolutionError>;
 
     fn report_type_error(&self, trace: TypeTrace, terr: &ty::type_err);
 
@@ -151,7 +149,7 @@ trait ErrorReportingHelpers {
 
 impl<'a> ErrorReporting for InferCtxt<'a> {
     fn report_region_errors(&self,
-                            errors: &OptVec<RegionResolutionError>) {
+                            errors: &Vec<RegionResolutionError>) {
         let p_errors = self.process_errors(errors);
         let errors = if p_errors.is_empty() { errors } else { &p_errors };
         for error in errors.iter() {
@@ -195,12 +193,12 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
     // complete view of what lifetimes should be the same.
     // If the return value is an empty vector, it means that processing
     // failed (so the return value of this method should not be used)
-    fn process_errors(&self, errors: &OptVec<RegionResolutionError>)
-                      -> OptVec<RegionResolutionError> {
+    fn process_errors(&self, errors: &Vec<RegionResolutionError>)
+                      -> Vec<RegionResolutionError> {
         let mut var_origins = Vec::new();
         let mut trace_origins = Vec::new();
         let mut same_regions = Vec::new();
-        let mut processed_errors = opt_vec::Empty;
+        let mut processed_errors = Vec::new();
         for error in errors.iter() {
             match *error {
                 ConcreteFailure(origin, sub, sup) => {
@@ -239,7 +237,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
                 // declaration, we want to make sure that they are, in fact,
                 // from the same scope
                 if sr.scope_id != common_scope_id {
-                    return opt_vec::Empty;
+                    return vec!();
                 }
             }
             let pe = ProcessedErrors(var_origins, trace_origins, same_regions);
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 923822039b1..b1a1a6e3bd1 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -43,7 +43,7 @@ use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::Span;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 use util::common::indent;
 use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr};
 
@@ -668,7 +668,7 @@ impl<'a> InferCtxt<'a> {
     pub fn region_vars_for_defs(&self,
                                 span: Span,
                                 defs: &[ty::RegionParameterDef])
-                                -> OptVec<ty::Region> {
+                                -> OwnedSlice<ty::Region> {
         defs.iter()
             .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
             .collect()
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 7d2159b5b68..7c13c15ffec 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -29,8 +29,6 @@ use std::uint;
 use std::slice;
 use collections::{HashMap, HashSet};
 use syntax::ast;
-use syntax::opt_vec;
-use syntax::opt_vec::OptVec;
 
 mod doc;
 
@@ -561,9 +559,9 @@ impl<'a> RegionVarBindings<'a> {
     constraints, assuming such values can be found; if they cannot,
     errors are reported.
     */
-    pub fn resolve_regions(&self) -> OptVec<RegionResolutionError> {
+    pub fn resolve_regions(&self) -> Vec<RegionResolutionError> {
         debug!("RegionVarBindings: resolve_regions()");
-        let mut errors = opt_vec::Empty;
+        let mut errors = vec!();
         let v = self.infer_variable_values(&mut errors);
         let mut values = self.values.borrow_mut();
         *values.get() = Some(v);
@@ -815,7 +813,7 @@ type RegionGraph = graph::Graph<(), Constraint>;
 
 impl<'a> RegionVarBindings<'a> {
     fn infer_variable_values(&self,
-                             errors: &mut OptVec<RegionResolutionError>)
+                             errors: &mut Vec<RegionResolutionError>)
                              -> Vec<VarValue> {
         let mut var_data = self.construct_var_data();
         self.expansion(var_data.as_mut_slice());
@@ -1004,7 +1002,7 @@ impl<'a> RegionVarBindings<'a> {
 
     fn collect_concrete_region_errors(
         &self,
-        errors: &mut OptVec<RegionResolutionError>)
+        errors: &mut Vec<RegionResolutionError>)
     {
         let constraints = self.constraints.borrow();
         for (constraint, _) in constraints.get().iter() {
@@ -1033,7 +1031,7 @@ impl<'a> RegionVarBindings<'a> {
     fn extract_values_and_collect_conflicts(
         &self,
         var_data: &[VarData],
-        errors: &mut OptVec<RegionResolutionError>)
+        errors: &mut Vec<RegionResolutionError>)
         -> Vec<VarValue> {
         debug!("extract_values_and_collect_conflicts()");
 
@@ -1157,7 +1155,7 @@ impl<'a> RegionVarBindings<'a> {
         var_data: &[VarData],
         dup_vec: &mut [uint],
         node_idx: RegionVid,
-        errors: &mut OptVec<RegionResolutionError>)
+        errors: &mut Vec<RegionResolutionError>)
     {
         // Errors in expanding nodes result from a lower-bound that is
         // not contained by an upper-bound.
@@ -1206,7 +1204,7 @@ impl<'a> RegionVarBindings<'a> {
         var_data: &[VarData],
         dup_vec: &mut [uint],
         node_idx: RegionVid,
-        errors: &mut OptVec<RegionResolutionError>)
+        errors: &mut Vec<RegionResolutionError>)
     {
         // Errors in contracting nodes result from two upper-bounds
         // that have no intersection.
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs
index 995d3589c20..cef047fae5d 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc/middle/typeck/rscope.rs
@@ -14,7 +14,7 @@ use middle::ty;
 use std::cell::Cell;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 
 /// Defines strategies for handling regions that are omitted.  For
 /// example, if one writes the type `&Foo`, then the lifetime of
@@ -74,7 +74,7 @@ impl RegionScope for BindingRscope {
 }
 
 pub fn bound_type_regions(defs: &[ty::RegionParameterDef])
-                          -> OptVec<ty::Region> {
+                          -> OwnedSlice<ty::Region> {
     assert!(defs.iter().all(|def| def.def_id.krate == ast::LOCAL_CRATE));
     defs.iter().enumerate().map(
         |(i, def)| ty::ReEarlyBound(def.def_id.node, i, def.name)).collect()
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index db74ad99d81..8748c332170 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -199,7 +199,7 @@ use middle::ty;
 use std::fmt;
 use syntax::ast;
 use syntax::ast_util;
-use syntax::opt_vec;
+use syntax::owned_slice::OwnedSlice;
 use syntax::visit;
 use syntax::visit::Visitor;
 use util::ppaux::Repr;
@@ -286,8 +286,8 @@ fn determine_parameters_to_be_inferred<'a>(tcx: &'a ty::ctxt,
         // cache and share the variance struct used for items with
         // no type/region parameters
         empty_variances: @ty::ItemVariances { self_param: None,
-                                              type_params: opt_vec::Empty,
-                                              region_params: opt_vec::Empty }
+                                              type_params: OwnedSlice::empty(),
+                                              region_params: OwnedSlice::empty() }
     };
 
     visit::walk_crate(&mut terms_cx, krate, ());
@@ -904,32 +904,33 @@ impl<'a> SolveContext<'a> {
         let num_inferred = self.terms_cx.num_inferred();
         while index < num_inferred {
             let item_id = inferred_infos.get(index).item_id;
-            let mut item_variances = ty::ItemVariances {
-                self_param: None,
-                type_params: opt_vec::Empty,
-                region_params: opt_vec::Empty
-            };
+            let mut self_param = None;
+            let mut type_params = vec!();
+            let mut region_params = vec!();
+
             while index < num_inferred &&
                   inferred_infos.get(index).item_id == item_id {
                 let info = inferred_infos.get(index);
                 match info.kind {
                     SelfParam => {
-                        assert!(item_variances.self_param.is_none());
-                        item_variances.self_param =
-                            Some(*solutions.get(index));
+                        assert!(self_param.is_none());
+                        self_param = Some(*solutions.get(index));
                     }
                     TypeParam => {
-                        item_variances.type_params
-                                      .push(*solutions.get(index));
+                        type_params.push(*solutions.get(index));
                     }
                     RegionParam => {
-                        item_variances.region_params
-                                      .push(*solutions.get(index));
+                        region_params.push(*solutions.get(index));
                     }
                 }
                 index += 1;
             }
 
+            let item_variances = ty::ItemVariances {
+                self_param: self_param,
+                type_params: OwnedSlice::from_vec(type_params),
+                region_params: OwnedSlice::from_vec(region_params)
+            };
             debug!("item_id={} item_variances={}",
                     item_id,
                     item_variances.repr(tcx));
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 4e0a9c3fc3d..b2568c60dc0 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -29,8 +29,7 @@ use syntax::codemap::{Span, Pos};
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::{ast, ast_util};
-use syntax::opt_vec;
-use syntax::opt_vec::OptVec;
+use syntax::owned_slice::OwnedSlice;
 
 /// Produces a string suitable for debugging output.
 pub trait Repr {
@@ -606,12 +605,9 @@ impl<'a, T:Repr> Repr for &'a [T] {
     }
 }
 
-impl<T:Repr> Repr for OptVec<T> {
+impl<T:Repr> Repr for OwnedSlice<T> {
     fn repr(&self, tcx: &ctxt) -> ~str {
-        match *self {
-            opt_vec::Empty => ~"[]",
-            opt_vec::Vec(ref v) => repr_vec(tcx, v.as_slice())
-        }
+        repr_vec(tcx, self.as_slice())
     }
 }
 
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index c18349d8d5a..e8854215c00 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -56,12 +56,9 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
     }
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::opt_vec::OptVec<T> {
+impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
     fn clean(&self) -> Vec<U> {
-        match self {
-            &syntax::opt_vec::Empty => Vec::new(),
-            &syntax::opt_vec::Vec(ref v) => v.clean()
-        }
+        self.iter().map(|x| x.clean()).collect()
     }
 }
 
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 47eb275823a..34e4256e538 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -121,6 +121,19 @@ impl<T> Vec<T> {
         }
     }
 
+    /// Create a `Vec<T>` directly from the raw constituents.
+    ///
+    /// This is highly unsafe:
+    ///
+    /// - if `ptr` is null, then `length` and `capacity` should be 0
+    /// - `ptr` must point to an allocation of size `capacity`
+    /// - there must be `length` valid instances of type `T` at the
+    ///   beginning of that allocation
+    /// - `ptr` must be allocated by the default `Vec` allocator
+    pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut T) -> Vec<T> {
+        Vec { len: length, cap: capacity, ptr: ptr }
+    }
+
     /// Consumes the `Vec`, partitioning it based on a predcate.
     ///
     /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index baea0a19f96..41038705d4d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -13,7 +13,7 @@
 use codemap::{Span, Spanned, DUMMY_SP};
 use abi::AbiSet;
 use ast_util;
-use opt_vec::OptVec;
+use owned_slice::OwnedSlice;
 use parse::token::{InternedString, special_idents, str_to_ident};
 use parse::token;
 
@@ -143,7 +143,7 @@ pub struct PathSegment {
     /// The lifetime parameters for this path segment.
     lifetimes: Vec<Lifetime>,
     /// The type parameters for this path segment, if present.
-    types: OptVec<P<Ty>>,
+    types: OwnedSlice<P<Ty>>,
 }
 
 pub type CrateNum = u32;
@@ -180,14 +180,14 @@ pub enum TyParamBound {
 pub struct TyParam {
     ident: Ident,
     id: NodeId,
-    bounds: OptVec<TyParamBound>,
+    bounds: OwnedSlice<TyParamBound>,
     default: Option<P<Ty>>
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, Hash)]
 pub struct Generics {
     lifetimes: Vec<Lifetime>,
-    ty_params: OptVec<TyParam>,
+    ty_params: OwnedSlice<TyParam>,
 }
 
 impl Generics {
@@ -799,7 +799,7 @@ pub struct ClosureTy {
     // implement issue #7264. None means "fn()", which means infer a default
     // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
     // which means use no bounds (e.g., not even Owned on a ~fn()).
-    bounds: Option<OptVec<TyParamBound>>,
+    bounds: Option<OwnedSlice<TyParamBound>>,
 }
 
 #[deriving(Eq, Encodable, Decodable, Hash)]
@@ -823,7 +823,7 @@ pub enum Ty_ {
     TyClosure(@ClosureTy),
     TyBareFn(@BareFnTy),
     TyTup(Vec<P<Ty>> ),
-    TyPath(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
+    TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
     TyTypeof(@Expr),
     // TyInfer means the type should be inferred instead of it having been
     // specified. This can appear anywhere in a type.
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 656ca1c88ba..9d841255aa9 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -13,7 +13,7 @@ use ast;
 use ast_util;
 use codemap;
 use codemap::Span;
-use opt_vec;
+use owned_slice::OwnedSlice;
 use parse::token;
 use print::pprust;
 use visit::Visitor;
@@ -196,7 +196,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
             ast::PathSegment {
                 identifier: identifier,
                 lifetimes: Vec::new(),
-                types: opt_vec::Empty,
+                types: OwnedSlice::empty(),
             }
         ),
     }
@@ -318,7 +318,7 @@ pub static as_prec: uint = 12u;
 
 pub fn empty_generics() -> Generics {
     Generics {lifetimes: Vec::new(),
-              ty_params: opt_vec::Empty}
+              ty_params: OwnedSlice::empty()}
 }
 
 // ______________________________________________________________________
@@ -709,12 +709,12 @@ pub fn get_inner_tys(ty: P<Ty>) -> Vec<P<Ty>> {
 mod test {
     use ast::*;
     use super::*;
-    use opt_vec;
+    use owned_slice::OwnedSlice;
 
     fn ident_to_segment(id : &Ident) -> PathSegment {
         PathSegment {identifier:id.clone(),
                      lifetimes: Vec::new(),
-                     types: opt_vec::Empty}
+                     types: OwnedSlice::empty()}
     }
 
     #[test] fn idents_name_eq_test() {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index e860866ebf9..1106dc61db7 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -16,8 +16,7 @@ use codemap::{Span, respan, DUMMY_SP};
 use ext::base::ExtCtxt;
 use ext::quote::rt::*;
 use fold::Folder;
-use opt_vec;
-use opt_vec::OptVec;
+use owned_slice::OwnedSlice;
 use parse::token::special_idents;
 use parse::token;
 
@@ -48,7 +47,7 @@ pub trait AstBuilder {
     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
 
     fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty>;
-    fn ty_path(&self, ast::Path, Option<OptVec<ast::TyParamBound>>) -> P<ast::Ty>;
+    fn ty_path(&self, ast::Path, Option<OwnedSlice<ast::TyParamBound>>) -> P<ast::Ty>;
     fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
 
     fn ty_rptr(&self, span: Span,
@@ -61,14 +60,14 @@ pub trait AstBuilder {
     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
     fn ty_nil(&self) -> P<ast::Ty>;
 
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> Vec<P<ast::Ty>> ;
-    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> Vec<P<ast::Ty>> ;
+    fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
+    fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
     fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
     fn strip_bounds(&self, bounds: &Generics) -> Generics;
 
     fn typaram(&self,
                id: ast::Ident,
-               bounds: OptVec<ast::TyParamBound>,
+               bounds: OwnedSlice<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
@@ -274,13 +273,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             ast::PathSegment {
                 identifier: ident,
                 lifetimes: Vec::new(),
-                types: opt_vec::Empty,
+                types: OwnedSlice::empty(),
             }
         }).collect();
         segments.push(ast::PathSegment {
             identifier: last_identifier,
             lifetimes: lifetimes,
-            types: opt_vec::from(types),
+            types: OwnedSlice::from_vec(types),
         });
         ast::Path {
             span: sp,
@@ -304,7 +303,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         })
     }
 
-    fn ty_path(&self, path: ast::Path, bounds: Option<OptVec<ast::TyParamBound>>)
+    fn ty_path(&self, path: ast::Path, bounds: Option<OwnedSlice<ast::TyParamBound>>)
               -> P<ast::Ty> {
         self.ty(path.span,
                 ast::TyPath(path, bounds, ast::DUMMY_NODE_ID))
@@ -366,7 +365,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn typaram(&self,
                id: ast::Ident,
-               bounds: OptVec<ast::TyParamBound>,
+               bounds: OwnedSlice<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam {
         ast::TyParam {
             ident: id,
@@ -379,20 +378,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     // these are strange, and probably shouldn't be used outside of
     // pipes. Specifically, the global version possible generates
     // incorrect code.
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> Vec<P<ast::Ty>> {
-        opt_vec::take_vec(
-            ty_params.map(|p| self.ty_ident(DUMMY_SP, p.ident)))
+    fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
+        ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect()
     }
 
-    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> Vec<P<ast::Ty>> {
-        opt_vec::take_vec(
-            ty_params.map(|p| self.ty_path(
-                self.path_global(DUMMY_SP, vec!(p.ident)), None)))
+    fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
+        ty_params.iter().map(|p| self.ty_path(
+                self.path_global(DUMMY_SP, vec!(p.ident)), None)).collect()
     }
 
     fn strip_bounds(&self, generics: &Generics) -> Generics {
         let new_params = generics.ty_params.map(|ty_param| {
-            ast::TyParam { bounds: opt_vec::Empty, ..*ty_param }
+            ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
         });
         Generics {
             ty_params: new_params,
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 45a20afab7d..8441fa719ea 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -12,7 +12,7 @@ use ast;
 use codemap::Span;
 use ext::base::*;
 use ext::base;
-use opt_vec;
+use owned_slice::OwnedSlice;
 use parse::token;
 use parse::token::{str_to_ident};
 
@@ -52,7 +52,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     ast::PathSegment {
                         identifier: res,
                         lifetimes: Vec::new(),
-                        types: opt_vec::Empty,
+                        types: OwnedSlice::empty(),
                     }
                 )
             }
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 546c3eac41c..89a8b2cd336 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -184,7 +184,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap;
 use codemap::Span;
-use opt_vec;
+use owned_slice::OwnedSlice;
 use parse::token::InternedString;
 
 use std::vec;
@@ -360,27 +360,32 @@ impl<'a> TraitDef<'a> {
                            methods: Vec<@ast::Method> ) -> @ast::Item {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
-        let mut trait_generics = self.generics.to_generics(cx, self.span,
-                                                           type_ident, generics);
+        let Generics { mut lifetimes, ty_params } =
+            self.generics.to_generics(cx, self.span, type_ident, generics);
+        let mut ty_params = ty_params.into_vec();
+
         // Copy the lifetimes
-        for l in generics.lifetimes.iter() {
-            trait_generics.lifetimes.push(*l)
-        };
+        lifetimes.extend(&mut generics.lifetimes.iter().map(|l| *l));
+
         // Create the type parameters.
-        for ty_param in generics.ty_params.iter() {
+        ty_params.extend(&mut generics.ty_params.iter().map(|ty_param| {
             // I don't think this can be moved out of the loop, since
             // a TyParamBound requires an ast id
-            let mut bounds = opt_vec::from(
+            let mut bounds =
                 // extra restrictions on the generics parameters to the type being derived upon
                 self.additional_bounds.map(|p| {
                     cx.typarambound(p.to_path(cx, self.span,
                                                   type_ident, generics))
-                }));
+                });
             // require the current trait
             bounds.push(cx.typarambound(trait_path.clone()));
 
-            trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds, None));
-        }
+            cx.typaram(ty_param.ident, OwnedSlice::from_vec(bounds), None)
+        }));
+        let trait_generics = Generics {
+            lifetimes: lifetimes,
+            ty_params: OwnedSlice::from_vec(ty_params)
+        };
 
         // Create the reference to the trait.
         let trait_ref = cx.trait_ref(trait_path);
@@ -395,7 +400,7 @@ impl<'a> TraitDef<'a> {
         // Create the type of `self`.
         let self_type = cx.ty_path(
             cx.path_all(self.span, false, vec!( type_ident ), self_lifetimes,
-                        opt_vec::take_vec(self_ty_params)), None);
+                        self_ty_params.into_vec()), None);
 
         let attr = cx.attribute(
             self.span,
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 5b29af185a4..bfdfba7ba78 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -18,7 +18,7 @@ use ast::{P,Expr,Generics,Ident};
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap::{Span,respan};
-use opt_vec;
+use owned_slice::OwnedSlice;
 
 /// The types of pointers
 pub enum PtrTy<'a> {
@@ -116,11 +116,10 @@ fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifet
 }
 
 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
-    let lifetimes = match *lt {
-        Some(ref s) => opt_vec::with(cx.lifetime(span, cx.ident_of(*s).name)),
-        None => opt_vec::Empty
-    };
-    opt_vec::take_vec(lifetimes)
+    match *lt {
+        Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
+        None => vec!()
+    }
 }
 
 impl<'a> Ty<'a> {
@@ -173,7 +172,7 @@ impl<'a> Ty<'a> {
                 let lifetimes = self_generics.lifetimes.clone();
 
                 cx.path_all(span, false, vec!(self_ty), lifetimes,
-                            opt_vec::take_vec(self_params))
+                            self_params.into_vec())
             }
             Literal(ref p) => {
                 p.to_path(cx, span, self_ty, self_generics)
@@ -187,18 +186,18 @@ impl<'a> Ty<'a> {
 
 fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, bounds: &[Path],
                self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
-    let bounds = opt_vec::from(
+    let bounds =
         bounds.iter().map(|b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
             cx.typarambound(path)
-        }).collect());
+        }).collect();
     cx.typaram(cx.ident_of(name), bounds, None)
 }
 
 fn mk_generics(lifetimes: Vec<ast::Lifetime> ,  ty_params: Vec<ast::TyParam> ) -> Generics {
     Generics {
         lifetimes: lifetimes,
-        ty_params: opt_vec::from(ty_params)
+        ty_params: OwnedSlice::from_vec(ty_params)
     }
 }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index e1a41471de4..0afde5be9a0 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -13,7 +13,7 @@ use ast;
 use ast_util;
 use codemap::{respan, Span, Spanned};
 use parse::token;
-use opt_vec::OptVec;
+use owned_slice::OwnedSlice;
 use util::small_vector::SmallVector;
 
 // We may eventually want to be able to fold over type parameters, too.
@@ -424,8 +424,8 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
     }
 }
 
-pub fn fold_ty_params<T: Folder>(tps: &OptVec<TyParam>, fld: &mut T)
-                                   -> OptVec<TyParam> {
+pub fn fold_ty_params<T: Folder>(tps: &OwnedSlice<TyParam>, fld: &mut T)
+                                   -> OwnedSlice<TyParam> {
     tps.map(|tp| fold_ty_param(tp, fld))
 }
 
@@ -493,8 +493,8 @@ fn fold_mt<T: Folder>(mt: &MutTy, folder: &mut T) -> MutTy {
     }
 }
 
-fn fold_opt_bounds<T: Folder>(b: &Option<OptVec<TyParamBound>>, folder: &mut T)
-                              -> Option<OptVec<TyParamBound>> {
+fn fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut T)
+                              -> Option<OwnedSlice<TyParamBound>> {
     b.as_ref().map(|bounds| {
         bounds.map(|bound| {
             fold_ty_param_bound(bound, folder)
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index cea531ee3b3..70fb96e4c5f 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -49,7 +49,7 @@ pub mod syntax {
     pub use parse;
 }
 
-pub mod opt_vec;
+pub mod owned_slice;
 pub mod attr;
 pub mod diagnostic;
 pub mod codemap;
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
deleted file mode 100644
index aeb521468d2..00000000000
--- a/src/libsyntax/opt_vec.rs
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * Defines a type OptVec<T> that can be used in place of ~[T].
- * OptVec avoids the need for allocation for empty vectors.
- * OptVec implements the iterable interface as well as
- * other useful things like `push()` and `len()`.
- */
-
-use std::default::Default;
-use std::slice;
-
-#[deriving(Clone, Encodable, Decodable, Hash)]
-pub enum OptVec<T> {
-    Empty,
-    Vec(Vec<T> )
-}
-
-pub fn with<T>(t: T) -> OptVec<T> {
-    Vec(vec!(t))
-}
-
-pub fn from<T>(t: Vec<T> ) -> OptVec<T> {
-    if t.len() == 0 {
-        Empty
-    } else {
-        Vec(t)
-    }
-}
-
-impl<T> OptVec<T> {
-    pub fn push(&mut self, t: T) {
-        match *self {
-            Vec(ref mut v) => {
-                v.push(t);
-                return;
-            }
-            Empty => {
-                *self = Vec(vec!(t));
-            }
-        }
-    }
-
-    pub fn pop(&mut self) -> Option<T> {
-        match *self {
-            Vec(ref mut v) => v.pop(),
-            Empty => None
-        }
-    }
-
-    pub fn last<'a>(&'a self) -> Option<&'a T> {
-        match *self {
-            Vec(ref v) => v.last(),
-            Empty => None
-        }
-    }
-
-    pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
-        match *self {
-            Vec(ref mut v) => v.mut_last(),
-            Empty => None
-        }
-    }
-
-    pub fn map<U>(&self, op: |&T| -> U) -> OptVec<U> {
-        match *self {
-            Empty => Empty,
-            Vec(ref v) => Vec(v.map(op))
-        }
-    }
-
-    pub fn map_move<U>(self, op: |T| -> U) -> OptVec<U> {
-        match self {
-            Empty => Empty,
-            Vec(v) => Vec(v.move_iter().map(op).collect())
-        }
-    }
-
-    pub fn get<'a>(&'a self, i: uint) -> &'a T {
-        match *self {
-            Empty => fail!("invalid index {}", i),
-            Vec(ref v) => v.get(i)
-        }
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.len() == 0
-    }
-
-    pub fn len(&self) -> uint {
-        match *self {
-            Empty => 0,
-            Vec(ref v) => v.len()
-        }
-    }
-
-    pub fn swap_remove(&mut self, index: uint) {
-        match *self {
-            Empty => { fail!("index out of bounds"); }
-            Vec(ref mut v) => {
-                assert!(index < v.len());
-                v.swap_remove(index);
-            }
-        }
-    }
-
-    #[inline]
-    pub fn iter<'r>(&'r self) -> Items<'r, T> {
-        match *self {
-            Empty => Items{iter: None},
-            Vec(ref v) => Items{iter: Some(v.iter())}
-        }
-    }
-
-    #[inline]
-    pub fn map_to_vec<B>(&self, op: |&T| -> B) -> Vec<B> {
-        self.iter().map(op).collect()
-    }
-
-    pub fn mapi_to_vec<B>(&self, op: |uint, &T| -> B) -> Vec<B> {
-        let mut index = 0;
-        self.map_to_vec(|a| {
-            let i = index;
-            index += 1;
-            op(i, a)
-        })
-    }
-}
-
-pub fn take_vec<T>(v: OptVec<T>) -> Vec<T> {
-    match v {
-        Empty => Vec::new(),
-        Vec(v) => v
-    }
-}
-
-impl<T:Clone> OptVec<T> {
-    pub fn prepend(&self, t: T) -> OptVec<T> {
-        let mut v0 = vec!(t);
-        match *self {
-            Empty => {}
-            Vec(ref v1) => { v0.push_all(v1.as_slice()); }
-        }
-        return Vec(v0);
-    }
-}
-
-impl<A:Eq> Eq for OptVec<A> {
-    fn eq(&self, other: &OptVec<A>) -> bool {
-        // Note: cannot use #[deriving(Eq)] here because
-        // (Empty, Vec(~[])) ought to be equal.
-        match (self, other) {
-            (&Empty, &Empty) => true,
-            (&Empty, &Vec(ref v)) => v.is_empty(),
-            (&Vec(ref v), &Empty) => v.is_empty(),
-            (&Vec(ref v1), &Vec(ref v2)) => *v1 == *v2
-        }
-    }
-
-    fn ne(&self, other: &OptVec<A>) -> bool {
-        !self.eq(other)
-    }
-}
-
-impl<T> Default for OptVec<T> {
-    fn default() -> OptVec<T> { Empty }
-}
-
-pub struct Items<'a, T> {
-    priv iter: Option<slice::Items<'a, T>>
-}
-
-impl<'a, T> Iterator<&'a T> for Items<'a, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'a T> {
-        match self.iter {
-            Some(ref mut x) => x.next(),
-            None => None
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        match self.iter {
-            Some(ref x) => x.size_hint(),
-            None => (0, Some(0))
-        }
-    }
-}
-
-impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a T> {
-        match self.iter {
-            Some(ref mut x) => x.next_back(),
-            None => None
-        }
-    }
-}
-
-impl<A> FromIterator<A> for OptVec<A> {
-    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> OptVec<A> {
-        let mut r = Empty;
-        for x in *iterator {
-            r.push(x);
-        }
-        r
-    }
-}
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
new file mode 100644
index 00000000000..df38945f198
--- /dev/null
+++ b/src/libsyntax/owned_slice.rs
@@ -0,0 +1,142 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::default::Default;
+use std::hash::Hash;
+use std::{cast, mem, raw, ptr, slice};
+use serialize::{Encodable, Decodable, Encoder, Decoder};
+
+/// A non-growable owned slice. This would preferably become `~[T]`
+/// under DST.
+#[unsafe_no_drop_flag] // data is set to null on destruction
+pub struct OwnedSlice<T> {
+    /// null iff len == 0
+    priv data: *mut T,
+    priv len: uint,
+}
+
+#[unsafe_destructor]
+impl<T> Drop for OwnedSlice<T> {
+    fn drop(&mut self) {
+        if self.data.is_null() { return }
+
+        // extract the vector
+        let v = mem::replace(self, OwnedSlice::empty());
+        // free via the Vec destructor
+        v.into_vec();
+    }
+}
+
+impl<T> OwnedSlice<T> {
+    pub fn empty() -> OwnedSlice<T> {
+        OwnedSlice  { data: ptr::mut_null(), len: 0 }
+    }
+
+    #[inline(never)]
+    pub fn from_vec(mut v: Vec<T>) -> OwnedSlice<T> {
+        let len = v.len();
+
+        if len == 0 {
+            OwnedSlice::empty()
+        } else {
+            let p = v.as_mut_ptr();
+            // we own the allocation now
+            unsafe {cast::forget(v)}
+
+            OwnedSlice { data: p, len: len }
+        }
+    }
+
+    #[inline(never)]
+    pub fn into_vec(self) -> Vec<T> {
+        // null is ok, because len == 0 in that case, as required by Vec.
+        unsafe {
+            let ret = Vec::from_raw_parts(self.len, self.len, self.data);
+            // the vector owns the allocation now
+            cast::forget(self);
+            ret
+        }
+    }
+
+    pub fn as_slice<'a>(&'a self) -> &'a [T] {
+        static PTR_MARKER: u8 = 0;
+        let ptr = if self.data.is_null() {
+            // length zero, i.e. this will never be read as a T.
+            &PTR_MARKER as *u8 as *T
+        } else {
+            self.data as *T
+        };
+
+        let slice: &[T] = unsafe {cast::transmute(raw::Slice {
+            data: ptr,
+            len: self.len
+        })};
+
+        slice
+    }
+
+    pub fn get<'a>(&'a self, i: uint) -> &'a T {
+        self.as_slice().get(i).expect("OwnedSlice: index out of bounds")
+    }
+
+    pub fn iter<'r>(&'r self) -> slice::Items<'r, T> {
+        self.as_slice().iter()
+    }
+
+    pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
+        self.iter().map(f).collect()
+    }
+}
+
+impl<T> Default for OwnedSlice<T> {
+    fn default() -> OwnedSlice<T> {
+        OwnedSlice::empty()
+    }
+}
+
+impl<T: Clone> Clone for OwnedSlice<T> {
+    fn clone(&self) -> OwnedSlice<T> {
+        OwnedSlice::from_vec(Vec::from_slice(self.as_slice()))
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for OwnedSlice<T> {
+    fn hash(&self, state: &mut S) {
+        self.as_slice().hash(state)
+    }
+}
+
+impl<T: Eq> Eq for OwnedSlice<T> {
+    fn eq(&self, other: &OwnedSlice<T>) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl<T> Container for OwnedSlice<T> {
+    fn len(&self) -> uint { self.len }
+}
+
+impl<T> FromIterator<T> for OwnedSlice<T> {
+    fn from_iterator<I: Iterator<T>>(iter: &mut I) -> OwnedSlice<T> {
+        OwnedSlice::from_vec(iter.collect())
+    }
+}
+
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for OwnedSlice<T> {
+    fn encode(&self, s: &mut S) {
+       self.as_slice().encode(s)
+    }
+}
+
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for OwnedSlice<T> {
+    fn decode(d: &mut D) -> OwnedSlice<T> {
+        OwnedSlice::from_vec(Decodable::decode(d))
+    }
+}
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 286b44e5c80..eb6b462fb94 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -279,7 +279,7 @@ mod test {
     use std::io::MemWriter;
     use std::str;
     use codemap::{Span, BytePos, Spanned};
-    use opt_vec;
+    use owned_slice::OwnedSlice;
     use ast;
     use abi;
     use parse::parser::Parser;
@@ -312,7 +312,7 @@ mod test {
                             ast::PathSegment {
                                 identifier: str_to_ident("a"),
                                 lifetimes: Vec::new(),
-                                types: opt_vec::Empty,
+                                types: OwnedSlice::empty(),
                             }
                         ),
                     }),
@@ -331,12 +331,12 @@ mod test {
                                 ast::PathSegment {
                                     identifier: str_to_ident("a"),
                                     lifetimes: Vec::new(),
-                                    types: opt_vec::Empty,
+                                    types: OwnedSlice::empty(),
                                 },
                                 ast::PathSegment {
                                     identifier: str_to_ident("b"),
                                     lifetimes: Vec::new(),
-                                    types: opt_vec::Empty,
+                                    types: OwnedSlice::empty(),
                                 }
                             )
                         }),
@@ -545,7 +545,7 @@ mod test {
                                 ast::PathSegment {
                                     identifier: str_to_ident("d"),
                                     lifetimes: Vec::new(),
-                                    types: opt_vec::Empty,
+                                    types: OwnedSlice::empty(),
                                 }
                             ),
                         }),
@@ -567,7 +567,7 @@ mod test {
                                 ast::PathSegment {
                                     identifier: str_to_ident("b"),
                                     lifetimes: Vec::new(),
-                                    types: opt_vec::Empty,
+                                    types: OwnedSlice::empty(),
                                 }
                                ),
                             }),
@@ -595,7 +595,7 @@ mod test {
                                         ast::PathSegment {
                                             identifier: str_to_ident("b"),
                                             lifetimes: Vec::new(),
-                                            types: opt_vec::Empty,
+                                            types: OwnedSlice::empty(),
                                         }
                                     ),
                                 },
@@ -623,7 +623,7 @@ mod test {
                                                 identifier:
                                                     str_to_ident("int"),
                                                 lifetimes: Vec::new(),
-                                                types: opt_vec::Empty,
+                                                types: OwnedSlice::empty(),
                                             }
                                         ),
                                         }, None, ast::DUMMY_NODE_ID),
@@ -641,7 +641,7 @@ mod test {
                                                         identifier:
                                                             str_to_ident("b"),
                                                         lifetimes: Vec::new(),
-                                                        types: opt_vec::Empty,
+                                                        types: OwnedSlice::empty(),
                                                     }
                                                 ),
                                             },
@@ -661,7 +661,7 @@ mod test {
                                     abi::AbiSet::Rust(),
                                     ast::Generics{ // no idea on either of these:
                                         lifetimes: Vec::new(),
-                                        ty_params: opt_vec::Empty,
+                                        ty_params: OwnedSlice::empty(),
                                     },
                                     ast::P(ast::Block {
                                         view_items: Vec::new(),
@@ -680,7 +680,7 @@ mod test {
                                                                 lifetimes:
                                                                 Vec::new(),
                                                                 types:
-                                                                opt_vec::Empty
+                                                                OwnedSlice::empty()
                                                             }
                                                         ),
                                                       }),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 5398844d52a..c8492cc4113 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -75,8 +75,7 @@ use parse::token::{is_ident, is_ident_or_path, is_plain_ident};
 use parse::token::{keywords, special_idents, token_to_binop};
 use parse::token;
 use parse::{new_sub_parser_from_file, ParseSess};
-use opt_vec;
-use opt_vec::OptVec;
+use owned_slice::OwnedSlice;
 
 use std::cell::Cell;
 use collections::HashSet;
@@ -117,13 +116,13 @@ pub enum PathParsingMode {
 /// for the definition of a path segment.)
 struct PathSegmentAndBoundSet {
     segment: ast::PathSegment,
-    bound_set: Option<OptVec<TyParamBound>>,
+    bound_set: Option<OwnedSlice<TyParamBound>>,
 }
 
 /// A path paired with optional type bounds.
 pub struct PathAndBounds {
     path: ast::Path,
-    bounds: Option<OptVec<TyParamBound>>,
+    bounds: Option<OwnedSlice<TyParamBound>>,
 }
 
 enum ItemOrViewItem {
@@ -630,9 +629,9 @@ impl<'a> Parser<'a> {
                                   &mut self,
                                   sep: Option<token::Token>,
                                   f: |&mut Parser| -> T)
-                                  -> OptVec<T> {
+                                  -> OwnedSlice<T> {
         let mut first = true;
-        let mut v = opt_vec::Empty;
+        let mut v = Vec::new();
         while self.token != token::GT
             && self.token != token::BINOP(token::SHR) {
             match sep {
@@ -644,14 +643,14 @@ impl<'a> Parser<'a> {
             }
             v.push(f(self));
         }
-        return v;
+        return OwnedSlice::from_vec(v);
     }
 
     pub fn parse_seq_to_gt<T>(
                            &mut self,
                            sep: Option<token::Token>,
                            f: |&mut Parser| -> T)
-                           -> OptVec<T> {
+                           -> OwnedSlice<T> {
         let v = self.parse_seq_to_before_gt(sep, f);
         self.expect_gt();
         return v;
@@ -681,7 +680,7 @@ impl<'a> Parser<'a> {
                                    f: |&mut Parser| -> T)
                                    -> Vec<T> {
         let mut first: bool = true;
-        let mut v: Vec<T> = Vec::new();
+        let mut v = vec!();
         while self.token != *ket {
             match sep.sep {
               Some(ref t) => {
@@ -1531,7 +1530,7 @@ impl<'a> Parser<'a> {
                     segment: ast::PathSegment {
                         identifier: identifier,
                         lifetimes: Vec::new(),
-                        types: opt_vec::Empty,
+                        types: OwnedSlice::empty(),
                     },
                     bound_set: bound_set
                 });
@@ -1543,9 +1542,9 @@ impl<'a> Parser<'a> {
                 if mode != NoTypesAllowed && self.eat(&token::LT) {
                     let (lifetimes, types) =
                         self.parse_generic_values_after_lt();
-                    (true, lifetimes, opt_vec::from(types))
+                    (true, lifetimes, OwnedSlice::from_vec(types))
                 } else {
-                    (false, Vec::new(), opt_vec::Empty)
+                    (false, Vec::new(), OwnedSlice::empty())
                 }
             };
 
@@ -3432,12 +3431,12 @@ impl<'a> Parser<'a> {
     // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
     // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
     // NB: The None/Some distinction is important for issue #7264.
-    fn parse_optional_ty_param_bounds(&mut self) -> Option<OptVec<TyParamBound>> {
+    fn parse_optional_ty_param_bounds(&mut self) -> Option<OwnedSlice<TyParamBound>> {
         if !self.eat(&token::COLON) {
             return None;
         }
 
-        let mut result = opt_vec::Empty;
+        let mut result = vec!();
         loop {
             match self.token {
                 token::LIFETIME(lifetime) => {
@@ -3462,7 +3461,7 @@ impl<'a> Parser<'a> {
             }
         }
 
-        return Some(result);
+        return Some(OwnedSlice::from_vec(result));
     }
 
     // matches typaram = IDENT optbounds ( EQ ty )?
@@ -3515,7 +3514,7 @@ impl<'a> Parser<'a> {
         let result = self.parse_seq_to_gt(
             Some(token::COMMA),
             |p| p.parse_ty(false));
-        (lifetimes, opt_vec::take_vec(result))
+        (lifetimes, result.into_vec())
     }
 
     fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
@@ -4882,7 +4881,7 @@ impl<'a> Parser<'a> {
                     ast::PathSegment {
                         identifier: identifier,
                         lifetimes: Vec::new(),
-                        types: opt_vec::Empty,
+                        types: OwnedSlice::empty(),
                     }
                 }).collect()
             };
@@ -4917,7 +4916,7 @@ impl<'a> Parser<'a> {
                             ast::PathSegment {
                                 identifier: identifier,
                                 lifetimes: Vec::new(),
-                                types: opt_vec::Empty,
+                                types: OwnedSlice::empty(),
                             }
                         }).collect()
                     };
@@ -4935,7 +4934,7 @@ impl<'a> Parser<'a> {
                             ast::PathSegment {
                                 identifier: identifier,
                                 lifetimes: Vec::new(),
-                                types: opt_vec::Empty,
+                                types: OwnedSlice::empty(),
                             }
                         }).collect()
                     };
@@ -4957,7 +4956,7 @@ impl<'a> Parser<'a> {
                 ast::PathSegment {
                     identifier: identifier,
                     lifetimes: Vec::new(),
-                    types: opt_vec::Empty,
+                    types: OwnedSlice::empty(),
                 }
             }).collect()
         };
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 1b8f48861aa..9cecd5f6c2b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -12,8 +12,7 @@ use abi::AbiSet;
 use ast::{P, RegionTyParamBound, TraitTyParamBound, Required, Provided};
 use ast;
 use ast_util;
-use opt_vec::OptVec;
-use opt_vec;
+use owned_slice::OwnedSlice;
 use attr::{AttrMetaMethods, AttributeMethods};
 use codemap::{CodeMap, BytePos};
 use codemap;
@@ -478,7 +477,7 @@ impl<'a> State<'a> {
             ast::TyBareFn(f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: opt_vec::Empty
+                    ty_params: OwnedSlice::empty()
                 };
                 try!(self.print_ty_fn(Some(f.abis), None, &None,
                                    f.purity, ast::Many, f.decl, None, &None,
@@ -487,7 +486,7 @@ impl<'a> State<'a> {
             ast::TyClosure(f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: opt_vec::Empty
+                    ty_params: OwnedSlice::empty()
                 };
                 try!(self.print_ty_fn(None, Some(f.sigil), &f.region,
                                    f.purity, f.onceness, f.decl, None, &f.bounds,
@@ -1518,7 +1517,7 @@ impl<'a> State<'a> {
     fn print_path_(&mut self,
                    path: &ast::Path,
                    colons_before_params: bool,
-                   opt_bounds: &Option<OptVec<ast::TyParamBound>>)
+                   opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>)
         -> IoResult<()> {
         try!(self.maybe_print_comment(path.span.lo));
         if path.global {
@@ -1564,7 +1563,7 @@ impl<'a> State<'a> {
                     }
                     try!(self.commasep(
                         Inconsistent,
-                        segment.types.map_to_vec(|&t| t).as_slice(),
+                        segment.types.as_slice(),
                         |s, ty| s.print_type_ref(ty)));
                 }
 
@@ -1580,7 +1579,7 @@ impl<'a> State<'a> {
     }
 
     fn print_bounded_path(&mut self, path: &ast::Path,
-                          bounds: &Option<OptVec<ast::TyParamBound>>)
+                          bounds: &Option<OwnedSlice<ast::TyParamBound>>)
         -> IoResult<()> {
         self.print_path_(path, false, bounds)
     }
@@ -1826,7 +1825,7 @@ impl<'a> State<'a> {
         self.maybe_print_comment(decl.output.span.lo)
     }
 
-    pub fn print_bounds(&mut self, bounds: &OptVec<ast::TyParamBound>,
+    pub fn print_bounds(&mut self, bounds: &OwnedSlice<ast::TyParamBound>,
                         print_colon_anyway: bool) -> IoResult<()> {
         if !bounds.is_empty() {
             try!(word(&mut self.s, ":"));
@@ -2028,7 +2027,7 @@ impl<'a> State<'a> {
                        onceness: ast::Onceness,
                        decl: &ast::FnDecl,
                        id: Option<ast::Ident>,
-                       opt_bounds: &Option<OptVec<ast::TyParamBound>>,
+                       opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        generics: Option<&ast::Generics>,
                        opt_explicit_self: Option<ast::ExplicitSelf_>)
         -> IoResult<()> {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 482bac77777..de3eb1b9b8d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -13,8 +13,7 @@ use ast::*;
 use ast;
 use codemap::Span;
 use parse;
-use opt_vec;
-use opt_vec::OptVec;
+use owned_slice::OwnedSlice;
 
 // Context-passing AST walker. Each overridden visit method has full control
 // over what happens with its node, it can do its own traversal of the node's
@@ -56,7 +55,7 @@ pub fn generics_of_fn(fk: &FnKind) -> Generics {
         FkFnBlock(..) => {
             Generics {
                 lifetimes: Vec::new(),
-                ty_params: opt_vec::Empty,
+                ty_params: OwnedSlice::empty(),
             }
         }
     }
@@ -457,7 +456,7 @@ pub fn walk_foreign_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
 }
 
 pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                     bounds: &OptVec<TyParamBound>,
+                                                     bounds: &OwnedSlice<TyParamBound>,
                                                      env: E) {
     for bound in bounds.iter() {
         match *bound {