about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/tydecode.rs14
-rw-r--r--src/librustc/metadata/tyencode.rs16
-rw-r--r--src/librustc/middle/kind.rs2
-rw-r--r--src/librustc/middle/trans/base.rs27
-rw-r--r--src/librustc/middle/trans/common.rs12
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/trans/glue.rs10
-rw-r--r--src/librustc/middle/trans/meth.rs56
-rw-r--r--src/librustc/middle/trans/monomorphize.rs13
-rw-r--r--src/librustc/middle/trans/reflect.rs4
-rw-r--r--src/librustc/middle/trans/type_of.rs4
-rw-r--r--src/librustc/middle/ty.rs117
-rw-r--r--src/librustc/middle/typeck/astconv.rs20
-rw-r--r--src/librustc/middle/typeck/check/method.rs8
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs2
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs50
-rw-r--r--src/librustc/middle/typeck/collect.rs11
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs46
-rw-r--r--src/librustc/middle/typeck/infer/glb.rs8
-rw-r--r--src/librustc/middle/typeck/infer/lub.rs8
-rw-r--r--src/librustc/middle/typeck/infer/sub.rs8
-rw-r--r--src/librustc/middle/typeck/mod.rs2
-rw-r--r--src/librustc/util/ppaux.rs13
23 files changed, 293 insertions, 162 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 04dd9156660..e9cbd2685df 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -157,6 +157,16 @@ fn parse_vstore(st: @mut PState) -> ty::vstore {
     }
 }
 
+fn parse_trait_store(st: @mut PState) -> ty::TraitStore {
+    match next(st) {
+        '~' => ty::UniqTraitStore,
+        '@' => ty::BoxTraitStore,
+        '&' => ty::RegionTraitStore(parse_region(st)),
+        '.' => ty::BareTraitStore,
+        c => st.tcx.sess.bug(fmt!("parse_trait_store(): bad input '%c'", c))
+    }
+}
+
 fn parse_substs(st: @mut PState, conv: conv_did) -> ty::substs {
     let self_r = parse_opt(st, || parse_region(st) );
 
@@ -269,9 +279,9 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
         fail_unless!(next(st) == '[');
         let def = parse_def(st, NominalType, conv);
         let substs = parse_substs(st, conv);
-        let vstore = parse_vstore(st);
+        let store = parse_trait_store(st);
         fail_unless!(next(st) == ']');
-        return ty::mk_trait(st.tcx, def, substs, vstore);
+        return ty::mk_trait(st.tcx, def, substs, store);
       }
       'p' => {
         let did = parse_def(st, TypeParameter, conv);
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index d07d8917c65..ff24a889163 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -214,6 +214,18 @@ pub fn enc_vstore(w: io::Writer, cx: @ctxt, v: ty::vstore) {
     }
 }
 
+pub fn enc_trait_store(w: io::Writer, cx: @ctxt, s: ty::TraitStore) {
+    match s {
+        ty::UniqTraitStore => w.write_char('~'),
+        ty::BoxTraitStore => w.write_char('@'),
+        ty::BareTraitStore => w.write_char('.'),
+        ty::RegionTraitStore(re) => {
+            w.write_char('&');
+            enc_region(w, cx, re);
+        }
+    }
+}
+
 fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
     match st {
       ty::ty_nil => w.write_char('n'),
@@ -252,12 +264,12 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
         enc_substs(w, cx, (*substs));
         w.write_char(']');
       }
-      ty::ty_trait(def, ref substs, vstore) => {
+      ty::ty_trait(def, ref substs, store) => {
         w.write_str(&"x[");
         w.write_str((cx.ds)(def));
         w.write_char('|');
         enc_substs(w, cx, (*substs));
-        enc_vstore(w, cx, vstore);
+        enc_trait_store(w, cx, store);
         w.write_char(']');
       }
       ty::ty_tup(ts) => {
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 48d136ce65f..99781a80c62 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -462,7 +462,7 @@ pub fn check_cast_for_escaping_regions(
 pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) {
     let target_ty = ty::expr_ty(cx.tcx, target);
     match ty::get(target_ty).sty {
-        ty::ty_trait(_, _, ty::vstore_uniq) => {
+        ty::ty_trait(_, _, ty::UniqTraitStore) => {
             let source_ty = ty::expr_ty(cx.tcx, source);
             if !ty::type_is_owned(cx.tcx, source_ty) {
                 cx.tcx.sess.span_err(
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 2ab4454a89a..a340e6472b8 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -802,13 +802,36 @@ pub fn trans_external_path(ccx: @CrateContext, did: ast::def_id, t: ty::t)
 pub fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block {
     let _icx = bcx.insn_ctxt("invoke_");
     if bcx.unreachable { return bcx; }
+
+    match bcx.node_info {
+        None => error!("invoke at ???"),
+        Some(node_info) => {
+            error!("invoke at %s",
+                   bcx.sess().codemap.span_to_str(node_info.span));
+        }
+    }
+
     if need_invoke(bcx) {
-        debug!("invoking");
+        unsafe {
+            debug!("invoking %x at %x",
+                   ::core::cast::transmute(llfn),
+                   ::core::cast::transmute(bcx.llbb));
+            for llargs.each |&llarg| {
+                debug!("arg: %x", ::core::cast::transmute(llarg));
+            }
+        }
         let normal_bcx = sub_block(bcx, ~"normal return");
         Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
         return normal_bcx;
     } else {
-        debug!("calling");
+        unsafe {
+            debug!("calling %x at %x",
+                   ::core::cast::transmute(llfn),
+                   ::core::cast::transmute(bcx.llbb));
+            for llargs.each |&llarg| {
+                debug!("arg: %x", ::core::cast::transmute(llarg));
+            }
+        }
         Call(bcx, llfn, llargs);
         return bcx;
     }
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 2e5dee49c34..70fc29fd25b 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -1033,17 +1033,19 @@ pub fn T_captured_tydescs(cx: @CrateContext, n: uint) -> TypeRef {
     return T_struct(vec::from_elem::<TypeRef>(n, T_ptr(cx.tydesc_type)));
 }
 
-pub fn T_opaque_trait(cx: @CrateContext, vstore: ty::vstore) -> TypeRef {
-    match vstore {
-        ty::vstore_box => {
+pub fn T_opaque_trait(cx: @CrateContext, store: ty::TraitStore) -> TypeRef {
+    match store {
+        ty::BoxTraitStore | ty::BareTraitStore => {
             T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)])
         }
-        ty::vstore_uniq => {
+        ty::UniqTraitStore => {
             T_struct(~[T_ptr(cx.tydesc_type),
                        T_unique_ptr(T_unique(cx, T_i8())),
                        T_ptr(cx.tydesc_type)])
         }
-        _ => T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())])
+        ty::RegionTraitStore(_) => {
+            T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())])
+        }
     }
 }
 
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index c163183bfc8..e986d0bdae3 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -678,9 +678,9 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
         }
         ast::expr_cast(val, _) => {
             match ty::get(node_id_type(bcx, expr.id)).sty {
-                ty::ty_trait(_, _, vstore) => {
+                ty::ty_trait(_, _, store) => {
                     return meth::trans_trait_cast(bcx, val, expr.id, dest,
-                                                  vstore);
+                                                  store);
                 }
                 _ => {
                     bcx.tcx().sess.span_bug(expr.span,
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index b3905680f72..8302f46120e 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -551,11 +551,12 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
       ty::ty_closure(_) => {
         closure::make_closure_glue(bcx, v0, t, drop_ty)
       }
-      ty::ty_trait(_, _, ty::vstore_box) => {
+      ty::ty_trait(_, _, ty::BoxTraitStore) |
+      ty::ty_trait(_, _, ty::BareTraitStore) => {
         let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u]));
         decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
       }
-      ty::ty_trait(_, _, ty::vstore_uniq) => {
+      ty::ty_trait(_, _, ty::UniqTraitStore) => {
         let lluniquevalue = GEPi(bcx, v0, [0, 1]);
         let lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2]));
         call_tydesc_glue_full(bcx, lluniquevalue, lltydesc,
@@ -617,12 +618,13 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
       ty::ty_closure(_) => {
         closure::make_closure_glue(bcx, v, t, take_ty)
       }
-      ty::ty_trait(_, _, ty::vstore_box) => {
+      ty::ty_trait(_, _, ty::BoxTraitStore) |
+      ty::ty_trait(_, _, ty::BareTraitStore) => {
         let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u]));
         incr_refcnt_of_boxed(bcx, llbox);
         bcx
       }
-      ty::ty_trait(_, _, ty::vstore_uniq) => {
+      ty::ty_trait(_, _, ty::UniqTraitStore) => {
         let llval = GEPi(bcx, v, [0, 1]);
         let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2]));
         call_tydesc_glue_full(bcx, llval, lltydesc,
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index b8c5ff4258c..5a46c24b939 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -249,12 +249,12 @@ pub fn trans_method_callee(bcx: block,
                 None => fail!(~"trans_method_callee: missing param_substs")
             }
         }
-        typeck::method_trait(_, off, vstore) => {
+        typeck::method_trait(_, off, store) => {
             trans_trait_callee(bcx,
                                callee_id,
                                off,
                                self,
-                               vstore,
+                               store,
                                mentry.explicit_self)
         }
         typeck::method_self(*) | typeck::method_super(*) => {
@@ -570,7 +570,7 @@ pub fn trans_trait_callee(bcx: block,
                           callee_id: ast::node_id,
                           n_method: uint,
                           self_expr: @ast::expr,
-                          vstore: ty::vstore,
+                          store: ty::TraitStore,
                           explicit_self: ast::self_ty_)
                        -> Callee {
     //!
@@ -599,7 +599,7 @@ pub fn trans_trait_callee(bcx: block,
                                   callee_ty,
                                   n_method,
                                   llpair,
-                                  vstore,
+                                  store,
                                   explicit_self)
 }
 
@@ -607,7 +607,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
                                      callee_ty: ty::t,
                                      n_method: uint,
                                      llpair: ValueRef,
-                                     vstore: ty::vstore,
+                                     store: ty::TraitStore,
                                      explicit_self: ast::self_ty_)
                                   -> Callee {
     //!
@@ -641,16 +641,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
         }
         ast::sty_by_ref => {
             // We need to pass a pointer to a pointer to the payload.
-            match vstore {
-                ty::vstore_box | ty::vstore_uniq => {
+            match store {
+                ty::BoxTraitStore |
+                ty::BareTraitStore |
+                ty::UniqTraitStore => {
                     llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
                 }
-                ty::vstore_slice(_) => {
+                ty::RegionTraitStore(_) => {
                     llself = llbox;
                 }
-                ty::vstore_fixed(*) => {
-                    bcx.tcx().sess.bug(~"vstore_fixed trait");
-                }
             }
 
             self_mode = ast::by_ref;
@@ -662,16 +661,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
         ast::sty_region(_) => {
             // As before, we need to pass a pointer to a pointer to the
             // payload.
-            match vstore {
-                ty::vstore_box | ty::vstore_uniq => {
+            match store {
+                ty::BoxTraitStore |
+                ty::BareTraitStore |
+                ty::UniqTraitStore => {
                     llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
                 }
-                ty::vstore_slice(_) => {
+                ty::RegionTraitStore(_) => {
                     llself = llbox;
                 }
-                ty::vstore_fixed(*) => {
-                    bcx.tcx().sess.bug(~"vstore_fixed trait");
-                }
             }
 
             let llscratch = alloca(bcx, val_ty(llself));
@@ -687,8 +685,8 @@ pub fn trans_trait_callee_from_llval(bcx: block,
             bcx = glue::take_ty(bcx, llbox, callee_ty);
 
             // Pass a pointer to the box.
-            match vstore {
-                ty::vstore_box => llself = llbox,
+            match store {
+                ty::BoxTraitStore | ty::BareTraitStore => llself = llbox,
                 _ => bcx.tcx().sess.bug(~"@self receiver with non-@Trait")
             }
 
@@ -700,8 +698,8 @@ pub fn trans_trait_callee_from_llval(bcx: block,
         }
         ast::sty_uniq(_) => {
             // Pass the unique pointer.
-            match vstore {
-                ty::vstore_uniq => llself = llbox,
+            match store {
+                ty::UniqTraitStore => llself = llbox,
                 _ => bcx.tcx().sess.bug(~"~self receiver with non-~Trait")
             }
 
@@ -796,7 +794,9 @@ pub fn make_impl_vtable(ccx: @CrateContext,
     // XXX: This should support multiple traits.
     let trt_id = driver::session::expect(
         tcx.sess,
-        ty::ty_to_def_id(ty::impl_traits(tcx, impl_id, ty::vstore_box)[0]),
+        ty::ty_to_def_id(ty::impl_traits(tcx,
+                                         impl_id,
+                                         ty::BoxTraitStore)[0]),
         || ~"make_impl_vtable: non-trait-type implemented");
 
     let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
@@ -834,7 +834,7 @@ pub fn trans_trait_cast(bcx: block,
                         val: @ast::expr,
                         id: ast::node_id,
                         dest: expr::Dest,
-                        vstore: ty::vstore)
+                        store: ty::TraitStore)
                      -> block {
     let mut bcx = bcx;
     let _icx = bcx.insn_ctxt("impl::trans_cast");
@@ -849,8 +849,8 @@ pub fn trans_trait_cast(bcx: block,
     let ccx = bcx.ccx();
     let v_ty = expr_ty(bcx, val);
 
-    match vstore {
-        ty::vstore_slice(*) | ty::vstore_box => {
+    match store {
+        ty::RegionTraitStore(_) | ty::BoxTraitStore | ty::BareTraitStore => {
             let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]);
             // Just store the pointer into the pair.
             llboxdest = PointerCast(bcx,
@@ -858,7 +858,7 @@ pub fn trans_trait_cast(bcx: block,
                                     T_ptr(type_of(bcx.ccx(), v_ty)));
             bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
         }
-        ty::vstore_uniq => {
+        ty::UniqTraitStore => {
             // Translate the uniquely-owned value into the second element of
             // the triple. (The first element is the vtable.)
             let mut llvaldest = GEPi(bcx, lldest, [0, 1]);
@@ -874,10 +874,6 @@ pub fn trans_trait_cast(bcx: block,
             let lltydescdest = GEPi(bcx, lldest, [0, 2]);
             Store(bcx, tydesc.tydesc, lltydescdest);
         }
-        _ => {
-            bcx.tcx().sess.span_bug(val.span, ~"unexpected vstore in \
-                                                trans_trait_cast");
-        }
     }
 
     // Store the vtable into the pair or triple.
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index f970d8f26b3..320fc3ed77a 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -286,14 +286,11 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
         ty::ty_closure(ref fty) => {
             Some(normalized_closure_ty(tcx, fty.sigil))
         }
-        ty::ty_trait(_, _, ref vstore) => {
-            let sigil = match *vstore {
-                ty::vstore_uniq => ast::OwnedSigil,
-                ty::vstore_box => ast::ManagedSigil,
-                ty::vstore_slice(_) => ast::BorrowedSigil,
-                ty::vstore_fixed(*) => {
-                    tcx.sess.bug(fmt!("ty_trait with vstore_fixed"));
-                }
+        ty::ty_trait(_, _, ref store) => {
+            let sigil = match *store {
+                ty::UniqTraitStore => ast::OwnedSigil,
+                ty::BoxTraitStore | ty::BareTraitStore => ast::ManagedSigil,
+                ty::RegionTraitStore(_) => ast::BorrowedSigil,
             };
 
             // Traits have the same runtime representation as closures.
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 60af486b3cf..a4a7d958e69 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -96,14 +96,14 @@ pub impl Reflector {
         }
         let bool_ty = ty::mk_bool(tcx);
         let scratch = scratch_datum(bcx, bool_ty, false);
-        // XXX: Should not be vstore_box!
+        // XXX: Should not be BoxTraitStore!
         let bcx = callee::trans_call_inner(
             self.bcx, None, mth_ty, bool_ty,
             |bcx| meth::trans_trait_callee_from_llval(bcx,
                                                       mth_ty,
                                                       mth_idx,
                                                       v,
-                                                      ty::vstore_box,
+                                                      ty::BoxTraitStore,
                                                       ast::sty_region(
                                                         ast::m_imm)),
             ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 6855ec5d572..0c3e93885f9 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -130,7 +130,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
 
         ty::ty_bare_fn(*) => T_ptr(T_i8()),
         ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
-        ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
+        ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
 
         ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size),
         ty::ty_evec(mt, ty::vstore_fixed(size)) => {
@@ -234,7 +234,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
 
       ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
       ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
-      ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
+      ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
       ty::ty_type => T_ptr(cx.tydesc_type),
       ty::ty_tup(*) => {
           let repr = adt::represent_type(cx, t);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 108d4e94017..8d6c6291fdd 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -24,7 +24,7 @@ use middle::typeck;
 use middle;
 use util::ppaux::{note_and_explain_region, bound_region_to_str};
 use util::ppaux::{region_to_str, explain_region, vstore_to_str};
-use util::ppaux::{ty_to_str, tys_to_str};
+use util::ppaux::{trait_store_to_str, ty_to_str, tys_to_str};
 use util::common::{indenter};
 
 use core::cast;
@@ -84,6 +84,7 @@ pub struct mt {
 
 #[auto_encode]
 #[auto_decode]
+#[deriving_eq]
 pub enum vstore {
     vstore_fixed(uint),
     vstore_uniq,
@@ -91,6 +92,16 @@ pub enum vstore {
     vstore_slice(Region)
 }
 
+#[auto_encode]
+#[auto_decode]
+#[deriving_eq]
+pub enum TraitStore {
+    BareTraitStore,             // a plain trait without a sigil
+    BoxTraitStore,              // @Trait
+    UniqTraitStore,             // ~Trait
+    RegionTraitStore(Region),   // &Trait
+}
+
 pub struct field_ty {
   ident: ident,
   id: def_id,
@@ -506,7 +517,7 @@ pub enum sty {
     ty_rptr(Region, mt),
     ty_bare_fn(BareFnTy),
     ty_closure(ClosureTy),
-    ty_trait(def_id, substs, vstore),
+    ty_trait(def_id, substs, TraitStore),
     ty_struct(def_id, substs),
     ty_tup(~[t]),
 
@@ -565,6 +576,7 @@ pub enum type_err {
     terr_regions_insufficiently_polymorphic(bound_region, Region),
     terr_regions_overly_polymorphic(bound_region, Region),
     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>),
     terr_self_substs,
@@ -1048,10 +1060,13 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
 }
 
 
-pub fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore)
-         -> t {
+pub fn mk_trait(cx: ctxt,
+                did: ast::def_id,
+                +substs: substs,
+                store: TraitStore)
+             -> t {
     // take a copy of substs so that we own the vectors inside
-    mk_t(cx, ty_trait(did, substs, vstore))
+    mk_t(cx, ty_trait(did, substs, store))
 }
 
 pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, +substs: substs) -> t {
@@ -1213,8 +1228,8 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
         ty_enum(tid, ref substs) => {
             ty_enum(tid, fold_substs(substs, fldop))
         }
-        ty_trait(did, ref substs, vst) => {
-            ty_trait(did, fold_substs(substs, fldop), vst)
+        ty_trait(did, ref substs, st) => {
+            ty_trait(did, fold_substs(substs, fldop), st)
         }
         ty_tup(ts) => {
             let new_ts = vec::map(ts, |tt| fldop(*tt));
@@ -1304,8 +1319,8 @@ pub fn fold_regions_and_ty(
       ty_struct(def_id, ref substs) => {
         ty::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt))
       }
-      ty_trait(def_id, ref substs, vst) => {
-        ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
+      ty_trait(def_id, ref substs, st) => {
+        ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st)
       }
       ty_bare_fn(ref f) => {
           ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
@@ -1893,15 +1908,16 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
                 TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
             }
 
-            ty_trait(_, _, vstore_uniq) => {
+            ty_trait(_, _, UniqTraitStore) => {
                 TC_OWNED_CLOSURE
             }
 
-            ty_trait(_, _, vstore_box) => {
+            ty_trait(_, _, BoxTraitStore) |
+            ty_trait(_, _, BareTraitStore) => {
                 TC_MANAGED
             }
 
-            ty_trait(_, _, vstore_slice(r)) => {
+            ty_trait(_, _, RegionTraitStore(r)) => {
                 borrowed_contents(r, m_imm)
             }
 
@@ -2013,7 +2029,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
             }
 
             ty_type => TC_NONE,
-            ty_trait(_, _, vstore_fixed(_)) => TC_NONE,
 
             ty_err => {
                 cx.sess.bug(~"Asked to compute contents of fictitious type");
@@ -2557,6 +2572,17 @@ impl to_bytes::IterBytes for vstore {
     }
 }
 
+impl to_bytes::IterBytes for TraitStore {
+    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
+        match *self {
+          BareTraitStore => 0u8.iter_bytes(lsb0, f),
+          UniqTraitStore => 1u8.iter_bytes(lsb0, f),
+          BoxTraitStore => 2u8.iter_bytes(lsb0, f),
+          RegionTraitStore(ref r) => to_bytes::iter_bytes_2(&3u8, r, lsb0, f),
+        }
+    }
+}
+
 impl to_bytes::IterBytes for substs {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
           to_bytes::iter_bytes_3(&self.self_r,
@@ -3419,6 +3445,11 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
                  vstore_to_str(cx, (*values).expected),
                  vstore_to_str(cx, (*values).found))
         }
+        terr_trait_stores_differ(_, ref values) => {
+            fmt!("trait storage differs: expected %s but found %s",
+                 trait_store_to_str(cx, (*values).expected),
+                 trait_store_to_str(cx, (*values).found))
+        }
         terr_in_field(err, fname) => {
             fmt!("in field `%s`, %s", *cx.sess.str_of(fname),
                  type_err_to_str(cx, err))
@@ -3565,12 +3596,19 @@ pub fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
 /*
   Could this return a list of (def_id, substs) pairs?
  */
-pub fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
-    fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t {
+pub fn impl_traits(cx: ctxt, id: ast::def_id, store: TraitStore) -> ~[t] {
+    fn storeify(cx: ctxt, ty: t, store: TraitStore) -> t {
         match ty::get(ty).sty {
-            ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
-            ty::ty_trait(did, ref substs, _) => {
-                mk_trait(cx, did, (/*bad*/copy *substs), vstore)
+            ty::ty_trait(did, ref substs, trait_store) => {
+                if store == trait_store ||
+                        (store == BareTraitStore &&
+                         trait_store == BoxTraitStore) ||
+                        (store == BoxTraitStore &&
+                         trait_store == BareTraitStore) {
+                    ty
+                } else {
+                    mk_trait(cx, did, (/*bad*/copy *substs), store)
+                }
             }
             _ => cx.sess.bug(~"impl_traits: not a trait")
         }
@@ -3585,16 +3623,16 @@ pub fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
                     _)) => {
 
                do option::map_default(&opt_trait, ~[]) |trait_ref| {
-                       ~[vstoreify(cx,
-                                   node_id_to_type(cx, trait_ref.ref_id),
-                                   vstore)]
+                       ~[storeify(cx,
+                                  node_id_to_type(cx, trait_ref.ref_id),
+                                  store)]
                    }
            }
            _ => ~[]
         }
     } else {
         vec::map(csearch::get_impl_traits(cx, id),
-                 |x| vstoreify(cx, *x, vstore))
+                 |x| storeify(cx, *x, store))
     }
 }
 
@@ -4163,6 +4201,9 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
                 t
             },
 
+        ty_trait(did, ref substs, BareTraitStore) =>
+            mk_trait(cx, did, copy *substs, BoxTraitStore),
+
         _ =>
             t
     };
@@ -4318,38 +4359,6 @@ impl cmp::Eq for mt {
     pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) }
 }
 
-impl cmp::Eq for vstore {
-    pure fn eq(&self, other: &vstore) -> bool {
-        match (*self) {
-            vstore_fixed(e0a) => {
-                match (*other) {
-                    vstore_fixed(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            vstore_uniq => {
-                match (*other) {
-                    vstore_uniq => true,
-                    _ => false
-                }
-            }
-            vstore_box => {
-                match (*other) {
-                    vstore_box => true,
-                    _ => false
-                }
-            }
-            vstore_slice(e0a) => {
-                match (*other) {
-                    vstore_slice(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-        }
-    }
-    pure fn ne(&self, other: &vstore) -> bool { !(*self).eq(other) }
-}
-
 impl cmp::Eq for Region {
     pure fn eq(&self, other: &Region) -> bool {
         match (*self) {
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 6c27decc283..9dda55b3a38 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -249,20 +249,26 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
                             type_def_id, path);
                         match ty::get(result.ty).sty {
                             ty::ty_trait(trait_def_id, ref substs, _) => {
-                                match vst {
-                                    ty::vstore_box | ty::vstore_slice(*) |
-                                    ty::vstore_uniq => {}
-                                    _ => {
+                                let trait_store = match vst {
+                                    ty::vstore_box => ty::BoxTraitStore,
+                                    ty::vstore_uniq => ty::UniqTraitStore,
+                                    ty::vstore_slice(r) => {
+                                        ty::RegionTraitStore(r)
+                                    }
+                                    ty::vstore_fixed(*) => {
                                         tcx.sess.span_err(
                                             path.span,
                                             ~"@trait, ~trait or &trait \
                                               are the only supported \
                                               forms of casting-to-\
                                               trait");
+                                        ty::BoxTraitStore
                                     }
-                                }
-                                return ty::mk_trait(tcx, trait_def_id,
-                                                    /*bad*/copy *substs, vst);
+                                };
+                                return ty::mk_trait(tcx,
+                                                    trait_def_id,
+                                                    /*bad*/copy *substs,
+                                                    trait_store);
 
                             }
                             _ => {}
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index d6060c1ae31..5d2469db285 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -288,9 +288,9 @@ pub impl LookupContext/&self {
                 ty_param(p) => {
                     self.push_inherent_candidates_from_param(self_ty, p);
                 }
-                ty_trait(did, ref substs, vstore) => {
+                ty_trait(did, ref substs, store) => {
                     self.push_inherent_candidates_from_trait(
-                        self_ty, did, substs, vstore);
+                        self_ty, did, substs, store);
                     self.push_inherent_impl_candidates_for_type(did);
                 }
                 ty_self => {
@@ -490,7 +490,7 @@ pub impl LookupContext/&self {
                                            self_ty: ty::t,
                                            did: def_id,
                                            substs: &ty::substs,
-                                           vstore: ty::vstore) {
+                                           store: ty::TraitStore) {
         debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)",
                self.did_to_str(did),
                substs_to_str(self.tcx(), substs));
@@ -539,7 +539,7 @@ pub impl LookupContext/&self {
             explicit_self: method.self_ty,
             num_method_tps: method.tps.len(),
             self_mode: get_mode_from_self_type(method.self_ty),
-            origin: method_trait(did, index, vstore)
+            origin: method_trait(did, index, store)
         });
     }
 
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 1dd88e6408b..4ff8431d88a 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -263,7 +263,7 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
             // 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(_, _, vstore_slice(trait_region)) => {
+                ty::ty_trait(_, _, ty::RegionTraitStore(trait_region)) => {
                     let source_ty = rcx.fcx.expr_ty(source);
                     constrain_regions_in_type(rcx, trait_region,
                                               expr.span, source_ty);
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 7c9ca4ba85a..de301ead1f8 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -140,7 +140,9 @@ pub fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
                     is_early: bool) -> Option<ty::substs> {
     let tcx = vcx.tcx();
     // use a dummy type just to package up the substs that need fixing up
-    let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
+    let t = ty::mk_trait(tcx,
+                         id, substs,
+                         ty::RegionTraitStore(ty::re_static));
     do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
         match ty::get(*t_f).sty {
           ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f),
@@ -167,9 +169,9 @@ pub fn lookup_vtable(vcx: &VtableContext,
     let _i = indenter();
 
     let tcx = vcx.tcx();
-    let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
-        ty::ty_trait(did, ref substs, vstore) =>
-            (did, (/*bad*/copy *substs), vstore),
+    let (trait_id, trait_substs, trait_store) = match ty::get(trait_ty).sty {
+        ty::ty_trait(did, ref substs, store) =>
+            (did, (/*bad*/copy *substs), store),
         _ => tcx.sess.impossible_case(location_info.span,
                                       "lookup_vtable: \
                                        don't know how to handle a non-trait")
@@ -261,8 +263,9 @@ pub fn lookup_vtable(vcx: &VtableContext,
                         // it's the same trait as trait_ty, we need to
                         // unify it with trait_ty in order to get all
                         // the ty vars sorted out.
-                        for vec::each(ty::impl_traits(tcx, im.did,
-                                                      trait_vstore)) |of_ty| {
+                        for vec::each(ty::impl_traits(tcx,
+                                                      im.did,
+                                                      trait_store)) |of_ty| {
                             match ty::get(*of_ty).sty {
                                 ty::ty_trait(id, _, _) => {
                                     // Not the trait we're looking for
@@ -381,7 +384,7 @@ pub fn lookup_vtable(vcx: &VtableContext,
                                               /*bad*/copy substs_f.tps,
                                               trait_tps,
                                               im.did,
-                                              trait_vstore);
+                                              trait_store);
                             let subres = lookup_vtables(
                                 vcx, location_info, im_bs, &substs_f,
                                 is_early);
@@ -455,11 +458,11 @@ pub fn connect_trait_tps(vcx: &VtableContext,
                          impl_tys: ~[ty::t],
                          trait_tys: ~[ty::t],
                          impl_did: ast::def_id,
-                         vstore: ty::vstore) {
+                         store: ty::TraitStore) {
     let tcx = vcx.tcx();
 
     // XXX: This should work for multiple traits.
-    let ity = ty::impl_traits(tcx, impl_did, vstore)[0];
+    let ity = ty::impl_traits(tcx, impl_did, store)[0];
     let trait_ty = ty::subst_tps(tcx, impl_tys, None, ity);
     debug!("(connect trait tps) trait type is %?, impl did is %?",
            ty::get(trait_ty).sty, impl_did);
@@ -557,17 +560,19 @@ pub fn early_resolve_expr(ex: @ast::expr,
       ast::expr_cast(src, _) => {
           let target_ty = fcx.expr_ty(ex);
           match ty::get(target_ty).sty {
-              ty::ty_trait(_, _, vstore) => {
+              ty::ty_trait(_, _, store) => {
                   // Look up vtables for the type we're casting to,
                   // passing in the source and target type.  The source
                   // must be a pointer type suitable to the object sigil,
                   // e.g.: `@x as @Trait`, `&x as &Trait` or `~x as ~Trait`
                   let ty = structurally_resolved_type(fcx, ex.span,
                                                       fcx.expr_ty(src));
-                  match (&ty::get(ty).sty, vstore) {
-                      (&ty::ty_box(mt), ty::vstore_box) |
-                      (&ty::ty_uniq(mt), ty::vstore_uniq) |
-                      (&ty::ty_rptr(_, mt), ty::vstore_slice(*)) => {
+                  match (&ty::get(ty).sty, store) {
+                      (&ty::ty_box(mt), ty::BoxTraitStore) |
+                      // XXX: Bare trait store is deprecated.
+                      (&ty::ty_box(mt), ty::BareTraitStore) |
+                      (&ty::ty_uniq(mt), ty::UniqTraitStore) |
+                      (&ty::ty_rptr(_, mt), ty::RegionTraitStore(*)) => {
                           let location_info =
                               &location_info_for_expr(ex);
                           let vcx = VtableContext {
@@ -604,9 +609,9 @@ pub fn early_resolve_expr(ex: @ast::expr,
 
                           // Now, if this is &trait, we need to link the
                           // regions.
-                          match (&ty::get(ty).sty, vstore) {
+                          match (&ty::get(ty).sty, store) {
                               (&ty::ty_rptr(ra, _),
-                               ty::vstore_slice(rb)) => {
+                               ty::RegionTraitStore(rb)) => {
                                   infer::mk_subr(fcx.infcx(),
                                                  false,
                                                  ex.span,
@@ -617,7 +622,8 @@ pub fn early_resolve_expr(ex: @ast::expr,
                           }
                       }
 
-                      (_, ty::vstore_box(*)) => {
+                      // XXX: Remove bare below.
+                      (_, ty::BoxTraitStore) | (_, ty::BareTraitStore) => {
                           fcx.ccx.tcx.sess.span_err(
                               ex.span,
                               fmt!("can only cast an @-pointer \
@@ -625,7 +631,7 @@ pub fn early_resolve_expr(ex: @ast::expr,
                                    ty::ty_sort_str(fcx.tcx(), ty)));
                       }
 
-                      (_, ty::vstore_uniq(*)) => {
+                      (_, ty::UniqTraitStore) => {
                           fcx.ccx.tcx.sess.span_err(
                               ex.span,
                               fmt!("can only cast an ~-pointer \
@@ -633,19 +639,13 @@ pub fn early_resolve_expr(ex: @ast::expr,
                                    ty::ty_sort_str(fcx.tcx(), ty)));
                       }
 
-                      (_, ty::vstore_slice(*)) => {
+                      (_, ty::RegionTraitStore(_)) => {
                           fcx.ccx.tcx.sess.span_err(
                               ex.span,
                               fmt!("can only cast an &-pointer \
                                     to an &-object, not a %s",
                                    ty::ty_sort_str(fcx.tcx(), ty)));
                       }
-
-                      (_, ty::vstore_fixed(*)) => {
-                          fcx.tcx().sess.span_bug(
-                              ex.span,
-                              fmt!("trait with fixed vstore"));
-                      }
                   }
               }
               _ => { /* not a cast to a trait; ignore */ }
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 6c8bfdb041d..29d1f81cdd6 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -81,8 +81,10 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
 
                     match intrinsic_item.node {
                       ast::item_trait(*) => {
-                        let ty = ty::mk_trait(ccx.tcx, def_id, substs,
-                                              ty::vstore_box);
+                        let ty = ty::mk_trait(ccx.tcx,
+                                              def_id,
+                                              substs,
+                                              ty::BareTraitStore);
                         ccx.tcx.intrinsic_defs.insert
                             (intrinsic_item.ident, (def_id, ty));
                       }
@@ -893,7 +895,10 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
       }
       ast::item_trait(ref generics, _, _) => {
         let (bounds, substs) = mk_substs(ccx, generics, rp);
-        let t = ty::mk_trait(tcx, local_def(it.id), substs, ty::vstore_box);
+        let t = ty::mk_trait(tcx,
+                             local_def(it.id),
+                             substs,
+                             ty::BareTraitStore);
         let tpt = ty_param_bounds_and_ty {
             bounds: bounds,
             region_param: rp,
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 1f5e9707e2d..cfe45aaf3a8 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -102,10 +102,16 @@ pub trait Combine {
     fn purities(&self, a: purity, b: purity) -> cres<purity>;
     fn abis(&self, a: ast::Abi, b: ast::Abi) -> cres<ast::Abi>;
     fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<Onceness>;
-    fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
+    fn contraregions(&self, a: ty::Region, b: ty::Region)
+                  -> cres<ty::Region>;
     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>;
+    fn trait_stores(&self,
+                    vk: ty::terr_vstore_kind,
+                    a: ty::TraitStore,
+                    b: ty::TraitStore)
+                 -> cres<ty::TraitStore>;
 }
 
 pub struct CombineFields {
@@ -349,6 +355,36 @@ pub fn super_vstores<C:Combine>(
     }
 }
 
+pub fn super_trait_stores<C:Combine>(self: &C,
+                                     vk: ty::terr_vstore_kind,
+                                     a: ty::TraitStore,
+                                     b: ty::TraitStore)
+                                  -> cres<ty::TraitStore> {
+    debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
+
+    match (a, b) {
+      (ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
+        do self.contraregions(a_r, b_r).chain |r| {
+            Ok(ty::RegionTraitStore(r))
+        }
+      }
+
+      // XXX: This should go away soon.
+      (ty::BareTraitStore, ty::BoxTraitStore) |
+      (ty::BoxTraitStore, ty::BareTraitStore) => {
+        Ok(ty::BoxTraitStore)
+      }
+
+      _ if a == b => {
+        Ok(a)
+      }
+
+      _ => {
+        Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
+      }
+    }
+}
+
 pub fn super_closure_tys<C:Combine>(
     self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
 {
@@ -491,12 +527,12 @@ pub fn super_tys<C:Combine>(
         }
       }
 
-      (ty::ty_trait(a_id, ref a_substs, a_vstore),
-       ty::ty_trait(b_id, ref b_substs, b_vstore))
+      (ty::ty_trait(a_id, ref a_substs, a_store),
+       ty::ty_trait(b_id, ref b_substs, b_store))
       if a_id == b_id => {
         do self.substs(a_id, a_substs, b_substs).chain |substs| {
-            do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| {
-                Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, vs))
+            do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
+                Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s))
             }
         }
       }
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index bba35f02b0c..ff13f7ee576 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -145,6 +145,14 @@ impl Combine for Glb {
         super_vstores(self, vk, a, b)
     }
 
+    fn trait_stores(&self,
+                    vk: ty::terr_vstore_kind,
+                    a: ty::TraitStore,
+                    b: ty::TraitStore)
+                 -> cres<ty::TraitStore> {
+        super_trait_stores(self, vk, a, b)
+    }
+
     fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
         super_modes(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index 3a12fb31a1a..933ad44a79e 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -227,6 +227,14 @@ impl Combine for Lub {
         super_vstores(self, vk, a, b)
     }
 
+    fn trait_stores(&self,
+                    vk: ty::terr_vstore_kind,
+                    a: ty::TraitStore,
+                    b: ty::TraitStore)
+                 -> cres<ty::TraitStore> {
+        super_trait_stores(self, vk, a, b)
+    }
+
     fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
         super_modes(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs
index b4d8905a936..580aefe5b1a 100644
--- a/src/librustc/middle/typeck/infer/sub.rs
+++ b/src/librustc/middle/typeck/infer/sub.rs
@@ -239,6 +239,14 @@ impl Combine for Sub {
         super_vstores(self, vk, a, b)
     }
 
+    fn trait_stores(&self,
+                    vk: ty::terr_vstore_kind,
+                    a: ty::TraitStore,
+                    b: ty::TraitStore)
+                 -> cres<ty::TraitStore> {
+        super_trait_stores(self, vk, a, b)
+    }
+
     fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
         super_modes(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 297e33aa8e3..ed1a3d33f4c 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -90,7 +90,7 @@ pub enum method_origin {
     method_param(method_param),
 
     // method invoked on a trait instance
-    method_trait(ast::def_id, uint, ty::vstore),
+    method_trait(ast::def_id, uint, ty::TraitStore),
 
     // method invoked on "self" inside a default method
     method_self(ast::def_id, uint)
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 7add8dd2dbe..05dc967e379 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -237,6 +237,15 @@ pub fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str {
     }
 }
 
+pub fn trait_store_to_str(cx: ctxt, s: ty::TraitStore) -> ~str {
+    match s {
+      ty::BareTraitStore => ~"",
+      ty::UniqTraitStore => ~"~",
+      ty::BoxTraitStore => ~"@",
+      ty::RegionTraitStore(r) => region_to_str_adorned(cx, "&", r, "")
+    }
+}
+
 pub fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
     match vs {
       ty::vstore_fixed(_) => {
@@ -441,11 +450,11 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
         let base = ast_map::path_to_str(path, cx.sess.intr());
         parameterized(cx, base, substs.self_r, substs.tps)
       }
-      ty_trait(did, ref substs, vs) => {
+      ty_trait(did, ref substs, s) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
         let ty = parameterized(cx, base, substs.self_r, substs.tps);
-        fmt!("%s%s", vstore_to_str(cx, vs), ty)
+        fmt!("%s%s", trait_store_to_str(cx, s), ty)
       }
       ty_evec(mt, vs) => {
         vstore_ty_to_str(cx, fmt!("%s", mt_to_str(cx, mt)), vs)