about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-11 05:01:38 -0700
committerbors <bors@rust-lang.org>2014-04-11 05:01:38 -0700
commit65abf96fb6630d7ddbcdc3b39f599c02ecfc2f1e (patch)
tree48c52b8d36d8c3568f2b00087eb6a18d81be9c2b
parent1b37afe8a2ab285ec1b15f5dbb072d005a8a4944 (diff)
parentee4c770f8ba364857b97a8c51c3eda14120b9ac5 (diff)
downloadrust-65abf96fb6630d7ddbcdc3b39f599c02ecfc2f1e.tar.gz
rust-65abf96fb6630d7ddbcdc3b39f599c02ecfc2f1e.zip
auto merge of #13424 : eddyb/rust/ty-mut-in-store, r=nikomatsakis
Cleans up some remnants of the old mutability system and only allows vector/trait mutability in `VstoreSlice` (`&mut [T]`) and `RegionTraitStore` (`&mut Trait`).
-rw-r--r--src/librustc/metadata/encoder.rs12
-rw-r--r--src/librustc/metadata/tydecode.rs24
-rw-r--r--src/librustc/metadata/tyencode.rs25
-rw-r--r--src/librustc/middle/astencode.rs49
-rw-r--r--src/librustc/middle/check_match.rs4
-rw-r--r--src/librustc/middle/lint.rs6
-rw-r--r--src/librustc/middle/mem_categorization.rs25
-rw-r--r--src/librustc/middle/trans/_match.rs8
-rw-r--r--src/librustc/middle/trans/base.rs10
-rw-r--r--src/librustc/middle/trans/callee.rs2
-rw-r--r--src/librustc/middle/trans/common.rs2
-rw-r--r--src/librustc/middle/trans/consts.rs22
-rw-r--r--src/librustc/middle/trans/debuginfo.rs42
-rw-r--r--src/librustc/middle/trans/expr.rs5
-rw-r--r--src/librustc/middle/trans/glue.rs4
-rw-r--r--src/librustc/middle/trans/reflect.rs26
-rw-r--r--src/librustc/middle/trans/tvec.rs70
-rw-r--r--src/librustc/middle/trans/type_of.rs32
-rw-r--r--src/librustc/middle/ty.rs189
-rw-r--r--src/librustc/middle/ty_fold.rs27
-rw-r--r--src/librustc/middle/typeck/astconv.rs91
-rw-r--r--src/librustc/middle/typeck/check/_match.rs31
-rw-r--r--src/librustc/middle/typeck/check/method.rs43
-rw-r--r--src/librustc/middle/typeck/check/mod.rs54
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs10
-rw-r--r--src/librustc/middle/typeck/check/regionmanip.rs6
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs37
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs45
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs50
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs1
-rw-r--r--src/librustc/middle/typeck/variance.rs24
-rw-r--r--src/librustc/util/ppaux.rs77
32 files changed, 490 insertions, 563 deletions
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index ac62702e59e..e2fb4e26e59 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -232,18 +232,6 @@ pub fn write_type(ecx: &EncodeContext,
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
-pub fn write_vstore(ecx: &EncodeContext,
-                    ebml_w: &mut Encoder,
-                    vstore: ty::vstore) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_str,
-        tcx: ecx.tcx,
-        abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
-    };
-    tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
-}
-
 fn encode_type(ecx: &EncodeContext,
                ebml_w: &mut Encoder,
                typ: ty::t) {
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 25971be6aac..f29b181125e 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -146,27 +146,28 @@ fn parse_sigil(st: &mut PState) -> ast::Sigil {
     }
 }
 
-fn parse_vstore(st: &mut PState, conv: conv_did) -> ty::vstore {
+fn parse_vstore<M>(st: &mut PState, conv: conv_did,
+                   parse_mut: |&mut PState| -> M) -> ty::Vstore<M> {
     assert_eq!(next(st), '/');
 
     let c = peek(st);
     if '0' <= c && c <= '9' {
         let n = parse_uint(st);
         assert_eq!(next(st), '|');
-        return ty::vstore_fixed(n);
+        return ty::VstoreFixed(n);
     }
 
     match next(st) {
-      '~' => ty::vstore_uniq,
-      '&' => ty::vstore_slice(parse_region(st, conv)),
-      c => st.tcx.sess.bug(format!("parse_vstore(): bad input '{}'", c))
+        '~' => ty::VstoreUniq,
+        '&' => ty::VstoreSlice(parse_region(st, conv), parse_mut(st)),
+        c => st.tcx.sess.bug(format!("parse_vstore(): bad input '{}'", c))
     }
 }
 
 fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
     match next(st) {
         '~' => ty::UniqTraitStore,
-        '&' => ty::RegionTraitStore(parse_region(st, conv)),
+        '&' => ty::RegionTraitStore(parse_region(st, conv), parse_mutability(st)),
         c => st.tcx.sess.bug(format!("parse_trait_store(): bad input '{}'", c))
     }
 }
@@ -328,10 +329,9 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         let def = parse_def(st, NominalType, |x,y| conv(x,y));
         let substs = parse_substs(st, |x,y| conv(x,y));
         let store = parse_trait_store(st, |x,y| conv(x,y));
-        let mt = parse_mutability(st);
         let bounds = parse_bounds(st, |x,y| conv(x,y));
         assert_eq!(next(st), ']');
-        return ty::mk_trait(st.tcx, def, substs, store, mt, bounds.builtin_bounds);
+        return ty::mk_trait(st.tcx, def, substs, store, bounds.builtin_bounds);
       }
       'p' => {
         let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
@@ -351,12 +351,12 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         return ty::mk_rptr(st.tcx, r, mt);
       }
       'V' => {
-        let mt = parse_mt(st, |x,y| conv(x,y));
-        let v = parse_vstore(st, |x,y| conv(x,y));
-        return ty::mk_vec(st.tcx, mt, v);
+        let ty = parse_ty(st, |x,y| conv(x,y));
+        let v = parse_vstore(st, |x,y| conv(x,y), parse_mutability);
+        return ty::mk_vec(st.tcx, ty, v);
       }
       'v' => {
-        let v = parse_vstore(st, |x,y| conv(x,y));
+        let v = parse_vstore(st, |x,y| conv(x,y), |_| ());
         return ty::mk_str(st.tcx, v);
       }
       'T' => {
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 485b28ca13b..d8c5197df27 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -204,14 +204,17 @@ fn enc_bound_region(w: &mut MemWriter, cx: &ctxt, br: ty::BoundRegion) {
     }
 }
 
-pub fn enc_vstore(w: &mut MemWriter, cx: &ctxt, v: ty::vstore) {
+pub fn enc_vstore<M>(w: &mut MemWriter, cx: &ctxt,
+                     v: ty::Vstore<M>,
+                     enc_mut: |&mut MemWriter, M|) {
     mywrite!(w, "/");
     match v {
-        ty::vstore_fixed(u) => mywrite!(w, "{}|", u),
-        ty::vstore_uniq => mywrite!(w, "~"),
-        ty::vstore_slice(r) => {
+        ty::VstoreFixed(u) => mywrite!(w, "{}|", u),
+        ty::VstoreUniq => mywrite!(w, "~"),
+        ty::VstoreSlice(r, m) => {
             mywrite!(w, "&");
             enc_region(w, cx, r);
+            enc_mut(w, m);
         }
     }
 }
@@ -224,9 +227,10 @@ pub fn enc_trait_ref(w: &mut MemWriter, cx: &ctxt, s: &ty::TraitRef) {
 pub fn enc_trait_store(w: &mut MemWriter, cx: &ctxt, s: ty::TraitStore) {
     match s {
         ty::UniqTraitStore => mywrite!(w, "~"),
-        ty::RegionTraitStore(re) => {
+        ty::RegionTraitStore(re, m) => {
             mywrite!(w, "&");
             enc_region(w, cx, re);
+            enc_mutability(w, m);
         }
     }
 }
@@ -266,11 +270,10 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, mutability, bounds }) => {
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, bounds }) => {
             mywrite!(w, "x[{}|", (cx.ds)(def_id));
             enc_substs(w, cx, substs);
             enc_trait_store(w, cx, store);
-            enc_mutability(w, mutability);
             let bounds = ty::ParamBounds {builtin_bounds: bounds,
                                           trait_bounds: Vec::new()};
             enc_bounds(w, cx, &bounds);
@@ -289,14 +292,14 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
             enc_region(w, cx, r);
             enc_mt(w, cx, mt);
         }
-        ty::ty_vec(mt, v) => {
+        ty::ty_vec(ty, v) => {
             mywrite!(w, "V");
-            enc_mt(w, cx, mt);
-            enc_vstore(w, cx, v);
+            enc_ty(w, cx, ty);
+            enc_vstore(w, cx, v, enc_mutability);
         }
         ty::ty_str(v) => {
             mywrite!(w, "v");
-            enc_vstore(w, cx, v);
+            enc_vstore(w, cx, v, |_, ()| {});
         }
         ty::ty_closure(ref f) => {
             mywrite!(w, "f");
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index e5b87d716e0..ebddc0525ea 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -514,6 +514,17 @@ impl tr for ty::BoundRegion {
     }
 }
 
+impl tr for ty::TraitStore {
+    fn tr(&self, xcx: &ExtendedDecodeContext) -> ty::TraitStore {
+        match *self {
+            ty::RegionTraitStore(r, m) => {
+                ty::RegionTraitStore(r.tr(xcx), m)
+            }
+            ty::UniqTraitStore => ty::UniqTraitStore
+        }
+    }
+}
+
 // ______________________________________________________________________
 // Encoding and decoding of freevar information
 
@@ -824,7 +835,6 @@ impl<'a> get_ty_str_ctxt for e::EncodeContext<'a> {
 
 trait ebml_writer_helpers {
     fn emit_ty(&mut self, ecx: &e::EncodeContext, ty: ty::t);
-    fn emit_vstore(&mut self, ecx: &e::EncodeContext, vstore: ty::vstore);
     fn emit_tys(&mut self, ecx: &e::EncodeContext, tys: &[ty::t]);
     fn emit_type_param_def(&mut self,
                            ecx: &e::EncodeContext,
@@ -841,10 +851,6 @@ impl<'a> ebml_writer_helpers for Encoder<'a> {
         self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
     }
 
-    fn emit_vstore(&mut self, ecx: &e::EncodeContext, vstore: ty::vstore) {
-        self.emit_opaque(|this| Ok(e::write_vstore(ecx, this, vstore)));
-    }
-
     fn emit_tys(&mut self, ecx: &e::EncodeContext, tys: &[ty::t]) {
         self.emit_from_vec(tys, |this, ty| Ok(this.emit_ty(ecx, *ty)));
     }
@@ -904,14 +910,12 @@ impl<'a> ebml_writer_helpers for Encoder<'a> {
                     })
                 }
 
-                ty::AutoObject(sigil, region, m, b, def_id, ref substs) => {
-                    this.emit_enum_variant("AutoObject", 2, 6, |this| {
-                        this.emit_enum_variant_arg(0, |this| sigil.encode(this));
-                        this.emit_enum_variant_arg(1, |this| region.encode(this));
-                        this.emit_enum_variant_arg(2, |this| m.encode(this));
-                        this.emit_enum_variant_arg(3, |this| b.encode(this));
-                        this.emit_enum_variant_arg(4, |this| def_id.encode(this));
-                        this.emit_enum_variant_arg(5, |this| Ok(this.emit_substs(ecx, substs)))
+                ty::AutoObject(store, b, def_id, ref substs) => {
+                    this.emit_enum_variant("AutoObject", 2, 4, |this| {
+                        this.emit_enum_variant_arg(0, |this| store.encode(this));
+                        this.emit_enum_variant_arg(1, |this| b.encode(this));
+                        this.emit_enum_variant_arg(2, |this| def_id.encode(this));
+                        this.emit_enum_variant_arg(3, |this| Ok(this.emit_substs(ecx, substs)))
                     })
                 }
             }
@@ -1280,25 +1284,16 @@ impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> {
                         ty::AutoDerefRef(auto_deref_ref.tr(xcx))
                     }
                     2 => {
-                        let sigil: ast::Sigil =
+                        let store: ty::TraitStore =
                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
-                        let region: Option<ty::Region> =
-                            this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
-                        let m: ast::Mutability =
-                            this.read_enum_variant_arg(2, |this| Decodable::decode(this)).unwrap();
                         let b: ty::BuiltinBounds =
-                            this.read_enum_variant_arg(3, |this| Decodable::decode(this)).unwrap();
+                            this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
                         let def_id: ast::DefId =
-                            this.read_enum_variant_arg(4, |this| Decodable::decode(this)).unwrap();
-                        let substs = this.read_enum_variant_arg(5, |this| Ok(this.read_substs(xcx)))
+                            this.read_enum_variant_arg(2, |this| Decodable::decode(this)).unwrap();
+                        let substs = this.read_enum_variant_arg(3, |this| Ok(this.read_substs(xcx)))
                                     .unwrap();
 
-                        let region = match region {
-                            Some(r) => Some(r.tr(xcx)),
-                            None => None
-                        };
-
-                        ty::AutoObject(sigil, region, m, b, def_id.tr(xcx), substs)
+                        ty::AutoObject(store.tr(xcx), b, def_id.tr(xcx), substs)
                     }
                     _ => fail!("bad enum variant for ty::AutoAdjustment")
                 })
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index e18f8f530ee..f59b2efd1cd 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -279,7 +279,7 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
                 }
                 not_useful
               }
-              ty::ty_vec(_, ty::vstore_fixed(n)) => {
+              ty::ty_vec(_, ty::VstoreFixed(n)) => {
                 is_useful_specialized(cx, m, v, vec(n), n, left_ty)
               }
               ty::ty_vec(..) => {
@@ -441,7 +441,7 @@ fn missing_ctor(cx: &MatchCheckCtxt,
         else if true_found { Some(val(const_bool(false))) }
         else { Some(val(const_bool(true))) }
       }
-      ty::ty_vec(_, ty::vstore_fixed(n)) => {
+      ty::ty_vec(_, ty::VstoreFixed(n)) => {
         let mut missing = true;
         let mut wrong = false;
         for r in m.iter() {
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 24dea77c170..16af63c4e16 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -917,8 +917,8 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
                 ty::ty_box(_) => {
                     n_box += 1;
                 }
-                ty::ty_uniq(_) | ty::ty_str(ty::vstore_uniq) |
-                ty::ty_vec(_, ty::vstore_uniq) |
+                ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
+                ty::ty_vec(_, ty::VstoreUniq) |
                 ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
                     n_uniq += 1;
                 }
@@ -1158,7 +1158,7 @@ fn check_unused_result(cx: &Context, s: &ast::Stmt) {
 fn check_deprecated_owned_vector(cx: &Context, e: &ast::Expr) {
     let t = ty::expr_ty(cx.tcx, e);
     match ty::get(t).sty {
-        ty::ty_vec(_, ty::vstore_uniq) => {
+        ty::ty_vec(_, ty::VstoreUniq) => {
             cx.span_lint(DeprecatedOwnedVector, e.span,
                          "use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index e376e66ca6f..a5da9e7f9d0 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -170,24 +170,23 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
     match ty::get(t).sty {
         ty::ty_uniq(_) |
         ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
-        ty::ty_vec(_, ty::vstore_uniq) |
-        ty::ty_str(ty::vstore_uniq) |
+        ty::ty_vec(_, ty::VstoreUniq) |
+        ty::ty_str(ty::VstoreUniq) |
         ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
             Some(deref_ptr(OwnedPtr))
         }
 
-        ty::ty_rptr(r, mt) |
-        ty::ty_vec(mt, ty::vstore_slice(r)) => {
+        ty::ty_rptr(r, mt) => {
             let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
-
-        ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(r), mutability: m, .. }) => {
-            let kind = ty::BorrowKind::from_mutbl(m);
+        ty::ty_vec(_, ty::VstoreSlice(r, mutbl)) |
+        ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(r, mutbl), .. }) => {
+            let kind = ty::BorrowKind::from_mutbl(mutbl);
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
 
-        ty::ty_str(ty::vstore_slice(r)) |
+        ty::ty_str(ty::VstoreSlice(r, ())) |
         ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil,
                                       region: r, ..}) => {
             Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
@@ -206,8 +205,8 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             Some(deref_interior(InteriorField(PositionalField(0))))
         }
 
-        ty::ty_vec(_, ty::vstore_fixed(_)) |
-        ty::ty_str(ty::vstore_fixed(_)) => {
+        ty::ty_vec(_, ty::VstoreFixed(_)) |
+        ty::ty_str(ty::VstoreFixed(_)) => {
             Some(deref_interior(InteriorElement(element_kind(t))))
         }
 
@@ -799,7 +798,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
         //!   the implicit index deref, if any (see above)
 
         let element_ty = match ty::index(base_cmt.ty) {
-          Some(ref mt) => mt.ty,
+          Some(ty) => ty,
           None => {
             self.tcx().sess.span_bug(
                 elt.span(),
@@ -882,8 +881,8 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
              */
 
             match ty::get(slice_ty).sty {
-                ty::ty_vec(slice_mt, ty::vstore_slice(slice_r)) => {
-                    (slice_mt.mutbl, slice_r)
+                ty::ty_vec(_, ty::VstoreSlice(slice_r, mutbl)) => {
+                    (mutbl, slice_r)
                 }
 
                 ty::ty_rptr(_, ref mt) => {
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 49163ce9699..393e35141b4 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -1109,10 +1109,8 @@ fn extract_vec_elems<'a>(
         let slice_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset);
         let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
         let slice_len = Sub(bcx, len, slice_len_offset);
-        let slice_ty = ty::mk_vec(bcx.tcx(),
-            ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable},
-            ty::vstore_slice(ty::ReStatic)
-        );
+        let slice_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty,
+                                  ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
         let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
         Store(bcx, slice_begin,
               GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
@@ -1319,7 +1317,7 @@ fn compare_values<'a>(
     }
 
     match ty::get(rhs_t).sty {
-        ty::ty_str(ty::vstore_uniq) => {
+        ty::ty_str(ty::VstoreUniq) => {
             let scratch_lhs = alloca(cx, val_ty(lhs), "__lhs");
             Store(cx, lhs, scratch_lhs);
             let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 92b1a60598b..3007b643e0a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -188,7 +188,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
         // FIXME #6750 ~Trait cannot be directly marked as
         // noalias because the actual object pointer is nested.
         ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
-        ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
+        ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) => {
             unsafe {
                 llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
             }
@@ -259,7 +259,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
             // FIXME #6750 ~Trait cannot be directly marked as
             // noalias because the actual object pointer is nested.
             ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
-            ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) |
+            ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) |
             ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
                 unsafe {
                     llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
@@ -657,10 +657,10 @@ 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);
+      ty::ty_str(ty::VstoreFixed(n)) |
+      ty::ty_vec(_, ty::VstoreFixed(n)) => {
         let unit_ty = ty::sequence_element_type(cx.tcx(), t);
+        let (base, len) = tvec::get_fixed_base_and_byte_len(cx, av, unit_ty, n);
         cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
       }
       ty::ty_tup(ref args) => {
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 13fcaa486f1..372bba6d51c 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -654,7 +654,7 @@ pub fn trans_call_inner<'a>(
         match ty::get(ret_ty).sty {
             // `~` pointer return values never alias because ownership
             // is transferred
-            ty::ty_uniq(..) | ty::ty_vec(_, ty::vstore_uniq) => {
+            ty::ty_uniq(..) | ty::ty_vec(_, ty::VstoreUniq) => {
                 attrs.push((0, NoAliasAttribute));
             }
             _ => {}
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index d03b13b1b8f..b8f6d445c36 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -712,7 +712,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
     match ty::get(t).sty {
         ty::ty_float(_) => MonoFloat,
         ty::ty_rptr(..) | ty::ty_uniq(..) | ty::ty_box(..) |
-        ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) |
+        ty::ty_str(ty::VstoreUniq) | ty::ty_vec(_, ty::VstoreUniq) |
         ty::ty_bare_fn(..) => MonoNonNull,
         // Is that everything?  Would closures or slices qualify?
         _ => MonoBits
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index d6156e7c3e6..66de46aa31d 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -246,7 +246,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
                                     assert_eq!(abi::slice_elt_base, 0);
                                     assert_eq!(abi::slice_elt_len, 1);
                                     match ty::get(ty).sty {
-                                        ty::ty_vec(_, ty::vstore_fixed(len)) => {
+                                        ty::ty_vec(_, ty::VstoreFixed(len)) => {
                                             llconst = C_struct(cx, [
                                                 llptr,
                                                 C_uint(cx, len)
@@ -434,20 +434,14 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                                           "index is not an integer-constant expression")
               };
               let (arr, len) = match ty::get(bt).sty {
-                  ty::ty_vec(_, vstore) | ty::ty_str(vstore) =>
-                      match vstore {
-                      ty::vstore_fixed(u) =>
-                          (bv, C_uint(cx, u)),
-
-                      ty::vstore_slice(_) => {
-                          let e1 = const_get_elt(cx, bv, [0]);
-                          (const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
-                      },
-                      _ => cx.sess().span_bug(base.span,
-                                              "index-expr base must be fixed-size or slice")
+                  ty::ty_vec(_, ty::VstoreFixed(u)) => (bv, C_uint(cx, u)),
+                  ty::ty_vec(_, ty::VstoreSlice(..)) |
+                  ty::ty_str(ty::VstoreSlice(..)) => {
+                    let e1 = const_get_elt(cx, bv, [0]);
+                    (const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
                   },
-                  _ =>  cx.sess().span_bug(base.span,
-                                           "index-expr base must be a vector or string type")
+                  _ => cx.sess().span_bug(base.span,
+                        "index-expr base must be a fixed-size vector or a slice")
               };
 
               let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 1b3be8d29f3..965276619e9 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -2098,7 +2098,6 @@ fn trait_metadata(cx: &CrateContext,
                   trait_type: ty::t,
                   substs: &ty::substs,
                   trait_store: ty::TraitStore,
-                  mutability: ast::Mutability,
                   _: &ty::BuiltinBounds)
                -> DIType {
     // The implementation provided here is a stub. It makes sure that the trait type is
@@ -2107,7 +2106,6 @@ fn trait_metadata(cx: &CrateContext,
     let last = ty::with_path(cx.tcx(), def_id, |mut path| path.last().unwrap());
     let ident_string = token::get_name(last.name());
     let name = ppaux::trait_store_to_str(cx.tcx(), trait_store) +
-               ppaux::mutability_to_str(mutability) +
                ident_string.get();
     // Add type and region parameters
     let name = ppaux::parameterized(cx.tcx(), name, &substs.regions,
@@ -2120,13 +2118,13 @@ fn trait_metadata(cx: &CrateContext,
 
     let trait_llvm_type = type_of::type_of(cx, trait_type);
 
-    return composite_type_metadata(cx,
-                                   trait_llvm_type,
-                                   name,
-                                   [],
-                                   containing_scope,
-                                   file_metadata,
-                                   definition_span);
+    composite_type_metadata(cx,
+                            trait_llvm_type,
+                            name,
+                            [],
+                            containing_scope,
+                            file_metadata,
+                            definition_span)
 }
 
 fn type_metadata(cx: &CrateContext,
@@ -2177,14 +2175,14 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_str(ref vstore) => {
             let i8_t = ty::mk_i8();
             match *vstore {
-                ty::vstore_fixed(len) => {
+                ty::VstoreFixed(len) => {
                     fixed_vec_metadata(cx, i8_t, len, usage_site_span)
                 },
-                ty::vstore_uniq  => {
+                ty::VstoreUniq  => {
                     let vec_metadata = vec_metadata(cx, i8_t, usage_site_span);
                     pointer_type_metadata(cx, t, vec_metadata)
                 }
-                ty::vstore_slice(_region) => {
+                ty::VstoreSlice(..) => {
                     vec_slice_metadata(cx, t, i8_t, usage_site_span)
                 }
             }
@@ -2195,17 +2193,17 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_box(typ) => {
             create_pointer_to_box_metadata(cx, t, typ)
         },
-        ty::ty_vec(ref mt, ref vstore) => {
+        ty::ty_vec(ty, ref vstore) => {
             match *vstore {
-                ty::vstore_fixed(len) => {
-                    fixed_vec_metadata(cx, mt.ty, len, usage_site_span)
+                ty::VstoreFixed(len) => {
+                    fixed_vec_metadata(cx, ty, len, usage_site_span)
                 }
-                ty::vstore_uniq => {
-                    let vec_metadata = vec_metadata(cx, mt.ty, usage_site_span);
+                ty::VstoreUniq => {
+                    let vec_metadata = vec_metadata(cx, ty, usage_site_span);
                     pointer_type_metadata(cx, t, vec_metadata)
                 }
-                ty::vstore_slice(_) => {
-                    vec_slice_metadata(cx, t, mt.ty, usage_site_span)
+                ty::VstoreSlice(..) => {
+                    vec_slice_metadata(cx, t, ty, usage_site_span)
                 }
             }
         },
@@ -2223,10 +2221,8 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_closure(ref closurety) => {
             subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
         },
-        ty::ty_trait(~ty::TyTrait { def_id, ref substs,
-                                store: trait_store, mutability,
-                                ref bounds }) => {
-            trait_metadata(cx, def_id, t, substs, trait_store, mutability, bounds)
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, ref bounds }) => {
+            trait_metadata(cx, def_id, t, substs, store, bounds)
         },
         ty::ty_struct(def_id, ref substs) => {
             if ty::type_is_simd(cx.tcx(), t) {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index c12c8c106cb..4515b5d086e 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -263,9 +263,8 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
 
         // this type may have a different region/mutability than the
         // real one, but it will have the same runtime representation
-        let slice_ty = ty::mk_vec(tcx,
-                                  ty::mt { ty: unit_ty, mutbl: ast::MutImmutable },
-                                  ty::vstore_slice(ty::ReStatic));
+        let slice_ty = ty::mk_vec(tcx, unit_ty,
+                                  ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
 
         let scratch = rvalue_scratch_datum(bcx, slice_ty, "__adjust");
         Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 5aee8b64848..f4b6ed235e8 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -93,7 +93,7 @@ fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
             }
         }
 
-        ty::ty_vec(mt, ty::vstore_uniq) if !ty::type_needs_drop(tcx, mt.ty) =>
+        ty::ty_vec(ty, ty::VstoreUniq) if !ty::type_needs_drop(tcx, ty) =>
             ty::mk_uniq(tcx, ty::mk_i8()),
 
         _ => t
@@ -289,7 +289,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 trans_exchange_free(bcx, llbox)
             })
         }
-        ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
+        ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) => {
             let llbox = Load(bcx, v0);
             let not_null = IsNotNull(bcx, llbox);
             with_cond(bcx, not_null, |bcx| {
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 2244c769af1..c4b9c7f97ad 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -54,7 +54,7 @@ impl<'a> Reflector<'a> {
         // We're careful to not use first class aggregates here because that
         // will kick us off fast isel. (Issue #4352.)
         let bcx = self.bcx;
-        let str_vstore = ty::vstore_slice(ty::ReStatic);
+        let str_vstore = ty::VstoreSlice(ty::ReStatic, ());
         let str_ty = ty::mk_str(bcx.tcx(), str_vstore);
         let scratch = rvalue_scratch_datum(bcx, str_ty, "");
         let len = C_uint(bcx.ccx(), s.get().len());
@@ -121,17 +121,17 @@ impl<'a> Reflector<'a> {
         self.visit("leave_" + bracket_name, extra);
     }
 
-    pub fn vstore_name_and_extra(&mut self,
-                                 t: ty::t,
-                                 vstore: ty::vstore)
-                                 -> (~str, Vec<ValueRef> ) {
+    pub fn vstore_name_and_extra<M>(&mut self,
+                                    t: ty::t,
+                                    vstore: ty::Vstore<M>)
+                                    -> (~str, Vec<ValueRef> ) {
         match vstore {
-            ty::vstore_fixed(n) => {
+            ty::VstoreFixed(n) => {
                 let extra = (vec!(self.c_uint(n))).append(self.c_size_and_align(t).as_slice());
                 (~"fixed", extra)
             }
-            ty::vstore_slice(_) => (~"slice", Vec::new()),
-            ty::vstore_uniq => (~"uniq", Vec::new()),
+            ty::VstoreSlice(..) => (~"slice", Vec::new()),
+            ty::VstoreUniq => (~"uniq", Vec::new()),
         }
     }
 
@@ -168,9 +168,15 @@ impl<'a> Reflector<'a> {
               let (name, extra) = self.vstore_name_and_extra(t, vst);
               self.visit(~"estr_" + name, extra.as_slice())
           }
-          ty::ty_vec(ref mt, vst) => {
+          ty::ty_vec(ty, vst) => {
               let (name, extra) = self.vstore_name_and_extra(t, vst);
-              let extra = extra.append(self.c_mt(mt).as_slice());
+              let extra = extra.append(self.c_mt(&ty::mt {
+                  ty: ty,
+                  mutbl: match vst {
+                      ty::VstoreSlice(_, m) => m,
+                      _ => ast::MutImmutable
+                  }
+              }).as_slice());
               self.visit(~"evec_" + name, extra.as_slice())
           }
           // Should remove mt from box and uniq.
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index 73370357a92..85962eb0d62 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -162,10 +162,8 @@ pub fn trans_slice_vstore<'a>(
         llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
 
         // Arrange for the backing array to be cleaned up.
-        let fixed_ty = ty::mk_vec(bcx.tcx(),
-                                  ty::mt {ty: vt.unit_ty,
-                                          mutbl: ast::MutMutable},
-                                  ty::vstore_fixed(count));
+        let fixed_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty,
+                                  ty::VstoreFixed(count));
         let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to();
         let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty);
         let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id);
@@ -244,7 +242,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
                     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 typ = ty::mk_str(bcx.tcx(), ty::VstoreUniq);
                     let lldestval = rvalue_scratch_datum(bcx,
                                                          typ,
                                                          "");
@@ -445,44 +443,22 @@ pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint {
     }
 }
 
-pub fn get_base_and_byte_len(bcx: &Block,
-                             llval: ValueRef,
-                             vec_ty: ty::t)
-                             -> (ValueRef, ValueRef) {
+pub fn get_fixed_base_and_byte_len(bcx: &Block,
+                                   llval: ValueRef,
+                                   unit_ty: ty::t,
+                                   vec_length: uint)
+                                   -> (ValueRef, ValueRef) {
     /*!
-     * Converts a vector into the slice pair.  The vector should be
-     * stored in `llval` which should be by ref. If you have a datum,
-     * you would probably prefer to call
-     * `Datum::get_base_and_byte_len()`.
+     * Converts a fixed-length vector into the slice pair.
+     * The vector should be stored in `llval` which should be by ref.
      */
 
     let ccx = bcx.ccx();
-    let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
-
-    let vstore = match ty::get(vec_ty).sty {
-        ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
-        _ => ty::vstore_uniq
-    };
+    let vt = vec_types(bcx, unit_ty);
 
-    match vstore {
-        ty::vstore_fixed(n) => {
-            let base = GEPi(bcx, llval, [0u, 0u]);
-            let len = Mul(bcx, C_uint(ccx, n), vt.llunit_size);
-            (base, len)
-        }
-        ty::vstore_slice(_) => {
-            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(), vec_ty));
-            let body = Load(bcx, llval);
-            (get_dataptr(bcx, body), get_fill(bcx, body))
-        }
-    }
+    let base = GEPi(bcx, llval, [0u, 0u]);
+    let len = Mul(bcx, C_uint(ccx, vec_length), vt.llunit_size);
+    (base, len)
 }
 
 pub fn get_base_and_len(bcx: &Block,
@@ -501,22 +477,30 @@ pub fn get_base_and_len(bcx: &Block,
     let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
 
     let vstore = match ty::get(vec_ty).sty {
-        ty::ty_str(vst) | ty::ty_vec(_, vst) => vst,
-        _ => ty::vstore_uniq
+        ty::ty_vec(_, vst) => vst,
+        ty::ty_str(vst) => {
+            // Convert from immutable-only-Vstore to Vstore.
+            match vst {
+                ty::VstoreFixed(n) => ty::VstoreFixed(n),
+                ty::VstoreSlice(r, ()) => ty::VstoreSlice(r, ast::MutImmutable),
+                ty::VstoreUniq => ty::VstoreUniq
+            }
+        }
+        _ => ty::VstoreUniq
     };
 
     match vstore {
-        ty::vstore_fixed(n) => {
+        ty::VstoreFixed(n) => {
             let base = GEPi(bcx, llval, [0u, 0u]);
             (base, C_uint(ccx, n))
         }
-        ty::vstore_slice(_) => {
+        ty::VstoreSlice(..) => {
             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 => {
+        ty::VstoreUniq => {
             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))
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 5a4cb1a33ef..071eb083d4f 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -116,15 +116,15 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_uint(t) => Type::uint_from_ty(cx, t),
         ty::ty_float(t) => Type::float_from_ty(cx, t),
 
-        ty::ty_str(ty::vstore_uniq) |
-        ty::ty_vec(_, ty::vstore_uniq) |
+        ty::ty_str(ty::VstoreUniq) |
+        ty::ty_vec(_, ty::VstoreUniq) |
         ty::ty_box(..) |
         ty::ty_uniq(..) |
         ty::ty_ptr(..) |
         ty::ty_rptr(..) => Type::i8p(cx),
 
-        ty::ty_str(ty::vstore_slice(..)) |
-        ty::ty_vec(_, ty::vstore_slice(..)) => {
+        ty::ty_str(ty::VstoreSlice(..)) |
+        ty::ty_vec(_, ty::VstoreSlice(..)) => {
             Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
         }
 
@@ -132,9 +132,9 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_closure(..) => Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false),
         ty::ty_trait(..) => Type::opaque_trait(cx),
 
-        ty::ty_str(ty::vstore_fixed(size)) => Type::array(&Type::i8(cx), size as u64),
-        ty::ty_vec(mt, ty::vstore_fixed(size)) => {
-            Type::array(&sizing_type_of(cx, mt.ty), size as u64)
+        ty::ty_str(ty::VstoreFixed(size)) => Type::array(&Type::i8(cx), size as u64),
+        ty::ty_vec(ty, ty::VstoreFixed(size)) => {
+            Type::array(&sizing_type_of(cx, ty), size as u64)
         }
 
         ty::ty_tup(..) | ty::ty_enum(..) => {
@@ -199,7 +199,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
       ty::ty_int(t) => Type::int_from_ty(cx, t),
       ty::ty_uint(t) => Type::uint_from_ty(cx, t),
       ty::ty_float(t) => Type::float_from_ty(cx, t),
-      ty::ty_str(ty::vstore_uniq) => {
+      ty::ty_str(ty::VstoreUniq) => {
         Type::vec(cx, &Type::i8(cx)).ptr_to()
       }
       ty::ty_enum(did, ref substs) => {
@@ -217,29 +217,29 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
       ty::ty_uniq(typ) => {
           type_of(cx, typ).ptr_to()
       }
-      ty::ty_vec(ref mt, ty::vstore_uniq) => {
-          Type::vec(cx, &type_of(cx, mt.ty)).ptr_to()
+      ty::ty_vec(ty, ty::VstoreUniq) => {
+          Type::vec(cx, &type_of(cx, ty)).ptr_to()
       }
       ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),
       ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(),
 
-      ty::ty_vec(ref mt, ty::vstore_slice(_)) => {
-          let p_ty = type_of(cx, mt.ty).ptr_to();
+      ty::ty_vec(ty, ty::VstoreSlice(..)) => {
+          let p_ty = type_of(cx, ty).ptr_to();
           let u_ty = Type::uint_from_ty(cx, ast::TyU);
           Type::struct_(cx, [p_ty, u_ty], false)
       }
 
-      ty::ty_str(ty::vstore_slice(_)) => {
+      ty::ty_str(ty::VstoreSlice(..)) => {
           // This means we get a nicer name in the output
           cx.tn.find_type("str_slice").unwrap()
       }
 
-      ty::ty_str(ty::vstore_fixed(n)) => {
+      ty::ty_str(ty::VstoreFixed(n)) => {
           Type::array(&Type::i8(cx), (n + 1u) as u64)
       }
 
-      ty::ty_vec(ref mt, ty::vstore_fixed(n)) => {
-          Type::array(&type_of(cx, mt.ty), n as u64)
+      ty::ty_vec(ty, ty::VstoreFixed(n)) => {
+          Type::array(&type_of(cx, ty), n as u64)
       }
 
       ty::ty_bare_fn(_) => {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index aac847c795a..0cb0d716ddc 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -27,7 +27,7 @@ use middle::ty_fold;
 use middle::ty_fold::TypeFolder;
 use middle;
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
-use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
+use util::ppaux::{trait_store_to_str, ty_to_str};
 use util::ppaux::{Repr, UserString};
 use util::common::{indenter};
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
@@ -130,16 +130,24 @@ pub struct mt {
 }
 
 #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
-pub enum vstore {
-    vstore_fixed(uint),
-    vstore_uniq,
-    vstore_slice(Region)
+/// Describes the "storage mode" of a `[]`, whether it's fixed length or a slice.
+///
+/// Set M to () to disable mutable slices.
+pub enum Vstore<M = ast::Mutability> {
+    /// [T, ..N]
+    VstoreFixed(uint),
+    /// ~[T]
+    VstoreUniq,
+    /// &[T] and &mut [T]
+    VstoreSlice(Region, M)
 }
 
 #[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
 pub enum TraitStore {
-    UniqTraitStore,             // ~Trait
-    RegionTraitStore(Region),   // &Trait
+    /// ~Trait
+    UniqTraitStore,
+    /// &Trait and &mut Trait
+    RegionTraitStore(Region, ast::Mutability),
 }
 
 pub struct field_ty {
@@ -208,8 +216,7 @@ pub enum Variance {
 pub enum AutoAdjustment {
     AutoAddEnv(ty::Region, ast::Sigil),
     AutoDerefRef(AutoDerefRef),
-    AutoObject(ast::Sigil, Option<ty::Region>,
-               ast::Mutability,
+    AutoObject(ty::TraitStore,
                ty::BuiltinBounds,
                ast::DefId, /* Trait ID */
                ty::substs /* Trait substitutions */)
@@ -729,11 +736,11 @@ pub enum sty {
     ty_int(ast::IntTy),
     ty_uint(ast::UintTy),
     ty_float(ast::FloatTy),
-    ty_str(vstore),
     ty_enum(DefId, substs),
     ty_box(t),
     ty_uniq(t),
-    ty_vec(mt, vstore),
+    ty_str(Vstore<()>),
+    ty_vec(t, Vstore),
     ty_ptr(mt),
     ty_rptr(Region, mt),
     ty_bare_fn(BareFnTy),
@@ -757,7 +764,6 @@ pub struct TyTrait {
     pub def_id: DefId,
     pub substs: substs,
     pub store: TraitStore,
-    pub mutability: ast::Mutability,
     pub bounds: BuiltinBounds
 }
 
@@ -811,7 +817,7 @@ pub enum type_err {
     terr_regions_no_overlap(Region, Region),
     terr_regions_insufficiently_polymorphic(BoundRegion, Region),
     terr_regions_overly_polymorphic(BoundRegion, Region),
-    terr_vstores_differ(terr_vstore_kind, expected_found<vstore>),
+    terr_vstores_differ(terr_vstore_kind, expected_found<Vstore<()>>),
     terr_trait_stores_differ(terr_vstore_kind, expected_found<TraitStore>),
     terr_in_field(@type_err, ast::Ident),
     terr_sorts(expected_found<t>),
@@ -1177,12 +1183,12 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
         return f;
     }
     match &st {
-      &ty_str(vstore_slice(r)) => {
+      &ty_str(VstoreSlice(r, ())) => {
         flags |= rflags(r);
       }
-      &ty_vec(ref mt, vstore_slice(r)) => {
+      &ty_vec(ty, VstoreSlice(r, _)) => {
         flags |= rflags(r);
-        flags |= get(mt.ty).flags;
+        flags |= get(ty).flags;
       }
       &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
       &ty_str(_) => {}
@@ -1202,16 +1208,16 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
       &ty_trait(~ty::TyTrait { ref substs, .. }) => {
           flags |= sflags(substs);
           match st {
-              ty_trait(~ty::TyTrait { store: RegionTraitStore(r), .. }) => {
+              ty_trait(~ty::TyTrait { store: RegionTraitStore(r, _), .. }) => {
                     flags |= rflags(r);
                 }
               _ => {}
           }
       }
-      &ty_box(tt) | &ty_uniq(tt) => {
+      &ty_box(tt) | &ty_uniq(tt) | &ty_vec(tt, _) => {
         flags |= get(tt).flags
       }
-      &ty_vec(ref m, _) | &ty_ptr(ref m) => {
+      &ty_ptr(ref m) => {
         flags |= get(m.ty).flags;
       }
       &ty_rptr(r, ref m) => {
@@ -1340,8 +1346,8 @@ pub fn mk_mach_float(tm: ast::FloatTy) -> t {
 #[inline]
 pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) }
 
-pub fn mk_str(cx: &ctxt, t: vstore) -> t {
-    mk_t(cx, ty_str(t))
+pub fn mk_str(cx: &ctxt, v: Vstore<()>) -> t {
+    mk_t(cx, ty_str(v))
 }
 
 pub fn mk_enum(cx: &ctxt, did: ast::DefId, substs: substs) -> t {
@@ -1376,8 +1382,8 @@ pub fn mk_nil_ptr(cx: &ctxt) -> t {
     mk_ptr(cx, mt {ty: mk_nil(), mutbl: ast::MutImmutable})
 }
 
-pub fn mk_vec(cx: &ctxt, tm: mt, t: vstore) -> t {
-    mk_t(cx, ty_vec(tm, t))
+pub fn mk_vec(cx: &ctxt, ty: t, v: Vstore) -> t {
+    mk_t(cx, ty_vec(ty, v))
 }
 
 pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
@@ -1413,7 +1419,6 @@ pub fn mk_trait(cx: &ctxt,
                 did: ast::DefId,
                 substs: substs,
                 store: TraitStore,
-                mutability: ast::Mutability,
                 bounds: BuiltinBounds)
              -> t {
     // take a copy of substs so that we own the vectors inside
@@ -1421,7 +1426,6 @@ pub fn mk_trait(cx: &ctxt,
         def_id: did,
         substs: substs,
         store: store,
-        mutability: mutability,
         bounds: bounds
     };
     mk_t(cx, ty_trait(inner))
@@ -1458,8 +1462,8 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
         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_ptr(ref tm) | ty_rptr(_, ref tm) => {
+        ty_box(ty) | ty_uniq(ty) | ty_vec(ty, _) => maybe_walk_ty(ty, f),
+        ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
             maybe_walk_ty(tm.ty, f);
         }
         ty_enum(_, ref substs) | ty_struct(_, ref substs) |
@@ -1597,8 +1601,8 @@ pub fn type_is_self(ty: t) -> bool {
 pub fn type_is_structural(ty: t) -> bool {
     match get(ty).sty {
       ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
-      ty_vec(_, vstore_fixed(_)) | ty_str(vstore_fixed(_)) |
-      ty_vec(_, vstore_slice(_)) | ty_str(vstore_slice(_))
+      ty_vec(_, VstoreFixed(_)) | ty_str(VstoreFixed(_)) |
+      ty_vec(_, VstoreSlice(..)) | ty_str(VstoreSlice(..))
       => true,
       _ => false
     }
@@ -1614,7 +1618,7 @@ 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(_) => mk_mach_uint(ast::TyU8),
-        ty_vec(mt, _) => mt.ty,
+        ty_vec(ty, _) => ty,
         _ => cx.sess.bug("sequence_element_type called on non-sequence value"),
     }
 }
@@ -1662,7 +1666,7 @@ pub fn type_is_unsafe_ptr(ty: t) -> bool {
 
 pub fn type_is_unique(ty: t) -> bool {
     match get(ty).sty {
-        ty_uniq(_) | ty_vec(_, vstore_uniq) | ty_str(vstore_uniq) => true,
+        ty_uniq(_) | ty_vec(_, VstoreUniq) | ty_str(VstoreUniq) => true,
         _ => false
     }
 }
@@ -1736,8 +1740,8 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t,
             !needs_unwind_cleanup
           }
           ty_uniq(_) |
-          ty_str(vstore_uniq) |
-          ty_vec(_, vstore_uniq) => {
+          ty_str(VstoreUniq) |
+          ty_vec(_, VstoreUniq) => {
             // Once we're inside a box, the annihilator will find
             // it and destroy it.
             if !encountered_box {
@@ -2050,7 +2054,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                 TC::None
             }
 
-            ty_str(vstore_uniq) => {
+            ty_str(VstoreUniq) => {
                 TC::OwnsOwned
             }
 
@@ -2066,8 +2070,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                 tc_ty(cx, typ, cache).owned_pointer()
             }
 
-            ty_trait(~ty::TyTrait { store, mutability, bounds, .. }) => {
-                object_contents(cx, store, mutability, bounds)
+            ty_trait(~ty::TyTrait { store, bounds, .. }) => {
+                object_contents(cx, store, bounds)
             }
 
             ty_ptr(ref mt) => {
@@ -2079,24 +2083,23 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                     borrowed_contents(r, mt.mutbl))
             }
 
-            ty_vec(mt, vstore_uniq) => {
-                tc_mt(cx, mt, cache).owned_pointer()
+            ty_vec(ty, VstoreUniq) => {
+                tc_ty(cx, ty, cache).owned_pointer()
             }
 
-            ty_vec(ref mt, vstore_slice(r)) => {
-                tc_ty(cx, mt.ty, cache).reference(
-                    borrowed_contents(r, mt.mutbl))
+            ty_vec(ty, VstoreSlice(r, mutbl)) => {
+                tc_ty(cx, ty, cache).reference(borrowed_contents(r, mutbl))
             }
 
-            ty_vec(mt, vstore_fixed(_)) => {
-                tc_mt(cx, mt, cache)
+            ty_vec(ty, VstoreFixed(_)) => {
+                tc_ty(cx, ty, cache)
             }
 
-            ty_str(vstore_slice(r)) => {
+            ty_str(VstoreSlice(r, ())) => {
                 borrowed_contents(r, ast::MutImmutable)
             }
 
-            ty_str(vstore_fixed(_)) => {
+            ty_str(VstoreFixed(_)) => {
                 TC::None
             }
 
@@ -2216,9 +2219,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
         // even more stuff.
         let st = match cty.sigil {
             ast::BorrowedSigil =>
-                object_contents(cx, RegionTraitStore(cty.region), MutMutable, cty.bounds),
-            ast::OwnedSigil =>
-                object_contents(cx, UniqTraitStore, MutImmutable, cty.bounds),
+                object_contents(cx, RegionTraitStore(cty.region, MutMutable), cty.bounds),
+            ast::OwnedSigil => object_contents(cx, UniqTraitStore, cty.bounds),
             ast::ManagedSigil => unreachable!()
         };
 
@@ -2239,18 +2241,16 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
 
     fn object_contents(cx: &ctxt,
                        store: TraitStore,
-                       mutbl: ast::Mutability,
                        bounds: BuiltinBounds)
                        -> TypeContents {
         // These are the type contents of the (opaque) interior
-        let contents = TC::ReachesMutable.when(mutbl == ast::MutMutable) |
-            kind_bounds_to_contents(cx, bounds, []);
+        let contents = kind_bounds_to_contents(cx, bounds, []);
 
         match store {
             UniqTraitStore => {
                 contents.owned_pointer()
             }
-            RegionTraitStore(r) => {
+            RegionTraitStore(r, mutbl) => {
                 contents.reference(borrowed_contents(r, mutbl))
             }
         }
@@ -2328,8 +2328,8 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
             // fixed length vectors need special treatment compared to
             // normal vectors, since they don't necessarily have the
             // possibilty to have length zero.
-            ty_vec(_, vstore_fixed(0)) => false, // don't need no contents
-            ty_vec(mt, vstore_fixed(_)) => type_requires(cx, seen, r_ty, mt.ty),
+            ty_vec(_, VstoreFixed(0)) => false, // don't need no contents
+            ty_vec(ty, VstoreFixed(_)) => type_requires(cx, seen, r_ty, ty),
 
             ty_nil |
             ty_bot |
@@ -2466,8 +2466,8 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
             }
             // Fixed-length vectors.
             // FIXME(#11924) Behavior undecided for zero-length vectors.
-            ty_vec(mt, vstore_fixed(_)) => {
-                type_structurally_recursive(cx, seen, mt.ty)
+            ty_vec(ty, VstoreFixed(_)) => {
+                type_structurally_recursive(cx, seen, ty)
             }
 
             // Push struct and enum def-ids onto `seen` before recursing.
@@ -2619,11 +2619,11 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
     }
 }
 
-// Returns the type and mutability of t[i]
-pub fn index(t: t) -> Option<mt> {
+// Returns the type of t[i]
+pub fn index(t: t) -> Option<t> {
     match get(t).sty {
-        ty_vec(mt, _) => Some(mt),
-        ty_str(_) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}),
+        ty_vec(ty, _) => Some(ty),
+        ty_str(_) => Some(mk_u8()),
         _ => None
     }
 }
@@ -2728,8 +2728,8 @@ pub fn ty_region(tcx: &ctxt,
                  ty: t) -> Region {
     match get(ty).sty {
         ty_rptr(r, _) => r,
-        ty_vec(_, vstore_slice(r)) => r,
-        ty_str(vstore_slice(r)) => r,
+        ty_vec(_, VstoreSlice(r, _)) => r,
+        ty_str(VstoreSlice(r, ())) => r,
         ref s => {
             tcx.sess.span_bug(
                 span,
@@ -2927,14 +2927,8 @@ pub fn adjust_ty(cx: &ctxt,
                     }
                 }
 
-                AutoObject(ref sigil, ref region, m, b, def_id, ref substs) => {
-                    trait_adjustment_to_ty(cx,
-                                           sigil,
-                                           region,
-                                           def_id,
-                                           substs,
-                                           m,
-                                           b)
+                AutoObject(store, bounds, def_id, ref substs) => {
+                    mk_trait(cx, def_id, substs.clone(), store, bounds)
                 }
             }
         }
@@ -2945,12 +2939,12 @@ pub fn adjust_ty(cx: &ctxt,
                   r: Region, m: ast::Mutability,
                   ty: ty::t) -> ty::t {
         match get(ty).sty {
-            ty_vec(mt, _) => {
-                ty::mk_vec(cx, mt {ty: mt.ty, mutbl: m}, vstore_slice(r))
+            ty_vec(ty, _) => {
+                ty::mk_vec(cx, ty, VstoreSlice(r, m))
             }
 
             ty_str(_) => {
-                ty::mk_str(cx, vstore_slice(r))
+                ty::mk_str(cx, VstoreSlice(r, ()))
             }
 
             ref s => {
@@ -2986,7 +2980,7 @@ pub fn adjust_ty(cx: &ctxt,
         match get(ty).sty {
             ty_trait(~ty::TyTrait {def_id, ref substs, bounds, .. }) => {
                 ty::mk_trait(cx, def_id, substs.clone(),
-                             RegionTraitStore(r), m, bounds)
+                             RegionTraitStore(r, m), bounds)
             }
             ref s => {
                 cx.sess.span_bug(
@@ -2998,19 +2992,6 @@ pub fn adjust_ty(cx: &ctxt,
     }
 }
 
-pub fn trait_adjustment_to_ty(cx: &ctxt, sigil: &ast::Sigil, region: &Option<Region>,
-                              def_id: ast::DefId, substs: &substs, m: ast::Mutability,
-                              bounds: BuiltinBounds) -> t {
-
-    let trait_store = match *sigil {
-        BorrowedSigil => RegionTraitStore(region.expect("expected valid region")),
-        OwnedSigil => UniqTraitStore,
-        ManagedSigil => unreachable!()
-    };
-
-    mk_trait(cx, def_id, substs.clone(), trait_store, m, bounds)
-}
-
 impl AutoRef {
     pub fn map_region(&self, f: |Region| -> Region) -> AutoRef {
         match *self {
@@ -3409,8 +3390,8 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
         terr_vstores_differ(k, ref values) => {
             format!("{} storage differs: expected `{}` but found `{}`",
                  terr_vstore_kind_to_str(k),
-                 vstore_to_str(cx, (*values).expected),
-                 vstore_to_str(cx, (*values).found))
+                 (*values).expected.repr(cx),
+                 (*values).found.repr(cx))
         }
         terr_trait_stores_differ(_, ref values) => {
             format!("trait storage differs: expected `{}` but found `{}`",
@@ -4201,10 +4182,10 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t {
             return t_norm;
         }
 
-        fn fold_vstore(&mut self, vstore: vstore) -> vstore {
+        fn fold_vstore<M>(&mut self, vstore: Vstore<M>) -> Vstore<M> {
             match vstore {
-                vstore_fixed(..) | vstore_uniq => vstore,
-                vstore_slice(_) => vstore_slice(ReStatic)
+                VstoreFixed(..) | VstoreUniq => vstore,
+                VstoreSlice(_, m) => VstoreSlice(ReStatic, m)
             }
         }
 
@@ -4389,8 +4370,7 @@ pub fn visitor_object_ty(tcx: &ctxt,
         mk_trait(tcx,
                  trait_ref.def_id,
                  trait_ref.substs.clone(),
-                 RegionTraitStore(region),
-                 ast::MutMutable,
+                 RegionTraitStore(region, ast::MutMutable),
                  EmptyBuiltinBounds())))
 }
 
@@ -4595,16 +4575,6 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             }
         }
     };
-    let vstore = |state: &mut sip::SipState, v: vstore| {
-        match v {
-            vstore_fixed(_) => 0u8.hash(state),
-            vstore_uniq => 1u8.hash(state),
-            vstore_slice(r) => {
-                2u8.hash(state);
-                region(state, r);
-            }
-        }
-    };
     let did = |state: &mut sip::SipState, did: DefId| {
         let h = if ast_util::is_local(did) {
             svh.clone()
@@ -4649,10 +4619,9 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             ty_uniq(_) => {
                 byte!(10);
             }
-            ty_vec(m, v) => {
+            ty_vec(_, v) => {
                 byte!(11);
-                mt(&mut state, m);
-                vstore(&mut state, v);
+                hash!(v);
             }
             ty_ptr(m) => {
                 byte!(12);
@@ -4676,17 +4645,17 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
                 hash!(c.bounds);
                 region(&mut state, c.region);
             }
-            ty_trait(~ty::TyTrait { def_id: d, store, mutability: m, bounds, .. }) => {
+            ty_trait(~ty::TyTrait { def_id: d, store, bounds, .. }) => {
                 byte!(17);
                 did(&mut state, d);
                 match store {
                     UniqTraitStore => byte!(0),
-                    RegionTraitStore(r) => {
+                    RegionTraitStore(r, m) => {
                         byte!(1)
                         region(&mut state, r);
+                        hash!(m);
                     }
                 }
-                hash!(m);
                 hash!(bounds);
             }
             ty_struct(d, _) => {
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index a0d2318e1d0..a100d01f66a 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -69,7 +69,7 @@ pub trait TypeFolder {
         r
     }
 
-    fn fold_vstore(&mut self, vstore: ty::vstore) -> ty::vstore {
+    fn fold_vstore<M>(&mut self, vstore: ty::Vstore<M>) -> ty::Vstore<M> {
         super_fold_vstore(self, vstore)
     }
 
@@ -148,18 +148,17 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_ptr(ref tm) => {
             ty::ty_ptr(this.fold_mt(tm))
         }
-        ty::ty_vec(ref tm, vst) => {
-            ty::ty_vec(this.fold_mt(tm), this.fold_vstore(vst))
+        ty::ty_vec(ty, vst) => {
+            ty::ty_vec(this.fold_ty(ty), this.fold_vstore(vst))
         }
         ty::ty_enum(tid, ref substs) => {
             ty::ty_enum(tid, this.fold_substs(substs))
         }
-        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, mutability, bounds }) => {
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, bounds }) => {
             ty::ty_trait(~ty::TyTrait{
                 def_id: def_id,
                 substs: this.fold_substs(substs),
                 store: this.fold_trait_store(store),
-                mutability: mutability,
                 bounds: bounds
             })
         }
@@ -193,13 +192,13 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
     }
 }
 
-pub fn super_fold_vstore<T:TypeFolder>(this: &mut T,
-                                       vstore: ty::vstore)
-                                       -> ty::vstore {
+pub fn super_fold_vstore<T:TypeFolder, M>(this: &mut T,
+                                          vstore: ty::Vstore<M>)
+                                          -> ty::Vstore<M> {
     match vstore {
-        ty::vstore_fixed(i) => ty::vstore_fixed(i),
-        ty::vstore_uniq => ty::vstore_uniq,
-        ty::vstore_slice(r) => ty::vstore_slice(this.fold_region(r)),
+        ty::VstoreFixed(i) => ty::VstoreFixed(i),
+        ty::VstoreUniq => ty::VstoreUniq,
+        ty::VstoreSlice(r, m) => ty::VstoreSlice(this.fold_region(r), m),
     }
 }
 
@@ -207,8 +206,10 @@ pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
                                             trait_store: ty::TraitStore)
                                             -> ty::TraitStore {
     match trait_store {
-        ty::UniqTraitStore      => ty::UniqTraitStore,
-        ty::RegionTraitStore(r) => ty::RegionTraitStore(this.fold_region(r)),
+        ty::UniqTraitStore => ty::UniqTraitStore,
+        ty::RegionTraitStore(r, m) => {
+            ty::RegionTraitStore(this.fold_region(r), m)
+        }
     }
 }
 
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index d2e98c617a7..3170fb82c88 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -356,7 +356,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
                             tcx.sess.span_err(ast_ty.span,
                                               "bare `str` is not a type");
                             // return /something/ so they can at least get more errors
-                            Some(ty::mk_str(tcx, ty::vstore_uniq))
+                            Some(ty::mk_str(tcx, ty::VstoreUniq))
                         }
                     }
                 }
@@ -372,29 +372,17 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
 pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
     this: &AC, rscope: &RS, ast_ty: &ast::Ty) -> ty::t {
 
-    fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(
-        this: &AC, rscope: &RS, ty: &ast::Ty) -> ty::mt {
-
-        ty::mt {ty: ast_ty_to_ty(this, rscope, ty), mutbl: ast::MutImmutable}
-    }
-
-    fn ast_mt_to_mt<AC:AstConv, RS:RegionScope>(
-        this: &AC, rscope: &RS, mt: &ast::MutTy) -> ty::mt {
-
-        ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl}
-    }
-
     enum PointerTy {
         Box,
-        VStore(ty::vstore)
+        VStore(ty::Vstore)
     }
     impl PointerTy {
-        fn expect_vstore(&self, tcx: &ty::ctxt, span: Span, ty: &str) -> ty::vstore {
+        fn expect_vstore(&self, tcx: &ty::ctxt, span: Span, ty: &str) -> ty::Vstore {
             match *self {
                 Box => {
                     tcx.sess.span_err(span, format!("managed {} are not supported", ty));
                     // everything can be ~, so this is a worth substitute
-                    ty::vstore_uniq
+                    ty::VstoreUniq
                 }
                 VStore(vst) => vst
             }
@@ -408,41 +396,44 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                   RS:RegionScope>(
                   this: &AC,
                   rscope: &RS,
-                  a_seq_ty: &ast::MutTy,
+                  a_seq_ty: &ast::Ty,
                   ptr_ty: PointerTy,
-                  constr: |ty::mt| -> ty::t)
+                  constr: |ty::t| -> ty::t)
                   -> ty::t {
         let tcx = this.tcx();
         debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
 
-        match a_seq_ty.ty.node {
+        match a_seq_ty.node {
             ast::TyVec(ty) => {
-                let vst = ptr_ty.expect_vstore(tcx, a_seq_ty.ty.span, "vectors");
-                let mut mt = ast_ty_to_mt(this, rscope, ty);
-                if a_seq_ty.mutbl == ast::MutMutable {
-                    mt.mutbl = ast::MutMutable;
-                }
+                let vst = ptr_ty.expect_vstore(tcx, a_seq_ty.span, "vectors");
                 debug!("&[]: vst={:?}", vst);
-                return ty::mk_vec(tcx, mt, vst);
+                return ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty), vst);
             }
             ast::TyPath(ref path, ref bounds, id) => {
                 // Note that the "bounds must be empty if path is not a trait"
                 // restriction is enforced in the below case for ty_path, which
                 // will run after this as long as the path isn't a trait.
                 match tcx.def_map.borrow().find(&id) {
-                    Some(&ast::DefPrimTy(ast::TyStr)) if
-                            a_seq_ty.mutbl == ast::MutImmutable => {
+                    Some(&ast::DefPrimTy(ast::TyStr)) => {
                         check_path_args(tcx, path, NO_TPS | NO_REGIONS);
                         let vst = ptr_ty.expect_vstore(tcx, path.span, "strings");
-                        return ty::mk_str(tcx, vst);
+                        match vst {
+                            ty::VstoreUniq => {
+                                return ty::mk_str(tcx, ty::VstoreUniq);
+                            }
+                            ty::VstoreSlice(r, ast::MutImmutable) => {
+                                return ty::mk_str(tcx, ty::VstoreSlice(r, ()));
+                            }
+                            _ => {}
+                        }
                     }
                     Some(&ast::DefTrait(trait_def_id)) => {
                         let result = ast_path_to_trait_ref(
                             this, rscope, trait_def_id, None, path);
                         let trait_store = match ptr_ty {
-                            VStore(ty::vstore_uniq) => ty::UniqTraitStore,
-                            VStore(ty::vstore_slice(r)) => {
-                                ty::RegionTraitStore(r)
+                            VStore(ty::VstoreUniq) => ty::UniqTraitStore,
+                            VStore(ty::VstoreSlice(r, m)) => {
+                                ty::RegionTraitStore(r, m)
                             }
                             _ => {
                                 tcx.sess.span_err(
@@ -457,7 +448,6 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                                             result.def_id,
                                             result.substs.clone(),
                                             trait_store,
-                                            a_seq_ty.mutbl,
                                             bounds);
                     }
                     _ => {}
@@ -466,8 +456,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
             _ => {}
         }
 
-        let seq_ty = ast_mt_to_mt(this, rscope, a_seq_ty);
-        return constr(seq_ty);
+        constr(ast_ty_to_ty(this, rscope, a_seq_ty))
     }
 
     let tcx = this.tcx();
@@ -490,27 +479,28 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
             ast::TyNil => ty::mk_nil(),
             ast::TyBot => ty::mk_bot(),
             ast::TyBox(ty) => {
-                let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
-                mk_pointer(this, rscope, &mt, Box, |tmt| ty::mk_box(tcx, tmt.ty))
+                mk_pointer(this, rscope, ty, Box, |ty| ty::mk_box(tcx, ty))
             }
             ast::TyUniq(ty) => {
-                let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
-                mk_pointer(this, rscope, &mt, VStore(ty::vstore_uniq),
-                           |tmt| ty::mk_uniq(tcx, tmt.ty))
+                mk_pointer(this, rscope, ty, VStore(ty::VstoreUniq),
+                           |ty| ty::mk_uniq(tcx, ty))
             }
             ast::TyVec(ty) => {
                 tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
                 // return /something/ so they can at least get more errors
-                ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), ty::vstore_uniq)
+                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty), ty::VstoreUniq)
             }
             ast::TyPtr(ref mt) => {
-                ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt))
+                ty::mk_ptr(tcx, ty::mt {
+                    ty: ast_ty_to_ty(this, rscope, mt.ty),
+                    mutbl: mt.mutbl
+                })
             }
             ast::TyRptr(ref region, ref mt) => {
                 let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
                 debug!("ty_rptr r={}", r.repr(this.tcx()));
-                mk_pointer(this, rscope, mt, VStore(ty::vstore_slice(r)),
-                           |tmt| ty::mk_rptr(tcx, r, tmt))
+                mk_pointer(this, rscope, &*mt.ty, VStore(ty::VstoreSlice(r, mt.mutbl)),
+                           |ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
             }
             ast::TyTup(ref fields) => {
                 let flds = fields.iter()
@@ -535,7 +525,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                 let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil {
                         // Use corresponding trait store to figure out default bounds
                         // if none were specified.
-                        ast::BorrowedSigil => ty::RegionTraitStore(ty::ReEmpty), // dummy region
+                        ast::BorrowedSigil => {
+                            // dummy region
+                            ty::RegionTraitStore(ty::ReEmpty, ast::MutMutable)
+                        }
                         ast::OwnedSigil    => ty::UniqTraitStore,
                         ast::ManagedSigil  => return ty::mk_err()
                     });
@@ -610,11 +603,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                     Ok(ref r) => {
                         match *r {
                             const_eval::const_int(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
-                                           ty::vstore_fixed(i as uint)),
+                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
+                                           ty::VstoreFixed(i as uint)),
                             const_eval::const_uint(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
-                                           ty::vstore_fixed(i as uint)),
+                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
+                                           ty::VstoreFixed(i as uint)),
                             _ => {
                                 tcx.sess.span_fatal(
                                     ast_ty.span, "expected constant expr for vector length");
@@ -850,7 +843,7 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar
             builtin_bounds
         },
         // &'static Trait is sugar for &'static Trait:'static.
-        (&None, ty::RegionTraitStore(ty::ReStatic)) => {
+        (&None, ty::RegionTraitStore(ty::ReStatic, _)) => {
             let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundStatic); set
         }
         // No bounds are automatically applied for &'r Trait or ~Trait
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index bcad3a87582..7b8d77196d6 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -615,13 +615,13 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
             fcx.infcx().next_region_var(
                 infer::PatternRegion(pat.span));
 
-        let (elt_type, region_var) = match *structure_of(fcx,
-                                                         pat.span,
-                                                         expected) {
-          ty::ty_vec(mt, vstore) => {
-            let region_var = match vstore {
-                ty::vstore_slice(r) => r,
-                ty::vstore_uniq => {
+        let (elt_type, region_var, mutbl) = match *structure_of(fcx,
+                                                                pat.span,
+                                                                expected) {
+          ty::ty_vec(ty, vstore) => {
+            match vstore {
+                ty::VstoreSlice(r, m) => (ty, r, m),
+                ty::VstoreUniq => {
                     fcx.type_error_message(pat.span,
                                            |_| {
                                             ~"unique vector patterns are no \
@@ -629,13 +629,12 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                                            },
                                            expected,
                                            None);
-                    default_region_var
+                    (ty, default_region_var, ast::MutImmutable)
                 }
-                ty::vstore_fixed(_) => {
-                    default_region_var
+                ty::VstoreFixed(_) => {
+                    (ty, default_region_var, ast::MutImmutable)
                 }
-            };
-            (mt, region_var)
+            }
           }
           _ => {
               for &elt in before.iter() {
@@ -662,20 +661,20 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
           }
         };
         for elt in before.iter() {
-            check_pat(pcx, *elt, elt_type.ty);
+            check_pat(pcx, *elt, elt_type);
         }
         match slice {
             Some(slice_pat) => {
                 let slice_ty = ty::mk_vec(tcx,
-                    ty::mt {ty: elt_type.ty, mutbl: elt_type.mutbl},
-                    ty::vstore_slice(region_var)
+                    elt_type,
+                    ty::VstoreSlice(region_var, mutbl)
                 );
                 check_pat(pcx, slice_pat, slice_ty);
             }
             None => ()
         }
         for elt in after.iter() {
-            check_pat(pcx, *elt, elt_type.ty);
+            check_pat(pcx, *elt, elt_type);
         }
         fcx.write_ty(pat.id, expected);
       }
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 611b3653ab3..6d4e87d6340 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -264,12 +264,12 @@ fn construct_transformed_self_ty_for_object(
                 ty::ty_rptr(r, mt) => { // must be SelfRegion
                     let r = r.subst(tcx, &substs); // handle Early-Bound lifetime
                     ty::mk_trait(tcx, trait_def_id, substs,
-                                 RegionTraitStore(r), mt.mutbl,
+                                 RegionTraitStore(r, mt.mutbl),
                                  ty::EmptyBuiltinBounds())
                 }
                 ty::ty_uniq(_) => { // must be SelfUniq
                     ty::mk_trait(tcx, trait_def_id, substs,
-                                 UniqTraitStore, ast::MutImmutable,
+                                 UniqTraitStore,
                                  ty::EmptyBuiltinBounds())
                 }
                 _ => {
@@ -770,22 +770,21 @@ impl<'a> LookupContext<'a> {
                      autoderefs: autoderefs+1,
                      autoref: Some(ty::AutoPtr(region, self_mt.mutbl))})
             }
-            ty::ty_vec(self_mt, vstore_slice(_)) => {
+            ty::ty_vec(self_ty, VstoreSlice(_, mutbl)) => {
                 let region =
                     self.infcx().next_region_var(infer::Autoref(self.span));
-                (ty::mk_vec(tcx, self_mt, vstore_slice(region)),
+                (ty::mk_vec(tcx, self_ty, VstoreSlice(region, mutbl)),
                  ty::AutoDerefRef {
                      autoderefs: autoderefs,
-                     autoref: Some(ty::AutoBorrowVec(region, self_mt.mutbl))})
+                     autoref: Some(ty::AutoBorrowVec(region, mutbl))})
             }
             ty::ty_trait(~ty::TyTrait {
-                def_id, ref substs, store: ty::RegionTraitStore(_), mutability: mutbl, bounds
+                def_id, ref substs, store: ty::RegionTraitStore(_, mutbl), bounds
             }) => {
                 let region =
                     self.infcx().next_region_var(infer::Autoref(self.span));
                 (ty::mk_trait(tcx, def_id, substs.clone(),
-                              ty::RegionTraitStore(region),
-                              mutbl, bounds),
+                              ty::RegionTraitStore(region, mutbl), bounds),
                  ty::AutoDerefRef {
                      autoderefs: autoderefs,
                      autoref: Some(ty::AutoBorrowObj(region, mutbl))})
@@ -821,15 +820,13 @@ impl<'a> LookupContext<'a> {
         let tcx = self.tcx();
         let sty = ty::get(self_ty).sty.clone();
         match sty {
-            ty_vec(mt, vstore_uniq) |
-            ty_vec(mt, vstore_slice(_)) | // NDM(#3148)
-            ty_vec(mt, vstore_fixed(_)) => {
+            ty_vec(ty, VstoreUniq) |
+            ty_vec(ty, VstoreSlice(..)) |
+            ty_vec(ty, VstoreFixed(_)) => {
                 // First try to borrow to a slice
                 let entry = self.search_for_some_kind_of_autorefd_method(
                     AutoBorrowVec, autoderefs, [MutImmutable, MutMutable],
-                    |m,r| ty::mk_vec(tcx,
-                                     ty::mt {ty:mt.ty, mutbl:m},
-                                     vstore_slice(r)));
+                    |m,r| ty::mk_vec(tcx, ty, VstoreSlice(r, m)));
 
                 if entry.is_some() { return entry; }
 
@@ -837,9 +834,7 @@ impl<'a> LookupContext<'a> {
                 self.search_for_some_kind_of_autorefd_method(
                     AutoBorrowVecRef, autoderefs, [MutImmutable, MutMutable],
                     |m,r| {
-                        let slice_ty = ty::mk_vec(tcx,
-                                                  ty::mt {ty:mt.ty, mutbl:m},
-                                                  vstore_slice(r));
+                        let slice_ty = ty::mk_vec(tcx, ty, VstoreSlice(r, m));
                         // NB: we do not try to autoref to a mutable
                         // pointer. That would be creating a pointer
                         // to a temporary pointer (the borrowed
@@ -849,18 +844,18 @@ impl<'a> LookupContext<'a> {
                     })
             }
 
-            ty_str(vstore_uniq) |
-            ty_str(vstore_fixed(_)) => {
+            ty_str(VstoreUniq) |
+            ty_str(VstoreFixed(_)) => {
                 let entry = self.search_for_some_kind_of_autorefd_method(
                     AutoBorrowVec, autoderefs, [MutImmutable],
-                    |_m,r| ty::mk_str(tcx, vstore_slice(r)));
+                    |_m,r| ty::mk_str(tcx, VstoreSlice(r, ())));
 
                 if entry.is_some() { return entry; }
 
                 self.search_for_some_kind_of_autorefd_method(
                     AutoBorrowVecRef, autoderefs, [MutImmutable],
                     |m,r| {
-                        let slice_ty = ty::mk_str(tcx, vstore_slice(r));
+                        let slice_ty = ty::mk_str(tcx, VstoreSlice(r, ()));
                         ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
                     })
             }
@@ -870,9 +865,9 @@ impl<'a> LookupContext<'a> {
 
                 self.search_for_some_kind_of_autorefd_method(
                     AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
-                    |trt_mut, reg| {
+                    |m, r| {
                         ty::mk_trait(tcx, trt_did, trt_substs.clone(),
-                                     RegionTraitStore(reg), trt_mut, b)
+                                     RegionTraitStore(r, m), b)
                     })
             }
 
@@ -1303,7 +1298,7 @@ impl<'a> LookupContext<'a> {
                     }
 
                     ty::ty_trait(~ty::TyTrait {
-                        def_id: self_did, store: RegionTraitStore(_), mutability: self_m, ..
+                        def_id: self_did, store: RegionTraitStore(_, self_m), ..
                     }) => {
                         mutability_matches(self_m, m) &&
                         rcvr_matches_object(self_did, candidate)
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index bfbac7aaebb..3c28f2bac27 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1287,10 +1287,10 @@ pub fn check_lit(fcx: &FnCtxt, lit: &ast::Lit) -> ty::t {
     let tcx = fcx.ccx.tcx;
 
     match lit.node {
-        ast::LitStr(..) => ty::mk_str(tcx, ty::vstore_slice(ty::ReStatic)),
+        ast::LitStr(..) => ty::mk_str(tcx, ty::VstoreSlice(ty::ReStatic, ())),
         ast::LitBinary(..) => {
-            ty::mk_vec(tcx, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable },
-                       ty::vstore_slice(ty::ReStatic))
+            ty::mk_vec(tcx, ty::mk_u8(),
+                       ty::VstoreSlice(ty::ReStatic, ast::MutImmutable))
         }
         ast::LitChar(_) => ty::mk_char(),
         ast::LitInt(_, t) => ty::mk_mach_int(t),
@@ -2479,17 +2479,17 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
       ast::ExprVstore(ev, vst) => {
         let typ = match ev.node {
           ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
-            let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
-            ty::mk_str(tcx, tt)
+            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, ());
+            ty::mk_str(tcx, v)
           }
           ast::ExprVec(ref args) => {
-            let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
-            let mut any_error = false;
-            let mut any_bot = false;
             let mutability = match vst {
                 ast::ExprVstoreMutSlice => ast::MutMutable,
                 _ => ast::MutImmutable,
             };
+            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, mutability);
+            let mut any_error = false;
+            let mut any_bot = false;
             let t: ty::t = fcx.infcx().next_ty_var();
             for e in args.iter() {
                 check_expr_has_type(fcx, *e, t);
@@ -2506,18 +2506,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             } else if any_bot {
                 ty::mk_bot()
             } else {
-                ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutability}, tt)
+                ty::mk_vec(tcx, t, v)
             }
           }
           ast::ExprRepeat(element, count_expr) => {
             check_expr_with_hint(fcx, count_expr, ty::mk_uint());
             let _ = ty::eval_repeat_count(fcx, count_expr);
-            let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
             let mutability = match vst {
                 ast::ExprVstoreMutSlice => ast::MutMutable,
                 _ => ast::MutImmutable,
             };
-            let t: ty::t = fcx.infcx().next_ty_var();
+            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, mutability);
+            let t = fcx.infcx().next_ty_var();
             check_expr_has_type(fcx, element, t);
             let arg_t = fcx.expr_ty(element);
             if ty::type_is_error(arg_t) {
@@ -2525,7 +2525,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             } else if ty::type_is_bot(arg_t) {
                 ty::mk_bot()
             } else {
-                ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutability}, tt)
+                ty::mk_vec(tcx, t, v)
             }
           }
           _ =>
@@ -3022,8 +3022,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         for e in args.iter() {
             check_expr_has_type(fcx, *e, t);
         }
-        let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable},
-                             ty::vstore_fixed(args.len()));
+        let typ = ty::mk_vec(tcx, t, ty::VstoreFixed(args.len()));
         fcx.write_ty(id, typ);
       }
       ast::ExprRepeat(element, count_expr) => {
@@ -3039,8 +3038,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             fcx.write_bot(id);
         }
         else {
-            let t = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable},
-                               ty::vstore_fixed(count));
+            let t = ty::mk_vec(tcx, t, ty::VstoreFixed(count));
             fcx.write_ty(id, t);
         }
       }
@@ -3108,9 +3106,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
-                  Some(mt) => {
+                  Some(ty) => {
                       check_expr_has_type(fcx, idx, ty::mk_uint());
-                      fcx.write_ty(id, mt.ty);
+                      fcx.write_ty(id, ty);
                       fcx.write_autoderef_adjustment(base.id, autoderefs);
                   }
                   None => {
@@ -3852,33 +3850,33 @@ pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
     return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
 }
 
-pub fn ast_expr_vstore_to_vstore(fcx: &FnCtxt,
-                                 e: &ast::Expr,
-                                 v: ast::ExprVstore)
-                              -> ty::vstore {
+pub fn ast_expr_vstore_to_vstore<M>(fcx: &FnCtxt,
+                                    e: &ast::Expr,
+                                    v: ast::ExprVstore,
+                                    m: M)
+                                    -> ty::Vstore<M> {
     match v {
-        ast::ExprVstoreUniq => ty::vstore_uniq,
+        ast::ExprVstoreUniq => ty::VstoreUniq,
         ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
             match e.node {
                 ast::ExprLit(..) => {
                     // string literals and *empty slices* live in static memory
-                    ty::vstore_slice(ty::ReStatic)
+                    ty::VstoreSlice(ty::ReStatic, m)
                 }
                 ast::ExprVec(ref elements) if elements.len() == 0 => {
                     // string literals and *empty slices* live in static memory
-                    ty::vstore_slice(ty::ReStatic)
+                    ty::VstoreSlice(ty::ReStatic, m)
                 }
                 ast::ExprRepeat(..) |
                 ast::ExprVec(..) => {
                     // vector literals are temporaries on the stack
                     match fcx.tcx().region_maps.temporary_scope(e.id) {
                         Some(scope) => {
-                            let r = ty::ReScope(scope);
-                            ty::vstore_slice(r)
+                            ty::VstoreSlice(ty::ReScope(scope), m)
                         }
                         None => {
                             // this slice occurs in a static somewhere
-                            ty::vstore_slice(ty::ReStatic)
+                            ty::VstoreSlice(ty::ReStatic, m)
                         }
                     }
                 }
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index c8613fd7065..d1a6c069f23 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -419,7 +419,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                         infer::AutoBorrow(expr.span));
                 }
             }
-            ty::AutoObject(ast::BorrowedSigil, Some(trait_region), _, _, _, _) => {
+            ty::AutoObject(ty::RegionTraitStore(trait_region, _), _, _, _) => {
                 // Determine if we are casting `expr` to an trait
                 // instance.  If so, we have to be sure that the type of
                 // the source obeys the trait's region bound.
@@ -540,7 +540,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             // explaining how it goes about doing that.
             let target_ty = rcx.resolve_node_type(expr.id);
             match ty::get(target_ty).sty {
-                ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(trait_region), .. }) => {
+                ty::ty_trait(~ty::TyTrait {
+                    store: ty::RegionTraitStore(trait_region, _), ..
+                }) => {
                     let source_ty = rcx.resolve_expr_type_adjusted(source);
                     constrain_regions_in_type(
                         rcx,
@@ -923,8 +925,8 @@ fn constrain_index(rcx: &mut Rcx,
 
     let r_index_expr = ty::ReScope(index_expr.id);
     match ty::get(indexed_ty).sty {
-        ty::ty_str(ty::vstore_slice(r_ptr)) |
-        ty::ty_vec(_, ty::vstore_slice(r_ptr)) => {
+        ty::ty_str(ty::VstoreSlice(r_ptr, ())) |
+        ty::ty_vec(_, ty::VstoreSlice(r_ptr, _)) => {
             rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
                             r_index_expr, r_ptr);
         }
diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs
index febf47add43..44478376fd5 100644
--- a/src/librustc/middle/typeck/check/regionmanip.rs
+++ b/src/librustc/middle/typeck/check/regionmanip.rs
@@ -100,11 +100,11 @@ pub fn relate_nested_regions(tcx: &ty::ctxt,
 
         fn fold_ty(&mut self, ty: ty::t) -> ty::t {
             match ty::get(ty).sty {
-                ty::ty_rptr(r, ref mt) |
-                ty::ty_vec(ref mt, ty::vstore_slice(r)) => {
+                ty::ty_rptr(r, ty::mt {ty, ..}) |
+                ty::ty_vec(ty, ty::VstoreSlice(r, _)) => {
                     self.relate(r);
                     self.stack.push(r);
-                    ty_fold::super_fold_ty(self, mt.ty);
+                    ty_fold::super_fold_ty(self, ty);
                     self.stack.pop().unwrap();
                 }
 
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 67cf14050ed..cc8a2b82772 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -468,8 +468,7 @@ fn fixup_substs(vcx: &VtableContext,
     // use a dummy type just to package up the substs that need fixing up
     let t = ty::mk_trait(tcx,
                          id, substs,
-                         ty::RegionTraitStore(ty::ReStatic),
-                         ast::MutImmutable,
+                         ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable),
                          ty::EmptyBuiltinBounds());
     fixup_ty(vcx, span, t, is_early).map(|t_f| {
         match ty::get(t_f).sty {
@@ -532,8 +531,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
       match ty::get(target_ty).sty {
           // Bounds of type's contents are not checked here, but in kind.rs.
           ty::ty_trait(~ty::TyTrait {
-              def_id: target_def_id, substs: ref target_substs, store: store,
-              mutability: target_mutbl, bounds: _bounds
+              def_id: target_def_id, substs: ref target_substs, store, ..
           }) => {
               fn mutability_allowed(a_mutbl: ast::Mutability,
                                     b_mutbl: ast::Mutability) -> bool {
@@ -547,15 +545,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
               let ty = structurally_resolved_type(fcx, ex.span,
                                                   fcx.expr_ty(src));
               match (&ty::get(ty).sty, store) {
-                  (&ty::ty_uniq(..), ty::UniqTraitStore)
-                    if !mutability_allowed(ast::MutImmutable,
-                                           target_mutbl) => {
-                      fcx.tcx().sess.span_err(ex.span,
-                                              format!("types differ in mutability"));
-                  }
-
-                  (&ty::ty_rptr(_, mt), ty::RegionTraitStore(..))
-                    if !mutability_allowed(mt.mutbl, target_mutbl) => {
+                  (&ty::ty_rptr(_, mt), ty::RegionTraitStore(_, mutbl))
+                    if !mutability_allowed(mt.mutbl, mutbl) => {
                       fcx.tcx().sess.span_err(ex.span,
                                               format!("types differ in mutability"));
                   }
@@ -598,7 +589,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
                       // regions.
                       match (&ty::get(ty).sty, store) {
                           (&ty::ty_rptr(ra, _),
-                           ty::RegionTraitStore(rb)) => {
+                           ty::RegionTraitStore(rb, _)) => {
                               infer::mk_subr(fcx.infcx(),
                                              false,
                                              infer::RelateObjectBound(
@@ -618,7 +609,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
                                ty::ty_sort_str(fcx.tcx(), ty)));
                   }
 
-                  (_, ty::RegionTraitStore(_)) => {
+                  (_, ty::RegionTraitStore(..)) => {
                       fcx.ccx.tcx.sess.span_err(
                           ex.span,
                           format!("can only cast an &-pointer \
@@ -716,10 +707,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
                         }
                     }
                 }
-                AutoObject(ref sigil,
-                           ref region,
-                           m,
-                           b,
+                AutoObject(store,
+                           bounds,
                            def_id,
                            ref substs) => {
                     debug!("doing trait adjustment for expr {} {} \
@@ -728,13 +717,9 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
                            ex.repr(fcx.tcx()),
                            is_early);
 
-                    let object_ty = ty::trait_adjustment_to_ty(cx.tcx,
-                                                               sigil,
-                                                               region,
-                                                               def_id,
-                                                               substs,
-                                                               m,
-                                                               b);
+                    let object_ty = ty::mk_trait(cx.tcx, def_id,
+                                                 substs.clone(),
+                                                 store, bounds);
                     resolve_object_cast(ex, object_ty);
                 }
                 AutoAddEnv(..) => {}
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index 38ffa2ae508..d76bfed661e 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -67,7 +67,7 @@ we may want to adjust precisely when coercions occur.
 
 use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn, AutoBorrowObj};
 use middle::ty::{AutoDerefRef};
-use middle::ty::{vstore_slice, vstore_uniq};
+use middle::ty::{VstoreSlice, VstoreUniq};
 use middle::ty::{mt};
 use middle::ty;
 use middle::typeck::infer::{CoerceResult, resolve_type, Coercion};
@@ -108,15 +108,15 @@ impl<'f> Coerce<'f> {
                 });
             }
 
-            ty::ty_str(vstore_slice(_)) => {
+            ty::ty_str(VstoreSlice(..)) => {
                 return self.unpack_actual_value(a, |sty_a| {
                     self.coerce_borrowed_string(a, sty_a, b)
                 });
             }
 
-            ty::ty_vec(mt_b, vstore_slice(_)) => {
+            ty::ty_vec(_, VstoreSlice(_, mutbl_b)) => {
                 return self.unpack_actual_value(a, |sty_a| {
-                    self.coerce_borrowed_vector(a, sty_a, b, mt_b)
+                    self.coerce_borrowed_vector(a, sty_a, b, mutbl_b)
                 });
             }
 
@@ -133,13 +133,13 @@ impl<'f> Coerce<'f> {
             }
 
             ty::ty_trait(~ty::TyTrait {
-                def_id, ref substs, store: ty::UniqTraitStore, mutability: m, bounds
+                def_id, ref substs, store: ty::UniqTraitStore, bounds
             }) => {
                 let result = self.unpack_actual_value(a, |sty_a| {
                     match *sty_a {
                         ty::ty_uniq(..) => {
                             self.coerce_object(a, sty_a, b, def_id, substs,
-                                               ty::UniqTraitStore, m, bounds)
+                                               ty::UniqTraitStore, bounds)
                         }
                         _ => Err(ty::terr_mismatch)
                     }
@@ -152,13 +152,13 @@ impl<'f> Coerce<'f> {
             }
 
             ty::ty_trait(~ty::TyTrait {
-                def_id, ref substs, store: ty::RegionTraitStore(region), mutability: m, bounds
+                def_id, ref substs, store: ty::RegionTraitStore(region, m), bounds
             }) => {
                 let result = self.unpack_actual_value(a, |sty_a| {
                     match *sty_a {
                         ty::ty_rptr(..) => {
                             self.coerce_object(a, sty_a, b, def_id, substs,
-                                               ty::RegionTraitStore(region), m, bounds)
+                                               ty::RegionTraitStore(region, m), bounds)
                         }
                         _ => self.coerce_borrowed_object(a, sty_a, b, m)
                     }
@@ -260,14 +260,14 @@ impl<'f> Coerce<'f> {
                b.inf_str(self.get_ref().infcx));
 
         match *sty_a {
-            ty::ty_str(vstore_uniq) => {}
+            ty::ty_str(VstoreUniq) => {}
             _ => {
                 return self.subtype(a, b);
             }
         };
 
         let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
-        let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, vstore_slice(r_a));
+        let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, VstoreSlice(r_a, ()));
         if_ok!(self.subtype(a_borrowed, b));
         Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
@@ -279,7 +279,7 @@ impl<'f> Coerce<'f> {
                                   a: ty::t,
                                   sty_a: &ty::sty,
                                   b: ty::t,
-                                  mt_b: ty::mt)
+                                  mutbl_b: ast::Mutability)
                                   -> CoerceResult {
         debug!("coerce_borrowed_vector(a={}, sty_a={:?}, b={})",
                a.inf_str(self.get_ref().infcx), sty_a,
@@ -288,19 +288,18 @@ impl<'f> Coerce<'f> {
         let sub = Sub(*self.get_ref());
         let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
         let ty_inner = match *sty_a {
-            ty::ty_vec(mt, _) => mt.ty,
+            ty::ty_vec(ty, _) => ty,
             _ => {
                 return self.subtype(a, b);
             }
         };
 
-        let a_borrowed = ty::mk_vec(self.get_ref().infcx.tcx,
-                                    mt {ty: ty_inner, mutbl: mt_b.mutbl},
-                                    vstore_slice(r_borrow));
+        let a_borrowed = ty::mk_vec(self.get_ref().infcx.tcx, ty_inner,
+                                    VstoreSlice(r_borrow, mutbl_b));
         if_ok!(sub.tys(a_borrowed, b));
         Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
-            autoref: Some(AutoBorrowVec(r_borrow, mt_b.mutbl))
+            autoref: Some(AutoBorrowVec(r_borrow, mutbl_b))
         })))
     }
 
@@ -320,7 +319,7 @@ impl<'f> Coerce<'f> {
         let a_borrowed = match *sty_a {
             ty::ty_trait(~ty::TyTrait { def_id, ref substs, bounds, .. }) => {
                 ty::mk_trait(tcx, def_id, substs.clone(),
-                             ty::RegionTraitStore(r_a), b_mutbl, bounds)
+                             ty::RegionTraitStore(r_a, b_mutbl), bounds)
             }
             _ => {
                 return self.subtype(a, b);
@@ -442,21 +441,13 @@ impl<'f> Coerce<'f> {
                          trait_def_id: ast::DefId,
                          trait_substs: &ty::substs,
                          trait_store: ty::TraitStore,
-                         m: ast::Mutability,
                          bounds: ty::BuiltinBounds) -> CoerceResult {
 
         debug!("coerce_object(a={}, sty_a={:?}, b={})",
                a.inf_str(self.get_ref().infcx), sty_a,
                b.inf_str(self.get_ref().infcx));
 
-        let (sigil, region) = match trait_store {
-            ty::UniqTraitStore => (ast::OwnedSigil, None),
-            ty::RegionTraitStore(region) => (ast::BorrowedSigil, Some(region))
-        };
-
-        let adjustment = @ty::AutoObject(sigil, region, m, bounds,
-                                         trait_def_id, trait_substs.clone());
-
-        Ok(Some(adjustment))
+        Ok(Some(@ty::AutoObject(trait_store, bounds,
+                                trait_def_id, trait_substs.clone())))
     }
 }
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 555aaa90da1..a2a7f9ec8bd 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -263,16 +263,16 @@ pub trait Combine {
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
 
     fn vstores(&self,
-               vk: ty::terr_vstore_kind,
-               a: ty::vstore,
-               b: ty::vstore)
-               -> cres<ty::vstore> {
+                vk: ty::terr_vstore_kind,
+                a: ty::Vstore<()>,
+                b: ty::Vstore<()>)
+                -> cres<ty::Vstore<()>> {
         debug!("{}.vstores(a={:?}, b={:?})", self.tag(), a, b);
 
         match (a, b) {
-            (ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
+            (ty::VstoreSlice(a_r, _), ty::VstoreSlice(b_r, _)) => {
                 self.contraregions(a_r, b_r).and_then(|r| {
-                    Ok(ty::vstore_slice(r))
+                    Ok(ty::VstoreSlice(r, ()))
                 })
             }
 
@@ -294,9 +294,10 @@ pub trait Combine {
         debug!("{}.trait_stores(a={:?}, b={:?})", self.tag(), a, b);
 
         match (a, b) {
-            (ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
+            (ty::RegionTraitStore(a_r, a_m),
+             ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => {
                 self.contraregions(a_r, b_r).and_then(|r| {
-                    Ok(ty::RegionTraitStore(r))
+                    Ok(ty::RegionTraitStore(r, a_m))
                 })
             }
 
@@ -480,7 +481,7 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
 
       (&ty::ty_trait(ref a_),
        &ty::ty_trait(ref b_))
-      if a_.def_id == b_.def_id && a_.mutability == b_.mutability => {
+      if a_.def_id == b_.def_id => {
           debug!("Trying to match traits {:?} and {:?}", a, b);
           let substs = if_ok!(this.substs(a_.def_id, &a_.substs, &b_.substs));
           let s = if_ok!(this.trait_stores(ty::terr_trait, a_.store, b_.store));
@@ -489,7 +490,6 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
                           a_.def_id,
                           substs.clone(),
                           s,
-                          a_.mutability,
                           bounds))
       }
 
@@ -517,10 +517,34 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
           Ok(ty::mk_rptr(tcx, r, mt))
       }
 
-      (&ty::ty_vec(ref a_mt, vs_a), &ty::ty_vec(ref b_mt, vs_b)) => {
-        this.mts(a_mt, b_mt).and_then(|mt| {
+      (&ty::ty_vec(a_inner, vs_a), &ty::ty_vec(b_inner, vs_b)) => {
+        // This could be nicer if we didn't have to go through .mts(a, b).
+        let (vs_a, mutbl_a) = match vs_a {
+            ty::VstoreFixed(n) => (ty::VstoreFixed(n), ast::MutImmutable),
+            ty::VstoreSlice(r, m) => (ty::VstoreSlice(r, ()), m),
+            ty::VstoreUniq => (ty::VstoreUniq, ast::MutImmutable)
+        };
+        let (vs_b, mutbl_b) = match vs_b {
+            ty::VstoreFixed(n) => (ty::VstoreFixed(n), ast::MutImmutable),
+            ty::VstoreSlice(r, m) => (ty::VstoreSlice(r, ()), m),
+            ty::VstoreUniq => (ty::VstoreUniq, ast::MutImmutable)
+        };
+        let a_mt = ty::mt {
+            ty: a_inner,
+            mutbl: mutbl_a
+        };
+        let b_mt = ty::mt {
+            ty: b_inner,
+            mutbl: mutbl_b
+        };
+        this.mts(&a_mt, &b_mt).and_then(|mt| {
             this.vstores(ty::terr_vec, vs_a, vs_b).and_then(|vs| {
-                Ok(ty::mk_vec(tcx, mt, vs))
+                let store = match vs {
+                    ty::VstoreFixed(n) => ty::VstoreFixed(n),
+                    ty::VstoreSlice(r, _) => ty::VstoreSlice(r, mt.mutbl),
+                    ty::VstoreUniq => ty::VstoreUniq
+                };
+                Ok(ty::mk_vec(tcx, mt.ty, store))
             })
         })
       }
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index e01e34a0e5a..d80a2518055 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -680,7 +680,6 @@ impl<'a> InferCtxt<'a> {
                                   trait_ref.def_id,
                                   trait_ref.substs.clone(),
                                   ty::UniqTraitStore,
-                                  ast::MutImmutable,
                                   ty::EmptyBuiltinBounds());
         let dummy1 = self.resolve_type_vars_if_possible(dummy0);
         match ty::get(dummy1).sty {
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 91d9b264a88..a0817360e39 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -645,9 +645,16 @@ impl<'a> ConstraintContext<'a> {
                 self.add_constraints_from_vstore(vstore, variance);
             }
 
-            ty::ty_vec(ref mt, vstore) => {
+            ty::ty_vec(ty, vstore) => {
                 self.add_constraints_from_vstore(vstore, variance);
-                self.add_constraints_from_mt(mt, variance);
+                let mt = ty::mt {
+                    ty: ty,
+                    mutbl: match vstore {
+                        ty::VstoreSlice(_, m) => m,
+                        _ => ast::MutImmutable
+                    }
+                };
+                self.add_constraints_from_mt(&mt, variance);
             }
 
             ty::ty_uniq(typ) | ty::ty_box(typ) => {
@@ -716,19 +723,18 @@ impl<'a> ConstraintContext<'a> {
         }
     }
 
-    /// Adds constraints appropriate for a vector with vstore `vstore`
+    /// Adds constraints appropriate for a vector with Vstore `vstore`
     /// appearing in a context with ambient variance `variance`
-    fn add_constraints_from_vstore(&mut self,
-                                   vstore: ty::vstore,
-                                   variance: VarianceTermPtr<'a>) {
+    fn add_constraints_from_vstore<M>(&mut self,
+                                      vstore: ty::Vstore<M>,
+                                      variance: VarianceTermPtr<'a>) {
         match vstore {
-            ty::vstore_slice(r) => {
+            ty::VstoreSlice(r, _) => {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(r, contra);
             }
 
-            ty::vstore_fixed(_) | ty::vstore_uniq => {
-            }
+            ty::VstoreFixed(_) | ty::VstoreUniq => {}
         }
     }
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0a9c6ee8e5c..3bb344548e1 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -198,36 +198,14 @@ pub fn mutability_to_str(m: ast::Mutability) -> ~str {
 }
 
 pub fn mt_to_str(cx: &ctxt, m: &mt) -> ~str {
-    mt_to_str_wrapped(cx, "", m, "")
-}
-
-pub fn mt_to_str_wrapped(cx: &ctxt, before: &str, m: &mt, after: &str) -> ~str {
-    let mstr = mutability_to_str(m.mutbl);
-    return format!("{}{}{}{}", mstr, before, ty_to_str(cx, m.ty), after);
-}
-
-pub fn vstore_to_str(cx: &ctxt, vs: ty::vstore) -> ~str {
-    match vs {
-      ty::vstore_fixed(n) => format!("{}", n),
-      ty::vstore_uniq => ~"~",
-      ty::vstore_slice(r) => region_ptr_to_str(cx, r)
-    }
+    format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
 }
 
 pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> ~str {
     match s {
-      ty::UniqTraitStore => ~"~",
-      ty::RegionTraitStore(r) => region_ptr_to_str(cx, r)
-    }
-}
-
-pub fn vstore_ty_to_str(cx: &ctxt, mt: &mt, vs: ty::vstore) -> ~str {
-    match vs {
-        ty::vstore_fixed(_) => {
-            format!("[{}, .. {}]", mt_to_str(cx, mt), vstore_to_str(cx, vs))
-        }
-        _ => {
-            format!("{}{}", vstore_to_str(cx, vs), mt_to_str_wrapped(cx, "[", mt, "]"))
+        ty::UniqTraitStore => ~"~",
+        ty::RegionTraitStore(r, m) => {
+            format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
         }
     }
 }
@@ -435,20 +413,32 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
                       false)
       }
       ty_trait(~ty::TyTrait {
-          def_id: did, ref substs, store: s, mutability: mutbl, ref bounds
+          def_id: did, ref substs, store, ref bounds
       }) => {
         let base = ty::item_path_str(cx, did);
         let ty = parameterized(cx, base, &substs.regions,
                                substs.tps.as_slice(), did, true);
         let bound_sep = if bounds.is_empty() { "" } else { ":" };
         let bound_str = bounds.repr(cx);
-        format!("{}{}{}{}{}", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty,
-                           bound_sep, bound_str)
+        format!("{}{}{}{}", trait_store_to_str(cx, store), ty, bound_sep, bound_str)
+      }
+      ty_vec(ty, vs) => {
+        match vs {
+            ty::VstoreFixed(n) => {
+                format!("[{}, .. {}]", ty_to_str(cx, ty), n)
+            }
+            _ => {
+                format!("{}[{}]", vs.repr(cx), ty_to_str(cx, ty))
+            }
+        }
       }
-      ty_vec(ref mt, vs) => {
-        vstore_ty_to_str(cx, mt, vs)
+      ty_str(vs) => {
+        match vs {
+            ty::VstoreFixed(n) => format!("str/{}", n),
+            ty::VstoreUniq => ~"~str",
+            ty::VstoreSlice(r, ()) => format!("{}str", region_ptr_to_str(cx, r))
+        }
       }
-      ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str")
     }
 }
 
@@ -881,16 +871,29 @@ impl Repr for ty::RegionVid {
 
 impl Repr for ty::TraitStore {
     fn repr(&self, tcx: &ctxt) -> ~str {
-        match self {
-            &ty::UniqTraitStore => ~"~Trait",
-            &ty::RegionTraitStore(r) => format!("&{} Trait", r.repr(tcx))
+        trait_store_to_str(tcx, *self)
+    }
+}
+
+impl Repr for ty::Vstore {
+    fn repr(&self, tcx: &ctxt) -> ~str {
+        match *self {
+            ty::VstoreFixed(n) => format!("{}", n),
+            ty::VstoreUniq => ~"~",
+            ty::VstoreSlice(r, m) => {
+                format!("{}{}", region_ptr_to_str(tcx, r), mutability_to_str(m))
+            }
         }
     }
 }
 
-impl Repr for ty::vstore {
+impl Repr for ty::Vstore<()> {
     fn repr(&self, tcx: &ctxt) -> ~str {
-        vstore_to_str(tcx, *self)
+        match *self {
+            ty::VstoreFixed(n) => format!("{}", n),
+            ty::VstoreUniq => ~"~",
+            ty::VstoreSlice(r, ()) => region_ptr_to_str(tcx, r)
+        }
     }
 }