diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 5df5b718f3e76..cfa2d647ec901 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -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(st: &mut PState, conv: conv_did, - parse_mut: |&mut PState| -> M) -> ty::Vstore { +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(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 { + 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);} } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 53fe1c19d8ff9..1d7d43f895ede 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -204,17 +204,17 @@ fn enc_bound_region(w: &mut MemWriter, cx: &ctxt, br: ty::BoundRegion) { } } -pub fn enc_vstore(w: &mut MemWriter, cx: &ctxt, - v: ty::Vstore, - 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"); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index e08ffa89cfba1..db1badb7d5986 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -191,7 +191,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, pats: Vec<@Pat> ) { } } } - ty::ty_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 { - 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 { + 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 { + 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 { // 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 } } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index e376f85ff6db0..6ce815d9bc46c 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -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`") + } + _ => {} + }, _ => {} } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index fc9d5a60eec63..84e9151c11cce 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -170,7 +170,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option { 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 { 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 { 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 @@ impl MemCategorizationContext { expr_ty: ty::t, def: ast::Def) -> McResult { - 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 @@ impl MemCategorizationContext { //! 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 @@ impl MemCategorizationContext { */ 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 @@ impl Repr for InteriorKind { 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 diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 393e35141b4ec..72818576cbb71 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -438,7 +438,8 @@ impl<'a,'b> Clone for ArmData<'a, 'b> { 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])); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 735b60622ed62..92a6bb73c8e3a 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -188,7 +188,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, // FIXME #6750 ~Trait cannot be directly marked as // noalias because the actual object pointer is nested. ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) | - ty::ty_vec(_, ty::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 @@ pub fn iter_structural_ty<'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); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 4aaa9760e8941..8bc217343f7fe 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -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)); } _ => {} diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b8f6d445c3637..72e716d0c3cae 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -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 diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 03b442bae218f..8848feb888904 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -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; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index e44370afa2d71..1a57acf84d221 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2202,27 +2202,27 @@ fn type_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) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 50eda155b52f1..4e850b8990a1a 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -240,8 +240,8 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, // this type may have a different region/mutability than the // real one, but it will have the same runtime representation - let slice_ty = ty::mk_vec(tcx, 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)) + } + } } _ => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 966e05ff1eaf0..98e09b2fd31fd 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -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| { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index de1ee72c9df1b..7dc4641e97fa7 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -54,7 +54,7 @@ impl<'a> Reflector<'a> { // We're careful to not use first class aggregates here because that // will kick us off fast isel. (Issue #4352.) let bcx = self.bcx; - let str_vstore = ty::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 @@ impl<'a> Reflector<'a> { self.visit("leave_" + bracket_name, extra); } - pub fn vstore_name_and_extra(&mut self, - t: ty::t, - vstore: ty::Vstore) - -> (~str, Vec ) { + pub fn vstore_name_and_extra(&mut self, + t: ty::t, + vstore: ty::Vstore) + -> (~str, Vec ) { 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 @@ impl<'a> Reflector<'a> { 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 @@ impl<'a> Reflector<'a> { 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) => { diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index a590c5b38f4c2..4bcb609df616c 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -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 { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 071eb083d4fdc..48c25fb985d83 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -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") diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f71e507cfcb74..037182d8b7b80 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -129,16 +129,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 { +/// 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)] @@ -738,8 +736,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), ty_ptr(mt), ty_rptr(Region, mt), ty_bare_fn(BareFnTy), @@ -816,7 +814,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>), + terr_vstores_differ(terr_vstore_kind, expected_found), terr_trait_stores_differ(terr_vstore_kind, expected_found), terr_in_field(@type_err, ast::Ident), terr_sorts(expected_found), @@ -1184,12 +1182,8 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { 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(_) => {} @@ -1217,10 +1211,10 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { _ => {} } } - &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) => { @@ -1354,7 +1348,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)) } @@ -1390,8 +1384,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) -> 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 { mk_t(cx, ty_tup(ts)) } @@ -1470,8 +1472,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) | @@ -1606,13 +1608,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) } } @@ -1626,7 +1638,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"), } } @@ -1660,8 +1677,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 } } @@ -1674,7 +1696,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 } } @@ -1748,8 +1770,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 { @@ -2091,19 +2112,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { 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) } @@ -2326,8 +2339,8 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool { // fixed length vectors need special treatment compared to // normal vectors, since they don't necessarily have the // possibilty to have length zero. - ty_vec(_, 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 | @@ -2343,7 +2356,7 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool { ty_err | ty_param(_) | ty_self(_) | - ty_vec(_, _) => { + ty_vec(_, None) => { false } ty_box(typ) | ty_uniq(typ) => { @@ -2464,8 +2477,8 @@ pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability { } // 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. @@ -2609,21 +2622,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 { 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 { +pub fn index(t: t) -> Option { 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 } } @@ -2728,8 +2754,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, @@ -2934,12 +2959,22 @@ pub fn adjust_ty(cx: &ctxt, 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 => { @@ -4168,10 +4203,10 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t { return t_norm; } - fn fold_vstore(&mut self, vstore: Vstore) -> Vstore { + fn fold_vstore(&mut self, vstore: Vstore) -> Vstore { match vstore { VstoreFixed(..) | VstoreUniq => vstore, - VstoreSlice(_, m) => VstoreSlice(ReStatic, m) + VstoreSlice(_) => VstoreSlice(ReStatic) } } @@ -4591,9 +4626,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); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 840f741badb7a..70e14d844e999 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -68,7 +68,7 @@ pub trait TypeFolder { r } - fn fold_vstore(&mut self, vstore: ty::Vstore) -> ty::Vstore { + fn fold_vstore(&mut self, vstore: ty::Vstore) -> ty::Vstore { super_fold_vstore(self, vstore) } @@ -147,8 +147,8 @@ pub fn super_fold_sty(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(this: &mut T, } } -pub fn super_fold_vstore(this: &mut T, - vstore: ty::Vstore) - -> ty::Vstore { +pub fn super_fold_vstore(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)), } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 99f10395437a5..40f69c8c0904e 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -389,6 +389,12 @@ pub fn ast_ty_to_ty( } } + fn ast_ty_to_mt(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 @@ pub fn ast_ty_to_ty( 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 @@ pub fn ast_ty_to_ty( 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 @@ pub fn ast_ty_to_ty( 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 @@ pub fn ast_ty_to_ty( _ => {} } - 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 @@ pub fn ast_ty_to_ty( 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 @@ pub fn ast_ty_to_ty( 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 @@ pub fn ast_ty_to_ty( 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"); diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 825c71c3a693a..286c8d1775107 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -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 => () diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 6d4e87d634069..178d3c8b54438 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -93,6 +93,7 @@ use middle::typeck::{MethodStatic, MethodObject}; 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 { 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 @@ impl<'a> LookupContext<'a> { 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 @@ impl<'a> LookupContext<'a> { 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 @@ impl<'a> LookupContext<'a> { } } + fn auto_slice_vec(&self, mt: ty::mt, autoderefs: uint) -> Option { + 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 @@ impl<'a> LookupContext<'a> { */ 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 @@ impl<'a> LookupContext<'a> { }); 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 @@ impl<'a> LookupContext<'a> { 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 @@ impl<'a> LookupContext<'a> { 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 { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f640b5dc9be0f..fb470cbdfb1ab 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1341,10 +1341,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), @@ -2513,7 +2512,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, ast::ExprVstore(ev, vst) => { let typ = match ev.node { ast::ExprLit(lit) if ast_util::lit_is_str(lit) => { - let 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) => { @@ -2521,7 +2520,7 @@ fn check_expr_with_unifier(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(); @@ -2540,7 +2539,23 @@ fn check_expr_with_unifier(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) => { @@ -2550,7 +2565,7 @@ fn check_expr_with_unifier(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); @@ -2559,7 +2574,17 @@ fn check_expr_with_unifier(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}), + } } } _ => @@ -3004,6 +3029,11 @@ fn check_expr_with_unifier(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 } } @@ -3060,7 +3090,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt, for e in args.iter() { check_expr_has_type(fcx, *e, t); } - let typ = ty::mk_vec(tcx, 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) => { @@ -3076,7 +3107,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt, 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); } } @@ -3144,9 +3176,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt, autoderef(fcx, expr.span, raw_base_t, Some(base.id), lvalue_pref, |base_t, _| ty::index(base_t)); match field_ty { - Some(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 => { @@ -3888,33 +3920,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(fcx: &FnCtxt, - e: &ast::Expr, - v: ast::ExprVstore, - m: M) - -> ty::Vstore { +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) } } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 9e7bb1b10f60f..f6a4d972a070f 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -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); + } + _ => {} + }, _ => {} } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 58a0a5859f9f5..d9ec448c2c5cf 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -100,8 +100,7 @@ pub fn relate_nested_regions(tcx: &ty::ctxt, fn fold_ty(&mut self, ty: ty::t) -> ty::t { match ty::get(ty).sty { - ty::ty_rptr(r, 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); diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 7d1ffa4451fb7..ad0590318ea92 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -102,9 +102,19 @@ impl<'f> Coerce<'f> { // 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 @@ impl<'f> Coerce<'f> { }); } - 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 @@ impl<'f> Coerce<'f> { }; 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 @@ impl<'f> Coerce<'f> { let sub = Sub(*self.get_ref()); let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); let ty_inner = match *sty_a { - ty::ty_vec(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, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 8c449a8f118f4..bd3bb18fa3364 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -270,15 +270,15 @@ pub trait Combine { fn vstores(&self, vk: ty::terr_vstore_kind, - a: ty::Vstore<()>, - b: ty::Vstore<()>) - -> cres> { + a: ty::Vstore, + b: ty::Vstore) + -> cres { 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(this: &C, a: ty::t, b: ty::t) -> cres { } (&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))) + } }) } diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index ecf4f67e7cd73..907153d6cbee4 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -717,16 +717,8 @@ impl<'a> ConstraintContext<'a> { 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 @@ impl<'a> ConstraintContext<'a> { /// Adds constraints appropriate for a vector with Vstore `vstore` /// appearing in a context with ambient variance `variance` - fn add_constraints_from_vstore(&mut self, - vstore: ty::Vstore, - variance: VarianceTermPtr<'a>) { + fn add_constraints_from_vstore(&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); } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c899ba45d616f..1d98cc143de78 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -395,23 +395,23 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str { 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 @@ impl Repr for ty::Vstore { 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) } } }