]> git.lizzy.rs Git - rust.git/commitdiff
Refactor ty_vec represent &[T] as &([T])
authorNick Cameron <ncameron@mozilla.com>
Wed, 9 Apr 2014 07:15:31 +0000 (19:15 +1200)
committerNick Cameron <ncameron@mozilla.com>
Sun, 20 Apr 2014 00:41:53 +0000 (12:41 +1200)
Refactores all uses of ty_vec and associated things to remove the vstore abstraction (still used for strings, for now). Pointers to vectors are stored as ty_rptr or ty_uniq wrapped around a ty_vec. There are no user-facing changes. Existing behaviour is preserved by special-casing many instances of pointers containing vectors. Hopefully with DST most of these hacks will go away. For now it is useful to leave them hanging around rather than abstracting them into a method or something.

Closes #13554.

28 files changed:
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/check_match.rs
src/librustc/middle/lint.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs

index 5df5b718f3e76b163d44d714a605b9cc4f5500ee..cfa2d647ec9014f924a87b162d4abed43a5ce4bd 100644 (file)
@@ -137,8 +137,7 @@ pub fn parse_substs_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx:
     parse_substs(&mut st, conv)
 }
 
-fn parse_vstore<M>(st: &mut PState, conv: conv_did,
-                   parse_mut: |&mut PState| -> M) -> ty::Vstore<M> {
+fn parse_vstore(st: &mut PState, conv: conv_did) -> ty::Vstore {
     assert_eq!(next(st), '/');
 
     let c = peek(st);
@@ -150,11 +149,24 @@ fn parse_vstore<M>(st: &mut PState, conv: conv_did,
 
     match next(st) {
         '~' => ty::VstoreUniq,
-        '&' => ty::VstoreSlice(parse_region(st, conv), parse_mut(st)),
+        '&' => ty::VstoreSlice(parse_region(st, conv)),
         c => st.tcx.sess.bug(format!("parse_vstore(): bad input '{}'", c))
     }
 }
 
+fn parse_size(st: &mut PState) -> Option<uint> {
+    assert_eq!(next(st), '/');
+
+    if peek(st) == '|' {
+        assert_eq!(next(st), '|');
+        None
+    } else {
+        let n = parse_uint(st);
+        assert_eq!(next(st), '|');
+        Some(n)
+    }
+}
+
 fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
     match next(st) {
         '~' => ty::UniqTraitStore,
@@ -342,12 +354,12 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         return ty::mk_rptr(st.tcx, r, 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);
+        let mt = parse_mt(st, |x,y| conv(x,y));
+        let sz = parse_size(st);
+        return ty::mk_vec(st.tcx, mt, sz);
       }
       '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' => {
@@ -396,7 +408,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
           assert_eq!(next(st), ']');
           return ty::mk_struct(st.tcx, did, substs);
       }
-      c => { error!("unexpected char in type string: {}", c); fail!();}
+      c => { fail!("unexpected char in type string: {}", c);}
     }
 }
 
index 53fe1c19d8ff948c60bc359ad29a5aff20f029a3..1d7d43f895ede84139ce3ffcca1ae59380f31970 100644 (file)
@@ -204,17 +204,17 @@ fn enc_bound_region(w: &mut MemWriter, cx: &ctxt, br: ty::BoundRegion) {
     }
 }
 
-pub fn enc_vstore<M>(w: &mut MemWriter, cx: &ctxt,
-                     v: ty::Vstore<M>,
-                     enc_mut: |&mut MemWriter, M|) {
+pub fn enc_vstore(w: &mut MemWriter, cx: &ctxt,
+                  v: ty::Vstore,
+                  enc_mut: |&mut MemWriter|) {
     mywrite!(w, "/");
     match v {
         ty::VstoreFixed(u) => mywrite!(w, "{}|", u),
         ty::VstoreUniq => mywrite!(w, "~"),
-        ty::VstoreSlice(r, m) => {
+        ty::VstoreSlice(r) => {
             mywrite!(w, "&");
             enc_region(w, cx, r);
-            enc_mut(w, m);
+            enc_mut(w);
         }
     }
 }
@@ -292,14 +292,18 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
             enc_region(w, cx, r);
             enc_mt(w, cx, mt);
         }
-        ty::ty_vec(ty, v) => {
+        ty::ty_vec(mt, sz) => {
             mywrite!(w, "V");
-            enc_ty(w, cx, ty);
-            enc_vstore(w, cx, v, enc_mutability);
+            enc_mt(w, cx, mt);
+            mywrite!(w, "/");
+            match sz {
+                Some(n) => mywrite!(w, "{}|", n),
+                None => mywrite!(w, "|"),
+            }
         }
         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");
index e08ffa89cfba17f6123d812c68f8737b4e0b96c4..db1badb7d59866587ed9b660c397c7f10f4c1ad7 100644 (file)
@@ -191,7 +191,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, pats: Vec<@Pat> ) {
                         }
                     }
                 }
-                ty::ty_vec(..) => {
+                ty::ty_vec(..) | ty::ty_rptr(..) => {
                     match *ctor {
                         vec(n) => Some(format!("vectors of length {}", n)),
                         _ => None
@@ -258,50 +258,57 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
           None => {
             match ty::get(left_ty).sty {
               ty::ty_bool => {
-                match is_useful_specialized(cx, m, v,
-                                            val(const_bool(true)),
-                                            0u, left_ty){
-                  not_useful => {
-                    is_useful_specialized(cx, m, v,
-                                          val(const_bool(false)),
-                                          0u, left_ty)
+                  match is_useful_specialized(cx, m, v,
+                                              val(const_bool(true)),
+                                              0u, left_ty){
+                      not_useful => {
+                          is_useful_specialized(cx, m, v,
+                                                val(const_bool(false)),
+                                                0u, left_ty)
+                      }
+                      ref u => (*u).clone(),
                   }
-                  ref u => (*u).clone(),
-                }
               }
               ty::ty_enum(eid, _) => {
-                for va in (*ty::enum_variants(cx.tcx, eid)).iter() {
-                    match is_useful_specialized(cx, m, v, variant(va.id),
-                                                va.args.len(), left_ty) {
-                      not_useful => (),
-                      ref u => return (*u).clone(),
-                    }
-                }
-                not_useful
+                  for va in (*ty::enum_variants(cx.tcx, eid)).iter() {
+                      match is_useful_specialized(cx, m, v, variant(va.id),
+                                                  va.args.len(), left_ty) {
+                        not_useful => (),
+                        ref u => return (*u).clone(),
+                      }
+                  }
+                  not_useful
               }
-              ty::ty_vec(_, ty::VstoreFixed(n)) => {
-                is_useful_specialized(cx, m, v, vec(n), n, left_ty)
+              ty::ty_vec(_, Some(n)) => {
+                  is_useful_specialized(cx, m, v, vec(n), n, left_ty)
               }
-              ty::ty_vec(..) => {
-                let max_len = m.iter().rev().fold(0, |max_len, r| {
-                  match r.get(0).node {
-                    PatVec(ref before, _, ref after) => {
-                      cmp::max(before.len() + after.len(), max_len)
-                    }
-                    _ => max_len
+              ty::ty_vec(..) => fail!("impossible case"),
+              ty::ty_rptr(_, ty::mt{ty: ty, ..}) | ty::ty_uniq(ty) => match ty::get(ty).sty {
+                  ty::ty_vec(_, None) => {
+                      let max_len = m.iter().rev().fold(0, |max_len, r| {
+                          match r.get(0).node {
+                              PatVec(ref before, _, ref after) => {
+                                  cmp::max(before.len() + after.len(), max_len)
+                              }
+                              _ => max_len
+                          }
+                      });
+                      for n in iter::range(0u, max_len + 1) {
+                          match is_useful_specialized(cx, m, v, vec(n), n, left_ty) {
+                              not_useful => (),
+                              ref u => return (*u).clone(),
+                          }
+                      }
+                      not_useful
                   }
-                });
-                for n in iter::range(0u, max_len + 1) {
-                  match is_useful_specialized(cx, m, v, vec(n), n, left_ty) {
-                    not_useful => (),
-                    ref u => return (*u).clone(),
+                  _ => {
+                      let arity = ctor_arity(cx, &single, left_ty);
+                      is_useful_specialized(cx, m, v, single, arity, left_ty)
                   }
-                }
-                not_useful
-              }
+              },
               _ => {
-                let arity = ctor_arity(cx, &single, left_ty);
-                is_useful_specialized(cx, m, v, single, arity, left_ty)
+                  let arity = ctor_arity(cx, &single, left_ty);
+                  is_useful_specialized(cx, m, v, single, arity, left_ty)
               }
             }
           }
@@ -394,17 +401,16 @@ fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool {
 }
 
 fn missing_ctor(cx: &MatchCheckCtxt,
-                    m: &matrix,
-                    left_ty: ty::t)
-                 -> Option<ctor> {
-    match ty::get(left_ty).sty {
-      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(..) | ty::ty_tup(_) |
-      ty::ty_struct(..) => {
-        for r in m.iter() {
-            if !is_wild(cx, *r.get(0)) { return None; }
-        }
-        return Some(single);
-      }
+                m: &matrix,
+                left_ty: ty::t)
+                -> Option<ctor> {
+    return match ty::get(left_ty).sty {
+      ty::ty_box(_) | ty::ty_tup(_) |
+      ty::ty_struct(..) => check_matrix_for_wild(cx, m),
+      ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty: ty, ..}) => match ty::get(ty).sty {
+          ty::ty_vec(_, None) => ctor_for_slice(m),
+          _ => check_matrix_for_wild(cx, m),
+      },
       ty::ty_enum(eid, _) => {
         let mut found = Vec::new();
         for r in m.iter() {
@@ -441,7 +447,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::VstoreFixed(n)) => {
+      ty::ty_vec(_, Some(n)) => {
         let mut missing = true;
         let mut wrong = false;
         for r in m.iter() {
@@ -464,8 +470,19 @@ fn missing_ctor(cx: &MatchCheckCtxt,
           _         => None
         }
       }
-      ty::ty_vec(..) => {
+      ty::ty_vec(..) => fail!("impossible case"),
+      _ => Some(single)
+    };
+
+    fn check_matrix_for_wild(cx: &MatchCheckCtxt, m: &matrix) -> Option<ctor> {
+        for r in m.iter() {
+            if !is_wild(cx, *r.get(0)) { return None; }
+        }
+        return Some(single);
+    }
 
+    // For slice and ~[T].
+    fn ctor_for_slice(m: &matrix) -> Option<ctor> {
         // Find the lengths and slices of all vector patterns.
         let mut vec_pat_lens = m.iter().filter_map(|r| {
             match r.get(0).node {
@@ -511,31 +528,37 @@ fn missing_ctor(cx: &MatchCheckCtxt,
           Some(k) => Some(vec(k)),
           None => None
         }
-      }
-      _ => Some(single)
     }
 }
 
 fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
-    match ty::get(ty).sty {
-      ty::ty_tup(ref fs) => fs.len(),
-      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(..) => 1u,
-      ty::ty_enum(eid, _) => {
-          let id = match *ctor { variant(id) => id,
-          _ => fail!("impossible case") };
-        match ty::enum_variants(cx.tcx, eid).iter().find(|v| v.id == id ) {
-            Some(v) => v.args.len(),
-            None => fail!("impossible case")
-        }
-      }
-      ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
-      ty::ty_vec(..) => {
+    fn vec_ctor_arity(ctor: &ctor) -> uint {
         match *ctor {
-          vec(n) => n,
-          _ => 0u
+            vec(n) => n,
+            _ => 0u
         }
-      }
-      _ => 0u
+    }
+
+    match ty::get(ty).sty {
+        ty::ty_tup(ref fs) => fs.len(),
+        ty::ty_box(_) => 1u,
+        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty: ty, ..}) => match ty::get(ty).sty {
+            ty::ty_vec(_, None) => vec_ctor_arity(ctor),
+            _ => 1u,
+        },
+        ty::ty_enum(eid, _) => {
+            let id = match *ctor {
+                variant(id) => id,
+                _ => fail!("impossible case")
+            };
+            match ty::enum_variants(cx.tcx, eid).iter().find(|v| v.id == id ) {
+                Some(v) => v.args.len(),
+                None => fail!("impossible case")
+            }
+        }
+        ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
+        ty::ty_vec(_, Some(_)) => vec_ctor_arity(ctor),
+        _ => 0u
     }
 }
 
index e376f85ff6db030934292ae3fa46568749e2218e..6ce815d9bc46c731681f3b2e7926fe9105bb8065 100644 (file)
@@ -918,7 +918,6 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
                     n_box += 1;
                 }
                 ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
-                ty::ty_vec(_, ty::VstoreUniq) |
                 ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
                 ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
                     n_uniq += 1;
@@ -1156,10 +1155,13 @@ 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::VstoreUniq) => {
-            cx.span_lint(DeprecatedOwnedVector, e.span,
-                         "use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
-        }
+        ty::ty_uniq(t) => match ty::get(t).sty {
+            ty::ty_vec(_, None) => {
+                cx.span_lint(DeprecatedOwnedVector, e.span,
+                             "use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
+            }
+            _ => {}
+        },
         _ => {}
     }
 }
index fc9d5a60eec63c7f1a37f5c11a6fd2fb9254ae29..84e9151c11ccee1cd2f881f68db389a09ea9d151 100644 (file)
@@ -170,7 +170,6 @@ 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::VstoreUniq) |
         ty::ty_str(ty::VstoreUniq) |
         ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
             Some(deref_ptr(OwnedPtr))
@@ -180,13 +179,12 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
-        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::VstoreSlice(r, ())) |
+        ty::ty_str(ty::VstoreSlice(r)) |
         ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(r, _), ..}) => {
             Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
         }
@@ -204,7 +202,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             Some(deref_interior(InteriorField(PositionalField(0))))
         }
 
-        ty::ty_vec(_, ty::VstoreFixed(_)) |
+        ty::ty_vec(_, Some(_)) |
         ty::ty_str(ty::VstoreFixed(_)) => {
             Some(deref_interior(InteriorElement(element_kind(t))))
         }
@@ -483,8 +481,8 @@ pub fn cat_def(&mut self,
                    expr_ty: ty::t,
                    def: ast::Def)
                    -> McResult<cmt> {
-        debug!("cat_def: id={} expr={}",
-               id, expr_ty.repr(self.tcx()));
+        debug!("cat_def: id={} expr={} def={:?}",
+               id, expr_ty.repr(self.tcx()), def);
 
         match def {
           ast::DefStruct(..) | ast::DefVariant(..) => {
@@ -785,7 +783,7 @@ pub fn cat_index<N:ast_node>(&mut self,
         //!   the implicit index deref, if any (see above)
 
         let element_ty = match ty::index(base_cmt.ty) {
-          Some(ty) => ty,
+          Some(ref mt) => mt.ty,
           None => {
             self.tcx().sess.span_bug(
                 elt.span(),
@@ -868,13 +866,10 @@ fn vec_slice_info(tcx: &ty::ctxt,
              */
 
             match ty::get(slice_ty).sty {
-                ty::ty_vec(_, ty::VstoreSlice(slice_r, mutbl)) => {
-                    (mutbl, slice_r)
-                }
-
-                ty::ty_rptr(_, ref mt) => {
-                    vec_slice_info(tcx, pat, mt.ty)
-                }
+                ty::ty_rptr(r, ref mt) => match ty::get(mt.ty).sty {
+                    ty::ty_vec(slice_mt, None) => (slice_mt.mutbl, r),
+                    _ => vec_slice_info(tcx, pat, mt.ty),
+                },
 
                 _ => {
                     tcx.sess.span_bug(
@@ -1307,6 +1302,11 @@ fn repr(&self, _tcx: &ty::ctxt) -> ~str {
 
 fn element_kind(t: ty::t) -> ElementKind {
     match ty::get(t).sty {
+        ty::ty_rptr(_, ty::mt{ty:ty, ..}) |
+        ty::ty_uniq(ty) => match ty::get(ty).sty {
+            ty::ty_vec(_, None) => VecElement,
+            _ => OtherElement
+        },
         ty::ty_vec(..) => VecElement,
         ty::ty_str(..) => StrElement,
         _ => OtherElement
index 393e35141b4ec4dff2151ad2ca550929761500e4..72818576cbb7147c00ba359a41ae6aca11d48759 100644 (file)
@@ -438,7 +438,8 @@ fn clone(&self) -> ArmData<'a, 'b> { *self }
 struct Match<'a,'b> {
     pats: Vec<@ast::Pat> ,
     data: ArmData<'a,'b>,
-    bound_ptrs: Vec<(Ident, ValueRef)> }
+    bound_ptrs: Vec<(Ident, ValueRef)>
+}
 
 impl<'a,'b> Repr for Match<'a,'b> {
     fn repr(&self, tcx: &ty::ctxt) -> ~str {
@@ -1109,8 +1110,9 @@ 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(), vt.unit_ty,
-                                  ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
+        let slice_ty = ty::mk_slice(bcx.tcx(),
+                                    ty::ReStatic,
+                                    ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
         let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
         Store(bcx, slice_begin,
               GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
index 735b60622ed62572f3e4c4eb18556469c535dafa..92a6bb73c8e3a3075eae64f7a71f67f256bb2e0b 100644 (file)
@@ -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::VstoreUniq) | ty::ty_str(ty::VstoreUniq) => {
+        ty::ty_str(ty::VstoreUniq) => {
             unsafe {
                 llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
             }
@@ -260,7 +260,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::VstoreUniq) | ty::ty_str(ty::VstoreUniq) |
+            ty::ty_str(ty::VstoreUniq) |
             ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
                 unsafe {
                     llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
@@ -664,8 +664,12 @@ fn iter_variant<'r,
               }
           })
       }
-      ty::ty_str(ty::VstoreFixed(n)) |
-      ty::ty_vec(_, ty::VstoreFixed(n)) => {
+      ty::ty_str(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_vec(_, Some(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);
index 4aaa9760e8941538242bfe16ce5fa77fd8cfac69..8bc217343f7fe97b037d4ba7ef80667ee6c30dd9 100644 (file)
@@ -653,7 +653,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::VstoreUniq) => {
+            ty::ty_uniq(..) => {
                 attrs.push((0, NoAliasAttribute));
             }
             _ => {}
index b8f6d445c36377fe76d3f35d2cb209380336a4c8..72e716d0c3cae7ac4b5e670741732787c34143b3 100644 (file)
@@ -711,8 +711,12 @@ pub enum MonoDataClass {
 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::VstoreUniq) | ty::ty_vec(_, ty::VstoreUniq) |
+        ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
+            ty::ty_vec(_, None) => MonoBits,
+            _ => MonoNonNull,
+        },
+        ty::ty_uniq(..) | ty::ty_box(..) |
+        ty::ty_str(ty::VstoreUniq) |
         ty::ty_bare_fn(..) => MonoNonNull,
         // Is that everything?  Would closures or slices qualify?
         _ => MonoBits
index 03b442bae218f723a5a3f2e73f746582af41eb4a..8848feb888904668c0351c26f923fe6900f80997 100644 (file)
@@ -139,8 +139,11 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
         Some(ref mt) => {
             assert!(mt.mutbl != ast::MutMutable);
             let dv = match ty::get(t).sty {
-                ty::ty_ptr(..) | ty::ty_rptr(..) => {
-                     const_deref_ptr(cx, v)
+                ty::ty_ptr(mt) | ty::ty_rptr(_, mt) => {
+                    match ty::get(mt.ty).sty {
+                        ty::ty_vec(_, None) => cx.sess().bug("unexpected slice"),
+                        _ => const_deref_ptr(cx, v),
+                    }
                 }
                 ty::ty_enum(..) | ty::ty_struct(..) => {
                     const_deref_newtype(cx, v, t)
@@ -244,7 +247,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::VstoreFixed(len)) => {
+                                        ty::ty_vec(_, Some(len)) => {
                                             llconst = C_struct(cx, [
                                                 llptr,
                                                 C_uint(cx, len)
@@ -432,14 +435,21 @@ 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(_, 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]))
                   },
+                  ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)),
+                  ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
+                      ty::ty_vec(_, None) => {
+                          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")
+                                          "index-expr base must be a vector or string type")
               };
 
               let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
index e44370afa2d71e59d9923499267717988160ec59..1a57acf84d22198a82c4e11b1e591737d838cd27 100644 (file)
@@ -2202,27 +2202,27 @@ fn create_pointer_to_box_metadata(cx: &CrateContext,
         ty::ty_box(typ) => {
             create_pointer_to_box_metadata(cx, t, typ)
         },
-        ty::ty_vec(ty, ref vstore) => {
-            match *vstore {
-                ty::VstoreFixed(len) => {
-                    fixed_vec_metadata(cx, ty, len, usage_site_span)
-                }
-                ty::VstoreUniq => {
-                    let vec_metadata = vec_metadata(cx, ty, usage_site_span);
+        ty::ty_vec(ref mt, Some(len)) => fixed_vec_metadata(cx, mt.ty, len, usage_site_span),
+        ty::ty_uniq(typ) => {
+            match ty::get(typ).sty {
+                ty::ty_vec(ref mt, None) => {
+                    let vec_metadata = vec_metadata(cx, mt.ty, usage_site_span);
                     pointer_type_metadata(cx, t, vec_metadata)
                 }
-                ty::VstoreSlice(..) => {
-                    vec_slice_metadata(cx, t, ty, usage_site_span)
+                _ => {
+                    let pointee = type_metadata(cx, typ, usage_site_span);
+                    pointer_type_metadata(cx, t, pointee)
                 }
             }
-        },
-        ty::ty_uniq(typ) => {
-            let pointee = type_metadata(cx, typ, usage_site_span);
-            pointer_type_metadata(cx, t, pointee)
         }
         ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
-            let pointee = type_metadata(cx, mt.ty, usage_site_span);
-            pointer_type_metadata(cx, t, pointee)
+            match ty::get(mt.ty).sty {
+                ty::ty_vec(ref mt, None) => vec_slice_metadata(cx, t, mt.ty, usage_site_span),
+                _ => {
+                    let pointee = type_metadata(cx, mt.ty, usage_site_span);
+                    pointer_type_metadata(cx, t, pointee)
+                }
+            }
         },
         ty::ty_bare_fn(ref barefnty) => {
             subroutine_type_metadata(cx, &barefnty.sig, usage_site_span)
index 50eda155b52f1736c949d2ab94b09a5ea26b2f3a..4e850b8990a1a1cdb440715da9d1270691cecd6a 100644 (file)
@@ -240,8 +240,8 @@ fn auto_slice<'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, unit_ty,
-                                  ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
+        let slice_ty = ty::mk_slice(tcx, ty::ReStatic,
+                                    ty::mt { ty: unit_ty, mutbl: ast::MutImmutable });
 
         let scratch = rvalue_scratch_datum(bcx, slice_ty, "__adjust");
         Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
@@ -1505,16 +1505,19 @@ pub enum cast_kind {
 
 pub fn cast_type_kind(t: ty::t) -> cast_kind {
     match ty::get(t).sty {
-        ty::ty_char       => cast_integral,
+        ty::ty_char        => cast_integral,
         ty::ty_float(..)   => cast_float,
         ty::ty_ptr(..)     => cast_pointer,
-        ty::ty_rptr(..)    => cast_pointer,
+        ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty{
+            ty::ty_vec(_, None) => cast_other,
+            _ => cast_pointer,
+        },
         ty::ty_bare_fn(..) => cast_pointer,
         ty::ty_int(..)     => cast_integral,
         ty::ty_uint(..)    => cast_integral,
-        ty::ty_bool       => cast_integral,
+        ty::ty_bool        => cast_integral,
         ty::ty_enum(..)    => cast_enum,
-        _                 => cast_other
+        _                  => cast_other
     }
 }
 
@@ -1717,7 +1720,10 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
 
     let r = match ty::get(datum.ty).sty {
         ty::ty_uniq(content_ty) => {
-            deref_owned_pointer(bcx, expr, datum, content_ty)
+            match ty::get(content_ty).sty {
+                ty::ty_vec(_, None) => bcx.tcx().sess.span_bug(expr.span, "unexpected ~[T]"),
+                _ => deref_owned_pointer(bcx, expr, datum, content_ty),
+            }
         }
 
         ty::ty_box(content_ty) => {
@@ -1731,16 +1737,21 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
 
         ty::ty_ptr(ty::mt { ty: content_ty, .. }) |
         ty::ty_rptr(_, ty::mt { ty: content_ty, .. }) => {
-            assert!(!ty::type_needs_drop(bcx.tcx(), datum.ty));
+            match ty::get(content_ty).sty {
+                ty::ty_vec(_, None) => bcx.tcx().sess.span_bug(expr.span, "unexpected &[T]"),
+                _ => {
+                    assert!(!ty::type_needs_drop(bcx.tcx(), datum.ty));
 
-            let ptr = datum.to_llscalarish(bcx);
+                    let ptr = datum.to_llscalarish(bcx);
 
-            // Always generate an lvalue datum, even if datum.mode is
-            // an rvalue.  This is because datum.mode is only an
-            // rvalue for non-owning pointers like &T or *T, in which
-            // case cleanup *is* scheduled elsewhere, by the true
-            // owner (or, in the case of *T, by the user).
-            DatumBlock(bcx, Datum(ptr, content_ty, LvalueExpr))
+                    // Always generate an lvalue datum, even if datum.mode is
+                    // an rvalue.  This is because datum.mode is only an
+                    // rvalue for non-owning pointers like &T or *T, in which
+                    // case cleanup *is* scheduled elsewhere, by the true
+                    // owner (or, in the case of *T, by the user).
+                    DatumBlock(bcx, Datum(ptr, content_ty, LvalueExpr))
+                }
+            }
         }
 
         _ => {
index 966e05ff1eaf04a84aa34b4cd49a3b4f76d5d383..98e09b2fd31fdfb9aaae81ace0508dc1f9af5bfa 100644 (file)
@@ -83,19 +83,21 @@ fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
             ty::mk_box(tcx, ty::mk_i8()),
 
         ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ) => {
-            let llty = sizing_type_of(ccx, typ);
-            // Unique boxes do not allocate for zero-size types. The standard library may assume
-            // that `free` is never called on the pointer returned for `~ZeroSizeType`.
-            if llsize_of_alloc(ccx, llty) == 0 {
-                ty::mk_i8()
-            } else {
-                ty::mk_uniq(tcx, ty::mk_i8())
-            }
-        }
-
-        ty::ty_vec(ty, ty::VstoreUniq) if !ty::type_needs_drop(tcx, ty) =>
-            ty::mk_uniq(tcx, ty::mk_i8()),
-
+            match ty::get(typ).sty {
+                ty::ty_vec(_, None) => t,
+                _ => {
+                    let llty = sizing_type_of(ccx, typ);
+                    // Unique boxes do not allocate for zero-size types. The standard
+                    // library may assume that `free` is never called on the pointer
+                    // returned for `~ZeroSizeType`.
+                    if llsize_of_alloc(ccx, llty) == 0 {
+                        ty::mk_i8()
+                    } else {
+                        ty::mk_uniq(tcx, ty::mk_i8())
+                    }
+                        }
+                    }
+                }
         _ => t
     }
 }
@@ -284,12 +286,22 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
         ty::ty_uniq(content_ty) => {
             let llbox = Load(bcx, v0);
             let not_null = IsNotNull(bcx, llbox);
-            with_cond(bcx, not_null, |bcx| {
-                let bcx = drop_ty(bcx, llbox, content_ty);
-                trans_exchange_free(bcx, llbox)
-            })
+            match ty::get(content_ty).sty {
+                ty::ty_vec(mt, None) => {
+                    with_cond(bcx, not_null, |bcx| {
+                        let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, mt.ty);
+                        trans_exchange_free(bcx, llbox)
+                    })
+                }
+                _ => {
+                    with_cond(bcx, not_null, |bcx| {
+                        let bcx = drop_ty(bcx, llbox, content_ty);
+                        trans_exchange_free(bcx, llbox)
+                    })
+                }
+            }
         }
-        ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) => {
+        ty::ty_str(ty::VstoreUniq) => {
             let llbox = Load(bcx, v0);
             let not_null = IsNotNull(bcx, llbox);
             with_cond(bcx, not_null, |bcx| {
index de1ee72c9df1bec6728e0213feb356926b9ccc0f..7dc4641e97fa71d40c5e7d1b866d747557416da5 100644 (file)
@@ -54,7 +54,7 @@ pub fn c_slice(&mut self, s: InternedString) -> ValueRef {
         // 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::VstoreSlice(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,10 +121,10 @@ pub fn bracketed(&mut self,
         self.visit("leave_" + bracket_name, extra);
     }
 
-    pub fn vstore_name_and_extra<M>(&mut self,
-                                    t: ty::t,
-                                    vstore: ty::Vstore<M>)
-                                    -> (~str, Vec<ValueRef> ) {
+    pub fn vstore_name_and_extra(&mut self,
+                                 t: ty::t,
+                                 vstore: ty::Vstore)
+                                 -> (~str, Vec<ValueRef> ) {
         match vstore {
             ty::VstoreFixed(n) => {
                 let extra = (vec!(self.c_uint(n))).append(self.c_size_and_align(t).as_slice());
@@ -168,17 +168,12 @@ pub fn visit_ty(&mut self, t: ty::t) {
               let (name, extra) = self.vstore_name_and_extra(t, vst);
               self.visit("estr_".to_owned() + name, extra.as_slice())
           }
-          ty::ty_vec(ty, vst) => {
-              let (name, extra) = self.vstore_name_and_extra(t, vst);
-              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_".to_owned() + name, extra.as_slice())
+          ty::ty_vec(ref mt, Some(sz)) => {
+              let extra = (vec!(self.c_uint(sz))).append(self.c_size_and_align(t).as_slice());
+              let extra = extra.append(self.c_mt(mt).as_slice());
+              self.visit("evec_fixed".to_owned(), extra.as_slice())
           }
+          ty::ty_vec(..) => fail!("unexpected unsized vec"),
           // Should remove mt from box and uniq.
           ty::ty_box(typ) => {
               let extra = self.c_mt(&ty::mt {
@@ -188,19 +183,37 @@ pub fn visit_ty(&mut self, t: ty::t) {
               self.visit("box", extra.as_slice())
           }
           ty::ty_uniq(typ) => {
-              let extra = self.c_mt(&ty::mt {
-                  ty: typ,
-                  mutbl: ast::MutImmutable,
-              });
-              self.visit("uniq", extra.as_slice())
+              match ty::get(typ).sty {
+                  ty::ty_vec(ref mt, None) => {
+                      let (name, extra) = (~"uniq", Vec::new());
+                      let extra = extra.append(self.c_mt(mt).as_slice());
+                      self.visit(~"evec_" + name, extra.as_slice())
+                  }
+                  _ => {
+                      let extra = self.c_mt(&ty::mt {
+                          ty: typ,
+                          mutbl: ast::MutImmutable,
+                      });
+                      self.visit("uniq", extra.as_slice())
+                  }
+              }
           }
           ty::ty_ptr(ref mt) => {
               let extra = self.c_mt(mt);
               self.visit("ptr", extra.as_slice())
           }
           ty::ty_rptr(_, ref mt) => {
-              let extra = self.c_mt(mt);
-              self.visit("rptr", extra.as_slice())
+              match ty::get(mt.ty).sty {
+                  ty::ty_vec(ref mt, None) => {
+                      let (name, extra) = (~"slice", Vec::new());
+                      let extra = extra.append(self.c_mt(mt).as_slice());
+                      self.visit(~"evec_" + name, extra.as_slice())
+                  }
+                  _ => {
+                      let extra = self.c_mt(mt);
+                      self.visit("rptr", extra.as_slice())
+                  }
+              }
           }
 
           ty::ty_tup(ref tys) => {
index a590c5b38f4c2452f01255f95d74c02b1d57d756..4bcb609df616c9a76252c6b195cd5503520bc69a 100644 (file)
@@ -162,8 +162,10 @@ 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(), vt.unit_ty,
-                                  ty::VstoreFixed(count));
+        let fixed_ty = ty::mk_vec(bcx.tcx(),
+                                  ty::mt {ty: vt.unit_ty,
+                                          mutbl: ast::MutMutable},
+                                  Some(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);
@@ -461,6 +463,35 @@ pub fn get_fixed_base_and_byte_len(bcx: &Block,
     (base, len)
 }
 
+pub fn get_base_and_byte_len_for_vec(bcx: &Block,
+                                     llval: ValueRef,
+                                     vec_ty: ty::t)
+                                     -> (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()`.
+     */
+
+    let ccx = bcx.ccx();
+    let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
+
+    let size = match ty::get(vec_ty).sty {
+        ty::ty_vec(_, size) => size,
+        _ => ccx.sess().bug("non-vector in get_base_and_byte_len_for_vec"),
+    };
+
+    match size {
+        Some(n) => {
+            let base = GEPi(bcx, llval, [0u, 0u]);
+            let len = Mul(bcx, C_uint(ccx, n), vt.llunit_size);
+            (base, len)
+        }
+        None => ccx.sess().bug("unsized vector in get_base_and_byte_len_for_vec")
+    }
+}
+
 pub fn get_base_and_len(bcx: &Block,
                         llval: ValueRef,
                         vec_ty: ty::t)
@@ -477,16 +508,17 @@ 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_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
+        ty::ty_str(vst) => vst,
+        ty::ty_vec(_, Some(n)) => ty::VstoreFixed(n),
+        ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty {
+            ty::ty_vec(_, None) => ty::VstoreSlice(r),
+            _ => ccx.sess().bug("unexpected type (ty_rptr) in get_base_and_len"),
+        },
+        ty::ty_uniq(t) => match ty::get(t).sty {
+            ty::ty_vec(_, None) => ty::VstoreUniq,
+            _ => ccx.sess().bug("unexpected type (ty_uniq) in get_base_and_len"),
+        },
+        _ => ccx.sess().bug("unexpected type in get_base_and_len"),
     };
 
     match vstore {
index 071eb083d4fdc2873d7d5050717a82d919e5289b..48c25fb985d83c8201328575c9de06798e309765 100644 (file)
@@ -117,14 +117,17 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_float(t) => Type::float_from_ty(cx, t),
 
         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_ptr(..) => Type::i8p(cx),
+        ty::ty_rptr(_, mt) => {
+            match ty::get(mt.ty).sty {
+                ty::ty_vec(_, None) => Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false),
+                _ => Type::i8p(cx),
+            }
+        }
 
-        ty::ty_str(ty::VstoreSlice(..)) |
-        ty::ty_vec(_, ty::VstoreSlice(..)) => {
+        ty::ty_str(ty::VstoreSlice(..)) => {
             Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
         }
 
@@ -133,8 +136,8 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_trait(..) => Type::opaque_trait(cx),
 
         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_vec(mt, Some(size)) => {
+            Type::array(&sizing_type_of(cx, mt.ty), size as u64)
         }
 
         ty::ty_tup(..) | ty::ty_enum(..) => {
@@ -153,7 +156,8 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
             }
         }
 
-        ty::ty_self(_) | ty::ty_infer(..) | ty::ty_param(..) | ty::ty_err(..) => {
+        ty::ty_self(_) | ty::ty_infer(..) | ty::ty_param(..) |
+        ty::ty_err(..) | ty::ty_vec(_, None) => {
             cx.sess().bug(format!("fictitious type {:?} in sizing_type_of()",
                                   ty::get(t).sty))
         }
@@ -215,18 +219,21 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           Type::at_box(cx, type_of(cx, typ)).ptr_to()
       }
       ty::ty_uniq(typ) => {
-          type_of(cx, typ).ptr_to()
-      }
-      ty::ty_vec(ty, ty::VstoreUniq) => {
-          Type::vec(cx, &type_of(cx, ty)).ptr_to()
+          match ty::get(typ).sty {
+              ty::ty_vec(mt, None) => Type::vec(cx, &type_of(cx, mt.ty)).ptr_to(),
+              _ => type_of(cx, typ).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(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_rptr(_, ref mt) => {
+          match ty::get(mt.ty).sty {
+              ty::ty_vec(mt, None) => {
+                  let p_ty = type_of(cx, mt.ty).ptr_to();
+                  let u_ty = Type::uint_from_ty(cx, ast::TyU);
+                  Type::struct_(cx, [p_ty, u_ty], false)
+              }
+              _ => type_of(cx, mt.ty).ptr_to(),
+          }
       }
 
       ty::ty_str(ty::VstoreSlice(..)) => {
@@ -238,8 +245,8 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           Type::array(&Type::i8(cx), (n + 1u) as u64)
       }
 
-      ty::ty_vec(ty, ty::VstoreFixed(n)) => {
-          Type::array(&type_of(cx, ty), n as u64)
+      ty::ty_vec(ref mt, Some(n)) => {
+          Type::array(&type_of(cx, mt.ty), n as u64)
       }
 
       ty::ty_bare_fn(_) => {
@@ -271,7 +278,9 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
               adt::incomplete_type_of(cx, repr, name)
           }
       }
-      ty::ty_self(..) => cx.sess().unimpl("type_of: ty_self"),
+
+      ty::ty_vec(_, None) => cx.sess().bug("type_of with unszied ty_vec"),
+      ty::ty_self(..) => cx.sess().unimpl("type_of with ty_self"),
       ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
       ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
       ty::ty_err(..) => cx.sess().bug("type_of with ty_err")
index d6f1866f5dc0386e77c78d1c3303e4ac4984e076..04d73e12f3704c3c7a3b089da769f6c23079ed69 100644 (file)
@@ -130,16 +130,14 @@ pub struct mt {
 }
 
 #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
-/// 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> {
+/// Describes the "storage mode" of a str, whether it's fixed length or a slice.
+pub enum Vstore {
     /// [T, ..N]
     VstoreFixed(uint),
     /// ~[T]
     VstoreUniq,
     /// &[T] and &mut [T]
-    VstoreSlice(Region, M)
+    VstoreSlice(Region)
 }
 
 #[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
@@ -735,8 +733,8 @@ pub enum sty {
     ty_enum(DefId, substs),
     ty_box(t),
     ty_uniq(t),
-    ty_str(Vstore<()>),
-    ty_vec(t, Vstore),
+    ty_str(Vstore),
+    ty_vec(mt, Option<uint>),
     ty_ptr(mt),
     ty_rptr(Region, mt),
     ty_bare_fn(BareFnTy),
@@ -813,7 +811,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>),
@@ -1179,12 +1177,8 @@ fn sflags(substs: &substs) -> uint {
         return f;
     }
     match &st {
-      &ty_str(VstoreSlice(r, ())) => {
-        flags |= rflags(r);
-      }
-      &ty_vec(ty, VstoreSlice(r, _)) => {
+      &ty_str(VstoreSlice(r)) => {
         flags |= rflags(r);
-        flags |= get(ty).flags;
       }
       &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
       &ty_str(_) => {}
@@ -1212,10 +1206,10 @@ fn sflags(substs: &substs) -> uint {
               _ => {}
           }
       }
-      &ty_box(tt) | &ty_uniq(tt) | &ty_vec(tt, _) => {
+      &ty_box(tt) | &ty_uniq(tt) => {
         flags |= get(tt).flags
       }
-      &ty_ptr(ref m) => {
+      &ty_ptr(ref m) | &ty_vec(ref m, _) => {
         flags |= get(m.ty).flags;
       }
       &ty_rptr(r, ref m) => {
@@ -1349,7 +1343,7 @@ 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, v: Vstore<()>) -> t {
+pub fn mk_str(cx: &ctxt, v: Vstore) -> t {
     mk_t(cx, ty_str(v))
 }
 
@@ -1385,8 +1379,16 @@ pub fn mk_nil_ptr(cx: &ctxt) -> t {
     mk_ptr(cx, mt {ty: mk_nil(), mutbl: ast::MutImmutable})
 }
 
-pub fn mk_vec(cx: &ctxt, ty: t, v: Vstore) -> t {
-    mk_t(cx, ty_vec(ty, v))
+pub fn mk_vec(cx: &ctxt, tm: mt, sz: Option<uint>) -> t {
+    mk_t(cx, ty_vec(tm, sz))
+}
+
+pub fn mk_slice(cx: &ctxt, r: Region, tm: mt) -> t {
+    mk_rptr(cx, r,
+            mt {
+                ty: mk_vec(cx, tm, None),
+                mutbl: tm.mutbl
+            })
 }
 
 pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
@@ -1465,8 +1467,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) | ty_vec(ty, _) => maybe_walk_ty(ty, f),
-        ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
+        ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
+        ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_vec(ref tm, _) => {
             maybe_walk_ty(tm.ty, f);
         }
         ty_enum(_, ref substs) | ty_struct(_, ref substs) |
@@ -1601,13 +1603,23 @@ pub fn type_is_self(ty: t) -> bool {
     }
 }
 
+fn type_is_slice(ty:t) -> bool {
+    match get(ty).sty {
+        ty_rptr(_, mt) => match get(mt.ty).sty {
+            ty_vec(_, None) => true,
+            _ => false,
+        },
+        _ => false
+    }
+}
+
 pub fn type_is_structural(ty: t) -> bool {
     match get(ty).sty {
       ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
-      ty_vec(_, VstoreFixed(_)) | ty_str(VstoreFixed(_)) |
-      ty_vec(_, VstoreSlice(..)) | ty_str(VstoreSlice(..))
+      ty_vec(_, Some(_)) |
+      ty_str(VstoreFixed(_)) | ty_str(VstoreSlice(_))
       => true,
-      _ => false
+      _ => type_is_slice(ty)
     }
 }
 
@@ -1621,7 +1633,12 @@ 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(ty, _) => ty,
+        ty_vec(mt, _) => mt.ty,
+        ty_ptr(mt{ty: t, ..}) | ty_rptr(_, mt{ty: t, ..}) |
+        ty_box(t) | ty_uniq(t) => match get(t).sty {
+            ty_vec(mt, None) => mt.ty,
+            _ => cx.sess.bug("sequence_element_type called on non-sequence value"),
+        },
         _ => cx.sess.bug("sequence_element_type called on non-sequence value"),
     }
 }
@@ -1655,8 +1672,13 @@ pub fn type_is_boxed(ty: t) -> bool {
 
 pub fn type_is_region_ptr(ty: t) -> bool {
     match get(ty).sty {
-      ty_rptr(_, _) => true,
-      _ => false
+        ty_rptr(_, mt) => match get(mt.ty).sty {
+            // FIXME(nrc, DST) slices weren't regarded as rptrs, so we preserve this
+            // odd behaviour for now. (But ~[] were unique. I have no idea why).
+            ty_vec(_, None) => false,
+            _ => true
+        },
+        _ => false
     }
 }
 
@@ -1669,7 +1691,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(_, VstoreUniq) | ty_str(VstoreUniq) => true,
+        ty_uniq(_) | ty_str(VstoreUniq) => true,
         _ => false
     }
 }
@@ -1743,8 +1765,7 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t,
             !needs_unwind_cleanup
           }
           ty_uniq(_) |
-          ty_str(VstoreUniq) |
-          ty_vec(_, VstoreUniq) => {
+          ty_str(VstoreUniq) => {
             // Once we're inside a box, the annihilator will find
             // it and destroy it.
             if !encountered_box {
@@ -2086,19 +2107,11 @@ fn tc_ty(cx: &ctxt,
                     borrowed_contents(r, mt.mutbl))
             }
 
-            ty_vec(ty, VstoreUniq) => {
-                tc_ty(cx, ty, cache).owned_pointer()
-            }
-
-            ty_vec(ty, VstoreSlice(r, mutbl)) => {
-                tc_ty(cx, ty, cache).reference(borrowed_contents(r, mutbl))
-            }
-
-            ty_vec(ty, VstoreFixed(_)) => {
-                tc_ty(cx, ty, cache)
+            ty_vec(mt, _) => {
+                tc_mt(cx, mt, cache)
             }
 
-            ty_str(VstoreSlice(r, ())) => {
+            ty_str(VstoreSlice(r)) => {
                 borrowed_contents(r, ast::MutImmutable)
             }
 
@@ -2321,8 +2334,8 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
             // fixed length vectors need special treatment compared to
             // normal vectors, since they don't necessarily have the
             // possibilty to have length zero.
-            ty_vec(_, VstoreFixed(0)) => false, // don't need no contents
-            ty_vec(ty, VstoreFixed(_)) => type_requires(cx, seen, r_ty, ty),
+            ty_vec(_, Some(0)) => false, // don't need no contents
+            ty_vec(mt, Some(_)) => type_requires(cx, seen, r_ty, mt.ty),
 
             ty_nil |
             ty_bot |
@@ -2338,7 +2351,7 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
             ty_err |
             ty_param(_) |
             ty_self(_) |
-            ty_vec(_, _) => {
+            ty_vec(_, None) => {
                 false
             }
             ty_box(typ) | ty_uniq(typ) => {
@@ -2459,8 +2472,8 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
             }
             // Fixed-length vectors.
             // FIXME(#11924) Behavior undecided for zero-length vectors.
-            ty_vec(ty, VstoreFixed(_)) => {
-                type_structurally_recursive(cx, sp, seen, ty)
+            ty_vec(mt, Some(_)) => {
+                type_structurally_recursive(cx, sp, seen, mt.ty)
             }
 
             // Push struct and enum def-ids onto `seen` before recursing.
@@ -2604,21 +2617,34 @@ pub fn type_is_c_like_enum(cx: &ctxt, ty: t) -> bool {
 // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
 pub fn deref(t: t, explicit: bool) -> Option<mt> {
     match get(t).sty {
-        ty_box(typ) | ty_uniq(typ) => Some(mt {
-            ty: typ,
-            mutbl: ast::MutImmutable,
-        }),
-        ty_rptr(_, mt) => Some(mt),
+        ty_box(typ) | ty_uniq(typ) => match get(typ).sty {
+            // Don't deref ~[] etc., might need to generalise this to all DST.
+            ty_vec(_, None) => None,
+            _ => Some(mt {
+                ty: typ,
+                mutbl: ast::MutImmutable,
+            }),
+        },
+        ty_rptr(_, mt) => match get(mt.ty).sty {
+            // Don't deref &[], might need to generalise this to all DST.
+            ty_vec(_, None) => None,
+            _ => Some(mt),
+        },
         ty_ptr(mt) if explicit => Some(mt),
         _ => None
     }
 }
 
 // Returns the type of t[i]
-pub fn index(t: t) -> Option<t> {
+pub fn index(t: t) -> Option<mt> {
     match get(t).sty {
-        ty_vec(ty, _) => Some(ty),
-        ty_str(_) => Some(mk_u8()),
+        ty_vec(mt, _) => Some(mt),
+        ty_ptr(mt{ty: t, ..}) | ty_rptr(_, mt{ty: t, ..}) |
+        ty_box(t) | ty_uniq(t) => match get(t).sty {
+            ty_vec(mt, None) => Some(mt),
+            _ => None,
+        },
+        ty_str(_) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}),
         _ => None
     }
 }
@@ -2723,8 +2749,7 @@ pub fn ty_region(tcx: &ctxt,
                  ty: t) -> Region {
     match get(ty).sty {
         ty_rptr(r, _) => r,
-        ty_vec(_, VstoreSlice(r, _)) => r,
-        ty_str(VstoreSlice(r, ())) => r,
+        ty_str(VstoreSlice(r)) => r,
         ref s => {
             tcx.sess.span_bug(
                 span,
@@ -2929,12 +2954,22 @@ fn borrow_vec(cx: &ctxt, span: Span,
                   r: Region, m: ast::Mutability,
                   ty: ty::t) -> ty::t {
         match get(ty).sty {
-            ty_vec(ty, _) => {
-                ty::mk_vec(cx, ty, VstoreSlice(r, m))
+            ty_uniq(t) | ty_ptr(mt{ty: t, ..}) |
+            ty_rptr(_, mt{ty: t, ..}) => match get(t).sty {
+                ty::ty_vec(mt, None) => ty::mk_slice(cx, r, ty::mt {ty: mt.ty, mutbl: m}),
+                ref s => {
+                    cx.sess.span_bug(
+                        span,
+                        format!("borrow-vec associated with bad sty: {:?}",
+                             s));
+                }
+            },
+            ty_vec(mt, Some(_)) => {
+                ty::mk_slice(cx, r, ty::mt {ty: mt.ty, mutbl: m})
             }
 
             ty_str(_) => {
-                ty::mk_str(cx, VstoreSlice(r, ()))
+                ty::mk_str(cx, VstoreSlice(r))
             }
 
             ref s => {
@@ -4152,10 +4187,10 @@ fn fold_ty(&mut self, t: ty::t) -> ty::t {
             return t_norm;
         }
 
-        fn fold_vstore<M>(&mut self, vstore: Vstore<M>) -> Vstore<M> {
+        fn fold_vstore(&mut self, vstore: Vstore) -> Vstore {
             match vstore {
                 VstoreFixed(..) | VstoreUniq => vstore,
-                VstoreSlice(_, m) => VstoreSlice(ReStatic, m)
+                VstoreSlice(_) => VstoreSlice(ReStatic)
             }
         }
 
@@ -4575,9 +4610,15 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             ty_uniq(_) => {
                 byte!(10);
             }
-            ty_vec(_, v) => {
+            ty_vec(m, Some(_)) => {
                 byte!(11);
-                hash!(v);
+                mt(&mut state, m);
+                1u8.hash(&mut state);
+            }
+            ty_vec(m, None) => {
+                byte!(11);
+                mt(&mut state, m);
+                0u8.hash(&mut state);
             }
             ty_ptr(m) => {
                 byte!(12);
index 840f741badb7a9576b5efddac83681c9cd9d573c..70e14d844e99948807551d9551de34e9bd80adb5 100644 (file)
@@ -68,7 +68,7 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
         r
     }
 
-    fn fold_vstore<M>(&mut self, vstore: ty::Vstore<M>) -> ty::Vstore<M> {
+    fn fold_vstore(&mut self, vstore: ty::Vstore) -> ty::Vstore {
         super_fold_vstore(self, vstore)
     }
 
@@ -147,8 +147,8 @@ 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(ty, vst) => {
-            ty::ty_vec(this.fold_ty(ty), this.fold_vstore(vst))
+        ty::ty_vec(ref tm, sz) => {
+            ty::ty_vec(this.fold_mt(tm), sz)
         }
         ty::ty_enum(tid, ref substs) => {
             ty::ty_enum(tid, this.fold_substs(substs))
@@ -191,13 +191,13 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
     }
 }
 
-pub fn super_fold_vstore<T:TypeFolder, M>(this: &mut T,
-                                          vstore: ty::Vstore<M>)
-                                          -> ty::Vstore<M> {
+pub fn super_fold_vstore<T:TypeFolder>(this: &mut T,
+                                       vstore: ty::Vstore)
+                                       -> ty::Vstore {
     match vstore {
         ty::VstoreFixed(i) => ty::VstoreFixed(i),
         ty::VstoreUniq => ty::VstoreUniq,
-        ty::VstoreSlice(r, m) => ty::VstoreSlice(this.fold_region(r), m),
+        ty::VstoreSlice(r) => ty::VstoreSlice(this.fold_region(r)),
     }
 }
 
index 99f10395437a5ee0bbd9f62e5caf254adcebb5ff..40f69c8c0904e71924a47ee2ebb29480b101eebf 100644 (file)
@@ -389,6 +389,12 @@ fn expect_vstore(&self, tcx: &ty::ctxt, span: Span, ty: &str) -> ty::Vstore {
         }
     }
 
+    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}
+    }
+
     // Handle ~, and & being able to mean strs and vecs.
     // If a_seq_ty is a str or a vec, make it a str/vec.
     // Also handle first-class trait types.
@@ -396,18 +402,20 @@ fn mk_pointer<AC:AstConv,
                   RS:RegionScope>(
                   this: &AC,
                   rscope: &RS,
-                  a_seq_ty: &ast::Ty,
+                  a_seq_ty: &ast::MutTy,
                   ptr_ty: PointerTy,
                   constr: |ty::t| -> ty::t)
                   -> ty::t {
         let tcx = this.tcx();
         debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
 
-        match a_seq_ty.node {
+        match a_seq_ty.ty.node {
             ast::TyVec(ty) => {
-                let vst = ptr_ty.expect_vstore(tcx, a_seq_ty.span, "vectors");
-                debug!("&[]: vst={:?}", vst);
-                return ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty), vst);
+                let mut mt = ast_ty_to_mt(this, rscope, ty);
+                if a_seq_ty.mutbl == ast::MutMutable {
+                    mt.mutbl = ast::MutMutable;
+                }
+                return constr(ty::mk_vec(tcx, mt, None));
             }
             ast::TyPath(ref path, ref bounds, id) => {
                 // Note that the "bounds must be empty if path is not a trait"
@@ -421,8 +429,8 @@ fn mk_pointer<AC:AstConv,
                             ty::VstoreUniq => {
                                 return ty::mk_str(tcx, ty::VstoreUniq);
                             }
-                            ty::VstoreSlice(r, ast::MutImmutable) => {
-                                return ty::mk_str(tcx, ty::VstoreSlice(r, ()));
+                            ty::VstoreSlice(r) => {
+                                return ty::mk_str(tcx, ty::VstoreSlice(r));
                             }
                             _ => {}
                         }
@@ -432,8 +440,8 @@ fn mk_pointer<AC:AstConv,
                             this, rscope, trait_def_id, None, path);
                         let trait_store = match ptr_ty {
                             VStore(ty::VstoreUniq) => ty::UniqTraitStore,
-                            VStore(ty::VstoreSlice(r, m)) => {
-                                ty::RegionTraitStore(r, m)
+                            VStore(ty::VstoreSlice(r)) => {
+                                ty::RegionTraitStore(r, a_seq_ty.mutbl)
                             }
                             _ => {
                                 tcx.sess.span_err(
@@ -456,7 +464,7 @@ fn mk_pointer<AC:AstConv,
             _ => {}
         }
 
-        constr(ast_ty_to_ty(this, rscope, a_seq_ty))
+        constr(ast_ty_to_ty(this, rscope, a_seq_ty.ty))
     }
 
     let tcx = this.tcx();
@@ -479,16 +487,19 @@ fn mk_pointer<AC:AstConv,
             ast::TyNil => ty::mk_nil(),
             ast::TyBot => ty::mk_bot(),
             ast::TyBox(ty) => {
-                mk_pointer(this, rscope, ty, Box, |ty| ty::mk_box(tcx, ty))
+                let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
+                mk_pointer(this, rscope, &mt, Box, |ty| ty::mk_box(tcx, ty))
             }
             ast::TyUniq(ty) => {
-                mk_pointer(this, rscope, ty, VStore(ty::VstoreUniq),
+                let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
+                mk_pointer(this, rscope, &mt, 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_ty(this, rscope, ty), ty::VstoreUniq)
+                let vec_ty = ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), None);
+                ty::mk_uniq(tcx, vec_ty)
             }
             ast::TyPtr(ref mt) => {
                 ty::mk_ptr(tcx, ty::mt {
@@ -499,7 +510,7 @@ fn mk_pointer<AC:AstConv,
             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.ty, VStore(ty::VstoreSlice(r, mt.mutbl)),
+                mk_pointer(this, rscope, mt, VStore(ty::VstoreSlice(r)),
                            |ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
             }
             ast::TyTup(ref fields) => {
@@ -612,11 +623,11 @@ fn mk_pointer<AC:AstConv,
                     Ok(ref r) => {
                         match *r {
                             const_eval::const_int(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
-                                           ty::VstoreFixed(i as uint)),
+                                ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
+                                           Some(i as uint)),
                             const_eval::const_uint(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
-                                           ty::VstoreFixed(i as uint)),
+                                ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
+                                           Some(i as uint)),
                             _ => {
                                 tcx.sess.span_fatal(
                                     ast_ty.span, "expected constant expr for vector length");
index 825c71c3a693a4732b1c4fa7351f9321f0865c08..286c8d1775107ef67df3cdd8cecec940a6a91f76 100644 (file)
@@ -616,48 +616,58 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
             fcx.infcx().next_region_var(
                 infer::PatternRegion(pat.span));
 
+        let check_err = || {
+            for &elt in before.iter() {
+                check_pat(pcx, elt, ty::mk_err());
+            }
+            for &elt in slice.iter() {
+                check_pat(pcx, elt, ty::mk_err());
+            }
+            for &elt in after.iter() {
+                check_pat(pcx, elt, ty::mk_err());
+            }
+            // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
+            fcx.infcx().type_error_message_str_with_expected(
+                pat.span,
+                |expected, actual| {
+                    expected.map_or("".to_owned(), |e| {
+                        format!("mismatched types: expected `{}` but found {}",
+                             e, actual)})},
+                Some(expected),
+                "a vector pattern".to_owned(),
+                None);
+            fcx.write_error(pat.id);
+        };
+
         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 \
-                                              longer supported"
-                                           },
-                                           expected,
-                                           None);
-                    (ty, default_region_var, ast::MutImmutable)
-                }
-                ty::VstoreFixed(_) => {
-                    (ty, default_region_var, ast::MutImmutable)
-                }
-            }
-          }
-          _ => {
-              for &elt in before.iter() {
-                  check_pat(pcx, elt, ty::mk_err());
+          ty::ty_vec(mt, Some(_)) => (mt.ty, default_region_var, ast::MutImmutable),
+          ty::ty_uniq(t) => match ty::get(t).sty {
+              ty::ty_vec(mt, None) => {
+                  fcx.type_error_message(pat.span,
+                                         |_| {
+                                          ~"unique vector patterns are no \
+                                            longer supported"
+                                         },
+                                         expected,
+                                         None);
+                  (mt.ty, default_region_var, ast::MutImmutable)
               }
-              for &elt in slice.iter() {
-                  check_pat(pcx, elt, ty::mk_err());
+              _ => {
+                  check_err();
+                  return;
               }
-              for &elt in after.iter() {
-                  check_pat(pcx, elt, ty::mk_err());
+          },
+          ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty {
+              ty::ty_vec(mt, None) => (mt.ty, r, mt.mutbl),
+              _ => {
+                  check_err();
+                  return;
               }
-              // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
-              fcx.infcx().type_error_message_str_with_expected(
-                  pat.span,
-                  |expected, actual| {
-                      expected.map_or("".to_owned(), |e| {
-                          format!("mismatched types: expected `{}` but found {}",
-                               e, actual)})},
-                  Some(expected),
-                  "a vector pattern".to_owned(),
-                  None);
-              fcx.write_error(pat.id);
+          },
+          _ => {
+              check_err();
               return;
           }
         };
@@ -666,10 +676,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
         }
         match slice {
             Some(slice_pat) => {
-                let slice_ty = ty::mk_vec(tcx,
-                    elt_type,
-                    ty::VstoreSlice(region_var, mutbl)
-                );
+                let slice_ty = ty::mk_slice(tcx,
+                                            region_var,
+                                            ty::mt {ty: elt_type, mutbl: mutbl});
                 check_pat(pcx, slice_pat, slice_ty);
             }
             None => ()
index 6d4e87d634069852f4d7e2965065130f6668fa97..178d3c8b54438e7f267a69d696178bd6a393dc26 100644 (file)
@@ -93,6 +93,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
 use middle::typeck::{param_numbered, param_self, param_index};
 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
 use util::common::indenter;
+use util::ppaux;
 use util::ppaux::Repr;
 
 use collections::HashSet;
@@ -332,6 +333,7 @@ impl<'a> LookupContext<'a> {
     fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
         let span = self.self_expr.map_or(self.span, |e| e.span);
         let self_expr_id = self.self_expr.map(|e| e.id);
+
         let (self_ty, autoderefs, result) =
             check::autoderef(
                 self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
@@ -721,7 +723,7 @@ fn search_for_autoderefd_method(&self,
             None => None,
             Some(method) => {
                 debug!("(searching for autoderef'd method) writing \
-                       adjustment {:?}", adjustment);
+                       adjustment {:?} for {}", adjustment, self.ty_to_str( self_ty));
                 match adjustment {
                     Some((self_expr_id, adj)) => {
                         self.fcx.write_adjustment(self_expr_id, adj);
@@ -765,19 +767,16 @@ fn consider_reborrow(&self,
             ty::ty_rptr(_, self_mt) => {
                 let region =
                     self.infcx().next_region_var(infer::Autoref(self.span));
+                let (extra_derefs, auto) = match ty::get(self_mt.ty).sty {
+                    ty::ty_vec(_, None) => (0, ty::AutoBorrowVec(region, self_mt.mutbl)),
+                    _ => (1, ty::AutoPtr(region, self_mt.mutbl)),
+                };
                 (ty::mk_rptr(tcx, region, self_mt),
                  ty::AutoDerefRef {
-                     autoderefs: autoderefs+1,
-                     autoref: Some(ty::AutoPtr(region, self_mt.mutbl))})
-            }
-            ty::ty_vec(self_ty, VstoreSlice(_, mutbl)) => {
-                let region =
-                    self.infcx().next_region_var(infer::Autoref(self.span));
-                (ty::mk_vec(tcx, self_ty, VstoreSlice(region, mutbl)),
-                 ty::AutoDerefRef {
-                     autoderefs: autoderefs,
-                     autoref: Some(ty::AutoBorrowVec(region, mutbl))})
+                     autoderefs: autoderefs + extra_derefs,
+                     autoref: Some(auto)})
             }
+
             ty::ty_trait(~ty::TyTrait {
                 def_id, ref substs, store: ty::RegionTraitStore(_, mutbl), bounds
             }) => {
@@ -808,6 +807,35 @@ fn default_method_hack(self_mt: ty::mt) -> bool {
         }
     }
 
+    fn auto_slice_vec(&self, mt: ty::mt, autoderefs: uint) -> Option<MethodCallee> {
+        let tcx = self.tcx();
+        debug!("auto_slice_vec {}", ppaux::ty_to_str(tcx, mt.ty));
+
+        // 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_slice(tcx, r,
+                               ty::mt {ty:mt.ty, mutbl:m}));
+
+        if entry.is_some() {
+            return entry;
+        }
+
+        // Then try to borrow to a slice *and* borrow a pointer.
+        self.search_for_some_kind_of_autorefd_method(
+            AutoBorrowVecRef, autoderefs, [MutImmutable, MutMutable],
+            |m,r| {
+                let slice_ty = ty::mk_slice(tcx, r,
+                                            ty::mt {ty:mt.ty, mutbl:m});
+                // NB: we do not try to autoref to a mutable
+                // pointer. That would be creating a pointer
+                // to a temporary pointer (the borrowed
+                // slice), so any update the callee makes to
+                // it can't be observed.
+                ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
+            })
+    }
+
     fn search_for_autosliced_method(&self,
                                     self_ty: ty::t,
                                     autoderefs: uint)
@@ -818,44 +846,32 @@ fn search_for_autosliced_method(&self,
          */
 
         let tcx = self.tcx();
+        debug!("search_for_autosliced_method {}", ppaux::ty_to_str(tcx, self_ty));
+
         let sty = ty::get(self_ty).sty.clone();
         match sty {
-            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, VstoreSlice(r, m)));
-
-                if entry.is_some() { return entry; }
-
-                // Then try to borrow to a slice *and* borrow a pointer.
-                self.search_for_some_kind_of_autorefd_method(
-                    AutoBorrowVecRef, autoderefs, [MutImmutable, MutMutable],
-                    |m,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
-                        // slice), so any update the callee makes to
-                        // it can't be observed.
-                        ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
-                    })
-            }
+            ty_rptr(_, mt) => match ty::get(mt.ty).sty {
+                ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
+                _ => None
+            },
+            ty_uniq(t) => match ty::get(t).sty {
+                ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
+                _ => None
+            },
+            ty_vec(mt, Some(_)) => self.auto_slice_vec(mt, autoderefs),
 
             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, VstoreSlice(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, VstoreSlice(r, ()));
+                        let slice_ty = ty::mk_str(tcx, VstoreSlice(r));
                         ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
                     })
             }
@@ -1163,7 +1179,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         });
         debug!("after replacing bound regions, fty={}", self.ty_to_str(fty));
 
-        // before we only checked whether self_ty could be a subtype
+        // Before, we only checked whether self_ty could be a subtype
         // of rcvr_ty; now we actually make it so (this may cause
         // variables to unify etc).  Since we checked beforehand, and
         // nothing has changed in the meantime, this unification
@@ -1293,8 +1309,11 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 debug!("(is relevant?) explicit self is a region");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_rptr(_, mt) => {
-                        mutability_matches(mt.mutbl, m) &&
-                        rcvr_matches_ty(self.fcx, mt.ty, candidate)
+                        match ty::get(mt.ty).sty {
+                            ty::ty_vec(_, None) => false,
+                            _ => mutability_matches(mt.mutbl, m) &&
+                                 rcvr_matches_ty(self.fcx, mt.ty, candidate),
+                        }
                     }
 
                     ty::ty_trait(~ty::TyTrait {
@@ -1312,7 +1331,10 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 debug!("(is relevant?) explicit self is a unique pointer");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
-                        rcvr_matches_ty(self.fcx, typ, candidate)
+                        match ty::get(typ).sty {
+                            ty::ty_vec(_, None) => false,
+                            _ => rcvr_matches_ty(self.fcx, typ, candidate),
+                        }
                     }
 
                     ty::ty_trait(~ty::TyTrait {
index d971b2c31c229b6834705a5b4264e25d76125fa4..65c335a24211446af7d9aef41d76415efff961b8 100644 (file)
@@ -1286,10 +1286,9 @@ 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::VstoreSlice(ty::ReStatic, ())),
+        ast::LitStr(..) => ty::mk_str(tcx, ty::VstoreSlice(ty::ReStatic)),
         ast::LitBinary(..) => {
-            ty::mk_vec(tcx, ty::mk_u8(),
-                       ty::VstoreSlice(ty::ReStatic, ast::MutImmutable))
+            ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable })
         }
         ast::LitChar(_) => ty::mk_char(),
         ast::LitInt(_, t) => ty::mk_mach_int(t),
@@ -2458,7 +2457,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
       ast::ExprVstore(ev, vst) => {
         let typ = match ev.node {
           ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
-            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, ());
+            let v = ast_expr_vstore_to_vstore(fcx, ev, vst);
             ty::mk_str(tcx, v)
           }
           ast::ExprVec(ref args) => {
@@ -2466,7 +2465,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
                 ast::ExprVstoreMutSlice => ast::MutMutable,
                 _ => ast::MutImmutable,
             };
-            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, mutability);
+            let v = ast_expr_vstore_to_vstore(fcx, ev, vst);
             let mut any_error = false;
             let mut any_bot = false;
             let t: ty::t = fcx.infcx().next_ty_var();
@@ -2485,7 +2484,23 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
             } else if any_bot {
                 ty::mk_bot()
             } else {
-                ty::mk_vec(tcx, t, v)
+                match v {
+                    ty::VstoreFixed(sz) => ty::mk_vec(tcx,
+                                                      ty::mt {ty: t, mutbl: mutability},
+                                                      Some(sz)),
+                    ty::VstoreUniq => ty::mk_uniq(tcx,
+                                                  ty::mk_vec(tcx,
+                                                             ty::mt {ty: t, mutbl: mutability},
+                                                             None)), // Sadly, we know the length
+                                                                     // - Some(args.len()) - but
+                                                                     // must thow it away or cause
+                                                                     // confusion further down the
+                                                                     // pipeline. Hopefully we can
+                                                                     // remedy this later.
+                                                                     // See below (x3) too.
+                    ty::VstoreSlice(r) => ty::mk_slice(tcx, r,
+                                                       ty::mt {ty: t, mutbl: mutability}),
+                }
             }
           }
           ast::ExprRepeat(element, count_expr) => {
@@ -2495,7 +2510,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
                 ast::ExprVstoreMutSlice => ast::MutMutable,
                 _ => ast::MutImmutable,
             };
-            let v = ast_expr_vstore_to_vstore(fcx, ev, vst, mutability);
+            let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
             let t = fcx.infcx().next_ty_var();
             check_expr_has_type(fcx, element, t);
             let arg_t = fcx.expr_ty(element);
@@ -2504,7 +2519,17 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
             } else if ty::type_is_bot(arg_t) {
                 ty::mk_bot()
             } else {
-                ty::mk_vec(tcx, t, v)
+                match tt {
+                    ty::VstoreFixed(sz) => ty::mk_vec(tcx,
+                                                      ty::mt {ty: t, mutbl: mutability},
+                                                      Some(sz)),
+                    ty::VstoreUniq => ty::mk_uniq(tcx,
+                                                  ty::mk_vec(tcx,
+                                                             ty::mt {ty: t, mutbl: mutability},
+                                                             None)),
+                    ty::VstoreSlice(r) => ty::mk_slice(tcx, r,
+                                                       ty::mt {ty: t, mutbl: mutability}),
+                }
             }
           }
           _ =>
@@ -2949,6 +2974,11 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
                         fn is_vec(t: ty::t) -> bool {
                             match ty::get(t).sty {
                                 ty::ty_vec(..) => true,
+                                ty::ty_ptr(ty::mt{ty: t, ..}) | ty::ty_rptr(_, ty::mt{ty: t, ..}) |
+                                ty::ty_box(t) | ty::ty_uniq(t) => match ty::get(t).sty {
+                                    ty::ty_vec(_, None) => true,
+                                    _ => false,
+                                },
                                 _ => false
                             }
                         }
@@ -3005,7 +3035,8 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
         for e in args.iter() {
             check_expr_has_type(fcx, *e, t);
         }
-        let typ = ty::mk_vec(tcx, t, ty::VstoreFixed(args.len()));
+        let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable},
+                             Some(args.len()));
         fcx.write_ty(id, typ);
       }
       ast::ExprRepeat(element, count_expr) => {
@@ -3021,7 +3052,8 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
             fcx.write_bot(id);
         }
         else {
-            let t = ty::mk_vec(tcx, t, ty::VstoreFixed(count));
+            let t = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable},
+                               Some(count));
             fcx.write_ty(id, t);
         }
       }
@@ -3089,9 +3121,9 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
-                  Some(ty) => {
+                  Some(mt) => {
                       check_expr_has_type(fcx, idx, ty::mk_uint());
-                      fcx.write_ty(id, ty);
+                      fcx.write_ty(id, mt.ty);
                       fcx.write_autoderef_adjustment(base.id, autoderefs);
                   }
                   None => {
@@ -3833,33 +3865,32 @@ 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<M>(fcx: &FnCtxt,
-                                    e: &ast::Expr,
-                                    v: ast::ExprVstore,
-                                    m: M)
-                                    -> ty::Vstore<M> {
+pub fn ast_expr_vstore_to_vstore(fcx: &FnCtxt,
+                                 e: &ast::Expr,
+                                 v: ast::ExprVstore)
+                                 -> ty::Vstore {
     match v {
         ast::ExprVstoreUniq => ty::VstoreUniq,
         ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
             match e.node {
                 ast::ExprLit(..) => {
                     // string literals and *empty slices* live in static memory
-                    ty::VstoreSlice(ty::ReStatic, m)
+                    ty::VstoreSlice(ty::ReStatic)
                 }
                 ast::ExprVec(ref elements) if elements.len() == 0 => {
                     // string literals and *empty slices* live in static memory
-                    ty::VstoreSlice(ty::ReStatic, m)
+                    ty::VstoreSlice(ty::ReStatic)
                 }
                 ast::ExprRepeat(..) |
                 ast::ExprVec(..) => {
                     // vector literals are temporaries on the stack
                     match fcx.tcx().region_maps.temporary_scope(e.id) {
                         Some(scope) => {
-                            ty::VstoreSlice(ty::ReScope(scope), m)
+                            ty::VstoreSlice(ty::ReScope(scope))
                         }
                         None => {
                             // this slice occurs in a static somewhere
-                            ty::VstoreSlice(ty::ReStatic, m)
+                            ty::VstoreSlice(ty::ReStatic)
                         }
                     }
                 }
index 9e7bb1b10f60f3279ea4bca78888585fa09e227f..f6a4d972a070f91bdcbc115e054d1b0d0353a86c 100644 (file)
@@ -928,11 +928,17 @@ 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::VstoreSlice(r_ptr, ())) |
-        ty::ty_vec(_, ty::VstoreSlice(r_ptr, _)) => {
+        ty::ty_str(ty::VstoreSlice(r_ptr)) => {
             rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
                             r_index_expr, r_ptr);
         }
+        ty::ty_rptr(r_ptr, mt) => match ty::get(mt.ty).sty {
+            ty::ty_vec(_, None) => {
+                rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
+                                r_index_expr, r_ptr);
+            }
+            _ => {}
+        },
 
         _ => {}
     }
index 58a0a5859f9f57c9e5674d5f661e94c0a120f280..d9ec448c2c5cf46af1c68659315364d1e3e881eb 100644 (file)
@@ -100,8 +100,7 @@ fn tcx<'a>(&'a self) -> &'a ty::ctxt {
 
         fn fold_ty(&mut self, ty: ty::t) -> ty::t {
             match ty::get(ty).sty {
-                ty::ty_rptr(r, ty::mt {ty, ..}) |
-                ty::ty_vec(ty, ty::VstoreSlice(r, _)) => {
+                ty::ty_rptr(r, ty::mt {ty, ..}) => {
                     self.relate(r);
                     self.stack.push(r);
                     ty_fold::super_fold_ty(self, ty);
index 7d1ffa4451fb764ef14a51670019bcc5dd5177a5..ad0590318ea924c2b244648fe75978ecf3ee7cde 100644 (file)
@@ -102,9 +102,19 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
         // See above for details.
         match ty::get(b).sty {
             ty::ty_rptr(_, mt_b) => {
-                return self.unpack_actual_value(a, |sty_a| {
-                    self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
-                });
+                match ty::get(mt_b.ty).sty {
+                    ty::ty_vec(mt_b, None) => {
+                        return self.unpack_actual_value(a, |sty_a| {
+                            self.coerce_borrowed_vector(a, sty_a, b, mt_b.mutbl)
+                        });
+                    }
+                    ty::ty_vec(_, _) => {},
+                    _ => {
+                        return self.unpack_actual_value(a, |sty_a| {
+                            self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
+                        });
+                    }
+                };
             }
 
             ty::ty_str(VstoreSlice(..)) => {
@@ -113,12 +123,6 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
                 });
             }
 
-            ty::ty_vec(_, VstoreSlice(_, mutbl_b)) => {
-                return self.unpack_actual_value(a, |sty_a| {
-                    self.coerce_borrowed_vector(a, sty_a, b, mutbl_b)
-                });
-            }
-
             ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
                 return self.unpack_actual_value(a, |sty_a| {
                     self.coerce_borrowed_fn(a, sty_a, b)
@@ -266,7 +270,7 @@ pub fn coerce_borrowed_string(&self,
         };
 
         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, VstoreSlice(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,
@@ -287,14 +291,21 @@ pub fn coerce_borrowed_vector(&self,
         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(ty, _) => ty,
+            ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) |
+            ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty {
+                ty::ty_vec(mt, None) => mt.ty,
+                _ => {
+                    return self.subtype(a, b);
+                }
+            },
+            ty::ty_vec(mt, _) => mt.ty,
             _ => {
                 return self.subtype(a, b);
             }
         };
 
-        let a_borrowed = ty::mk_vec(self.get_ref().infcx.tcx, ty_inner,
-                                    VstoreSlice(r_borrow, mutbl_b));
+        let a_borrowed = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow,
+                                      mt {ty: ty_inner, mutbl: mutbl_b});
         if_ok!(sub.tys(a_borrowed, b));
         Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
index 8c449a8f118f481e921e5e7c1f923c49c42a2052..bd3bb18fa3364897c23fb1e7dffb8bc720612ea5 100644 (file)
@@ -270,15 +270,15 @@ fn contraregions(&self, a: ty::Region, b: ty::Region)
 
     fn vstores(&self,
                 vk: ty::terr_vstore_kind,
-                a: ty::Vstore<()>,
-                b: ty::Vstore<()>)
-                -> cres<ty::Vstore<()>> {
+                a: ty::Vstore,
+                b: ty::Vstore)
+                -> cres<ty::Vstore> {
         debug!("{}.vstores(a={:?}, b={:?})", self.tag(), a, b);
 
         match (a, b) {
-            (ty::VstoreSlice(a_r, _), ty::VstoreSlice(b_r, _)) => {
+            (ty::VstoreSlice(a_r), ty::VstoreSlice(b_r)) => {
                 self.contraregions(a_r, b_r).and_then(|r| {
-                    Ok(ty::VstoreSlice(r, ()))
+                    Ok(ty::VstoreSlice(r))
                 })
             }
 
@@ -510,48 +510,49 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
       }
 
       (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
-        this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_uniq(tcx, typ)))
+            let typ = if_ok!(this.tys(a_inner, b_inner));
+
+            match (&ty::get(a_inner).sty, &ty::get(b_inner).sty) {
+                (&ty::ty_vec(_, None), &ty::ty_vec(_, None)) => Ok(ty::mk_uniq(tcx, typ)),
+                (&ty::ty_vec(_, None), _) |
+                (_, &ty::ty_vec(_, None)) => Err(ty::terr_sorts(expected_found(this, a, b))),
+                _ => Ok(ty::mk_uniq(tcx, typ)),
+            }
       }
 
       (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {
-        this.mts(a_mt, b_mt).and_then(|mt| Ok(ty::mk_ptr(tcx, mt)))
+            let mt = if_ok!(this.mts(a_mt, b_mt));
+            match (&ty::get(a_mt.ty).sty, &ty::get(b_mt.ty).sty) {
+                (&ty::ty_vec(_, None), &ty::ty_vec(_, None)) => Ok(ty::mk_ptr(tcx, mt)),
+                (&ty::ty_vec(_, None), _) |
+                (_, &ty::ty_vec(_, None)) => Err(ty::terr_sorts(expected_found(this, a, b))),
+                _ => Ok(ty::mk_ptr(tcx, mt)),
+            }
       }
 
       (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
-          let r = if_ok!(this.contraregions(a_r, b_r));
-          let mt = if_ok!(this.mts(a_mt, b_mt));
-          Ok(ty::mk_rptr(tcx, r, mt))
+            let r = if_ok!(this.contraregions(a_r, b_r));
+            let mt = if_ok!(this.mts(a_mt, b_mt));
+
+            // This is a horible hack - historically, [T] was not treated as a type,
+            // so, for example, &T and &[U] should not unify. In fact the only thing
+            // &[U] should unify with is &[T]. We preserve that behaviour with this
+            // check. See also ty_uniq, ty_ptr.
+            match (&ty::get(a_mt.ty).sty, &ty::get(b_mt.ty).sty) {
+                (&ty::ty_vec(_, None), &ty::ty_vec(_, None)) => Ok(ty::mk_rptr(tcx, r, mt)),
+                (&ty::ty_vec(_, None), _) |
+                (_, &ty::ty_vec(_, None)) => Err(ty::terr_sorts(expected_found(this, a, b))),
+                _ => Ok(ty::mk_rptr(tcx, r, 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| {
-                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))
-            })
+      (&ty::ty_vec(ref a_mt, sz_a), &ty::ty_vec(ref b_mt, sz_b)) => {
+        this.mts(a_mt, b_mt).and_then(|mt| {
+            if sz_a == sz_b {
+                Ok(ty::mk_vec(tcx, mt, sz_a))
+            } else {
+                Err(ty::terr_sorts(expected_found(this, a, b)))
+            }
         })
       }
 
index ecf4f67e7cd736f463983d772f26fadb4185cf9d..907153d6cbee4816fa7190e3d121bdd79b447f8a 100644 (file)
@@ -717,16 +717,8 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_vstore(vstore, variance);
             }
 
-            ty::ty_vec(ty, vstore) => {
-                self.add_constraints_from_vstore(vstore, 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_vec(ref mt, _) => {
+                self.add_constraints_from_mt(mt, variance);
             }
 
             ty::ty_uniq(typ) | ty::ty_box(typ) => {
@@ -799,11 +791,11 @@ fn add_constraints_from_ty(&mut self,
 
     /// Adds constraints appropriate for a vector with Vstore `vstore`
     /// appearing in a context with ambient variance `variance`
-    fn add_constraints_from_vstore<M>(&mut self,
-                                      vstore: ty::Vstore<M>,
-                                      variance: VarianceTermPtr<'a>) {
+    fn add_constraints_from_vstore(&mut self,
+                                   vstore: ty::Vstore,
+                                   variance: VarianceTermPtr<'a>) {
         match vstore {
-            ty::VstoreSlice(r, _) => {
+            ty::VstoreSlice(r) => {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(r, contra);
             }
index c899ba45d616fb3b573e4617d84571e0dcab335c..1d98cc143de78e7d7fe3feb71a0b0077a1105310 100644 (file)
@@ -395,23 +395,23 @@ fn push_sig_to_str(cx: &ctxt,
         let bound_str = bounds.repr(cx);
         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_str(vs) => {
         match vs {
             ty::VstoreFixed(n) => format!("str/{}", n),
             ty::VstoreUniq => "~str".to_owned(),
-            ty::VstoreSlice(r, ()) => format!("{}str", region_ptr_to_str(cx, r))
+            ty::VstoreSlice(r) => format!("{}str", region_ptr_to_str(cx, r))
         }
       }
+      ty_vec(ref mt, sz) => {
+          match sz {
+              Some(n) => {
+                  format!("[{}, .. {}]", mt_to_str(cx, mt), n)
+              }
+              None => {
+                  format!("[{}]", ty_to_str(cx, mt.ty))
+              }
+          }
+      }
     }
 }
 
@@ -853,19 +853,7 @@ fn repr(&self, tcx: &ctxt) -> ~str {
         match *self {
             ty::VstoreFixed(n) => format!("{}", n),
             ty::VstoreUniq => "~".to_owned(),
-            ty::VstoreSlice(r, m) => {
-                format!("{}{}", region_ptr_to_str(tcx, r), mutability_to_str(m))
-            }
-        }
-    }
-}
-
-impl Repr for ty::Vstore<()> {
-    fn repr(&self, tcx: &ctxt) -> ~str {
-        match *self {
-            ty::VstoreFixed(n) => format!("{}", n),
-            ty::VstoreUniq => "~".to_owned(),
-            ty::VstoreSlice(r, ()) => region_ptr_to_str(tcx, r)
+            ty::VstoreSlice(r) => region_ptr_to_str(tcx, r)
         }
     }
 }