From 37306c1d25a6bb8d1e96adaff6a360d6163b8f29 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 9 Apr 2014 19:15:31 +1200 Subject: [PATCH] Refactor ty_vec represent &[T] as &([T]) 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. --- src/librustc/metadata/tydecode.rs | 28 ++- src/librustc/metadata/tyencode.rs | 22 ++- src/librustc/middle/check_match.rs | 165 ++++++++++-------- src/librustc/middle/lint.rs | 12 +- src/librustc/middle/mem_categorization.rs | 28 +-- src/librustc/middle/trans/_match.rs | 8 +- src/librustc/middle/trans/base.rs | 12 +- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/common.rs | 8 +- src/librustc/middle/trans/consts.rs | 22 ++- src/librustc/middle/trans/debuginfo.rs | 30 ++-- src/librustc/middle/trans/expr.rs | 41 +++-- src/librustc/middle/trans/glue.rs | 48 +++-- src/librustc/middle/trans/reflect.rs | 57 +++--- src/librustc/middle/trans/tvec.rs | 56 ++++-- src/librustc/middle/trans/type_of.rs | 51 +++--- src/librustc/middle/ty.rs | 165 +++++++++++------- src/librustc/middle/ty_fold.rs | 14 +- src/librustc/middle/typeck/astconv.rs | 47 +++-- src/librustc/middle/typeck/check/_match.rs | 93 +++++----- src/librustc/middle/typeck/check/method.rs | 102 ++++++----- src/librustc/middle/typeck/check/mod.rs | 73 +++++--- src/librustc/middle/typeck/check/regionck.rs | 10 +- .../middle/typeck/check/regionmanip.rs | 3 +- src/librustc/middle/typeck/infer/coercion.rs | 37 ++-- src/librustc/middle/typeck/infer/combine.rs | 79 ++++----- src/librustc/middle/typeck/variance.rs | 20 +-- src/librustc/util/ppaux.rs | 36 ++-- 28 files changed, 759 insertions(+), 510 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 5df5b718f3e..cfa2d647ec9 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 53fe1c19d8f..1d7d43f895e 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 e08ffa89cfb..db1badb7d59 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 - } - ty::ty_vec(_, ty::VstoreFixed(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 + 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(), + } } - }); - 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 + not_useful } + ty::ty_vec(_, Some(n)) => { + is_useful_specialized(cx, m, v, vec(n), n, left_ty) + } + 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 + } + _ => { + 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) + 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 e376f85ff6d..6ce815d9bc4 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 fc9d5a60eec..84e9151c11c 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 393e35141b4..72818576cbb 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 735b60622ed..92a6bb73c8e 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 4aaa9760e89..8bc217343f7 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 b8f6d445c36..72e716d0c3c 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 03b442bae21..8848feb8889 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 e44370afa2d..1a57acf84d2 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 50eda155b52..4e850b8990a 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 966e05ff1ea..98e09b2fd31 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 de1ee72c9df..7dc4641e97f 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 a590c5b38f4..4bcb609df61 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 071eb083d4f..48c25fb985d 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 d6f1866f5dc..04d73e12f37 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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 { +/// 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), 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>), + 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), @@ -1179,13 +1177,9 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { return f; } match &st { - &ty_str(VstoreSlice(r, ())) => { + &ty_str(VstoreSlice(r)) => { flags |= rflags(r); } - &ty_vec(ty, VstoreSlice(r, _)) => { - flags |= rflags(r); - flags |= get(ty).flags; - } &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) | &ty_str(_) => {} // You might think that we could just return ty_err for @@ -1212,10 +1206,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) => { @@ -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) -> 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)) } @@ -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 @@ 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(mt, _) => { + tc_mt(cx, mt, cache) } - 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_str(VstoreSlice(r, ())) => { + ty_str(VstoreSlice(r)) => { borrowed_contents(r, ast::MutImmutable) } @@ -2321,8 +2334,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 | @@ -2338,7 +2351,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) => { @@ -2459,8 +2472,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. @@ -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 { 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 } } @@ -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 @@ 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 => { @@ -4152,10 +4187,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) } } @@ -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); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 840f741badb..70e14d844e9 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 99f10395437..40f69c8c090 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 825c71c3a69..286c8d17751 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) - } - } - } + 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) + } + _ => { + check_err(); + return; + } + }, + ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty { + ty::ty_vec(mt, None) => (mt.ty, r, mt.mutbl), + _ => { + check_err(); + return; + } + }, _ => { - 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); + 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 6d4e87d6340..178d3c8b544 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 d971b2c31c2..65c335a2421 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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_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) => { @@ -2466,7 +2465,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(); @@ -2485,7 +2484,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) => { @@ -2495,7 +2510,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); @@ -2504,7 +2519,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}), + } } } _ => @@ -2949,6 +2974,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 } } @@ -3005,7 +3035,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) => { @@ -3021,7 +3052,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); } } @@ -3089,9 +3121,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 => { @@ -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(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 9e7bb1b10f6..f6a4d972a07 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 58a0a5859f9..d9ec448c2c5 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 7d1ffa4451f..ad0590318ea 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 8c449a8f118..bd3bb18fa33 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 ecf4f67e7cd..907153d6cbe 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 c899ba45d61..1d98cc143de 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) } } }