auto merge of #13636 : nick29581/rust/ty_vec, r=pcwalton
Refactors 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.
This commit is contained in:
commit
02081e7c41
@ -137,8 +137,7 @@ pub fn parse_substs_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx:
|
|||||||
parse_substs(&mut st, conv)
|
parse_substs(&mut st, conv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_vstore<M>(st: &mut PState, conv: conv_did,
|
fn parse_vstore(st: &mut PState, conv: conv_did) -> ty::Vstore {
|
||||||
parse_mut: |&mut PState| -> M) -> ty::Vstore<M> {
|
|
||||||
assert_eq!(next(st), '/');
|
assert_eq!(next(st), '/');
|
||||||
|
|
||||||
let c = peek(st);
|
let c = peek(st);
|
||||||
@ -150,11 +149,24 @@ fn parse_vstore<M>(st: &mut PState, conv: conv_did,
|
|||||||
|
|
||||||
match next(st) {
|
match next(st) {
|
||||||
'~' => ty::VstoreUniq,
|
'~' => 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))
|
c => st.tcx.sess.bug(format!("parse_vstore(): bad input '{}'", c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_size(st: &mut PState) -> Option<uint> {
|
||||||
|
assert_eq!(next(st), '/');
|
||||||
|
|
||||||
|
if peek(st) == '|' {
|
||||||
|
assert_eq!(next(st), '|');
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let n = parse_uint(st);
|
||||||
|
assert_eq!(next(st), '|');
|
||||||
|
Some(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
|
fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
|
||||||
match next(st) {
|
match next(st) {
|
||||||
'~' => ty::UniqTraitStore,
|
'~' => 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);
|
return ty::mk_rptr(st.tcx, r, mt);
|
||||||
}
|
}
|
||||||
'V' => {
|
'V' => {
|
||||||
let ty = parse_ty(st, |x,y| conv(x,y));
|
let mt = parse_mt(st, |x,y| conv(x,y));
|
||||||
let v = parse_vstore(st, |x,y| conv(x,y), parse_mutability);
|
let sz = parse_size(st);
|
||||||
return ty::mk_vec(st.tcx, ty, v);
|
return ty::mk_vec(st.tcx, mt, sz);
|
||||||
}
|
}
|
||||||
'v' => {
|
'v' => {
|
||||||
let v = parse_vstore(st, |x,y| conv(x,y), |_| ());
|
let v = parse_vstore(st, |x,y| conv(x,y));
|
||||||
return ty::mk_str(st.tcx, v);
|
return ty::mk_str(st.tcx, v);
|
||||||
}
|
}
|
||||||
'T' => {
|
'T' => {
|
||||||
@ -396,7 +408,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
|||||||
assert_eq!(next(st), ']');
|
assert_eq!(next(st), ']');
|
||||||
return ty::mk_struct(st.tcx, did, substs);
|
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);}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,17 +204,17 @@ fn enc_bound_region(w: &mut MemWriter, cx: &ctxt, br: ty::BoundRegion) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enc_vstore<M>(w: &mut MemWriter, cx: &ctxt,
|
pub fn enc_vstore(w: &mut MemWriter, cx: &ctxt,
|
||||||
v: ty::Vstore<M>,
|
v: ty::Vstore,
|
||||||
enc_mut: |&mut MemWriter, M|) {
|
enc_mut: |&mut MemWriter|) {
|
||||||
mywrite!(w, "/");
|
mywrite!(w, "/");
|
||||||
match v {
|
match v {
|
||||||
ty::VstoreFixed(u) => mywrite!(w, "{}|", u),
|
ty::VstoreFixed(u) => mywrite!(w, "{}|", u),
|
||||||
ty::VstoreUniq => mywrite!(w, "~"),
|
ty::VstoreUniq => mywrite!(w, "~"),
|
||||||
ty::VstoreSlice(r, m) => {
|
ty::VstoreSlice(r) => {
|
||||||
mywrite!(w, "&");
|
mywrite!(w, "&");
|
||||||
enc_region(w, cx, r);
|
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_region(w, cx, r);
|
||||||
enc_mt(w, cx, mt);
|
enc_mt(w, cx, mt);
|
||||||
}
|
}
|
||||||
ty::ty_vec(ty, v) => {
|
ty::ty_vec(mt, sz) => {
|
||||||
mywrite!(w, "V");
|
mywrite!(w, "V");
|
||||||
enc_ty(w, cx, ty);
|
enc_mt(w, cx, mt);
|
||||||
enc_vstore(w, cx, v, enc_mutability);
|
mywrite!(w, "/");
|
||||||
|
match sz {
|
||||||
|
Some(n) => mywrite!(w, "{}|", n),
|
||||||
|
None => mywrite!(w, "|"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::ty_str(v) => {
|
ty::ty_str(v) => {
|
||||||
mywrite!(w, "v");
|
mywrite!(w, "v");
|
||||||
enc_vstore(w, cx, v, |_, ()| {});
|
enc_vstore(w, cx, v, |_| {});
|
||||||
}
|
}
|
||||||
ty::ty_closure(ref f) => {
|
ty::ty_closure(ref f) => {
|
||||||
mywrite!(w, "f");
|
mywrite!(w, "f");
|
||||||
|
@ -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 {
|
match *ctor {
|
||||||
vec(n) => Some(format!("vectors of length {}", n)),
|
vec(n) => Some(format!("vectors of length {}", n)),
|
||||||
_ => None
|
_ => None
|
||||||
@ -258,50 +258,57 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
|
|||||||
None => {
|
None => {
|
||||||
match ty::get(left_ty).sty {
|
match ty::get(left_ty).sty {
|
||||||
ty::ty_bool => {
|
ty::ty_bool => {
|
||||||
match is_useful_specialized(cx, m, v,
|
match is_useful_specialized(cx, m, v,
|
||||||
val(const_bool(true)),
|
val(const_bool(true)),
|
||||||
0u, left_ty){
|
0u, left_ty){
|
||||||
not_useful => {
|
not_useful => {
|
||||||
is_useful_specialized(cx, m, v,
|
is_useful_specialized(cx, m, v,
|
||||||
val(const_bool(false)),
|
val(const_bool(false)),
|
||||||
0u, left_ty)
|
0u, left_ty)
|
||||||
|
}
|
||||||
|
ref u => (*u).clone(),
|
||||||
}
|
}
|
||||||
ref u => (*u).clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::ty_enum(eid, _) => {
|
ty::ty_enum(eid, _) => {
|
||||||
for va in (*ty::enum_variants(cx.tcx, eid)).iter() {
|
for va in (*ty::enum_variants(cx.tcx, eid)).iter() {
|
||||||
match is_useful_specialized(cx, m, v, variant(va.id),
|
match is_useful_specialized(cx, m, v, variant(va.id),
|
||||||
va.args.len(), left_ty) {
|
va.args.len(), left_ty) {
|
||||||
not_useful => (),
|
not_useful => (),
|
||||||
ref u => return (*u).clone(),
|
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
|
|
||||||
}
|
}
|
||||||
});
|
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
let arity = ctor_arity(cx, &single, left_ty);
|
||||||
is_useful_specialized(cx, m, v, single, arity, 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,
|
fn missing_ctor(cx: &MatchCheckCtxt,
|
||||||
m: &matrix,
|
m: &matrix,
|
||||||
left_ty: ty::t)
|
left_ty: ty::t)
|
||||||
-> Option<ctor> {
|
-> Option<ctor> {
|
||||||
match ty::get(left_ty).sty {
|
return match ty::get(left_ty).sty {
|
||||||
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(..) | ty::ty_tup(_) |
|
ty::ty_box(_) | ty::ty_tup(_) |
|
||||||
ty::ty_struct(..) => {
|
ty::ty_struct(..) => check_matrix_for_wild(cx, m),
|
||||||
for r in m.iter() {
|
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty: ty, ..}) => match ty::get(ty).sty {
|
||||||
if !is_wild(cx, *r.get(0)) { return None; }
|
ty::ty_vec(_, None) => ctor_for_slice(m),
|
||||||
}
|
_ => check_matrix_for_wild(cx, m),
|
||||||
return Some(single);
|
},
|
||||||
}
|
|
||||||
ty::ty_enum(eid, _) => {
|
ty::ty_enum(eid, _) => {
|
||||||
let mut found = Vec::new();
|
let mut found = Vec::new();
|
||||||
for r in m.iter() {
|
for r in m.iter() {
|
||||||
@ -441,7 +447,7 @@ fn missing_ctor(cx: &MatchCheckCtxt,
|
|||||||
else if true_found { Some(val(const_bool(false))) }
|
else if true_found { Some(val(const_bool(false))) }
|
||||||
else { Some(val(const_bool(true))) }
|
else { Some(val(const_bool(true))) }
|
||||||
}
|
}
|
||||||
ty::ty_vec(_, ty::VstoreFixed(n)) => {
|
ty::ty_vec(_, Some(n)) => {
|
||||||
let mut missing = true;
|
let mut missing = true;
|
||||||
let mut wrong = false;
|
let mut wrong = false;
|
||||||
for r in m.iter() {
|
for r in m.iter() {
|
||||||
@ -464,8 +470,19 @@ fn missing_ctor(cx: &MatchCheckCtxt,
|
|||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_vec(..) => {
|
ty::ty_vec(..) => fail!("impossible case"),
|
||||||
|
_ => Some(single)
|
||||||
|
};
|
||||||
|
|
||||||
|
fn check_matrix_for_wild(cx: &MatchCheckCtxt, m: &matrix) -> Option<ctor> {
|
||||||
|
for r in m.iter() {
|
||||||
|
if !is_wild(cx, *r.get(0)) { return None; }
|
||||||
|
}
|
||||||
|
return Some(single);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For slice and ~[T].
|
||||||
|
fn ctor_for_slice(m: &matrix) -> Option<ctor> {
|
||||||
// Find the lengths and slices of all vector patterns.
|
// Find the lengths and slices of all vector patterns.
|
||||||
let mut vec_pat_lens = m.iter().filter_map(|r| {
|
let mut vec_pat_lens = m.iter().filter_map(|r| {
|
||||||
match r.get(0).node {
|
match r.get(0).node {
|
||||||
@ -511,31 +528,37 @@ fn missing_ctor(cx: &MatchCheckCtxt,
|
|||||||
Some(k) => Some(vec(k)),
|
Some(k) => Some(vec(k)),
|
||||||
None => None
|
None => None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => Some(single)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
|
fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
|
||||||
match ty::get(ty).sty {
|
fn vec_ctor_arity(ctor: &ctor) -> uint {
|
||||||
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(..) => {
|
|
||||||
match *ctor {
|
match *ctor {
|
||||||
vec(n) => n,
|
vec(n) => n,
|
||||||
_ => 0u
|
_ => 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,7 +918,6 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
|
|||||||
n_box += 1;
|
n_box += 1;
|
||||||
}
|
}
|
||||||
ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
|
ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
|
||||||
ty::ty_vec(_, ty::VstoreUniq) |
|
|
||||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||||
ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
|
ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
|
||||||
n_uniq += 1;
|
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) {
|
fn check_deprecated_owned_vector(cx: &Context, e: &ast::Expr) {
|
||||||
let t = ty::expr_ty(cx.tcx, e);
|
let t = ty::expr_ty(cx.tcx, e);
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_vec(_, ty::VstoreUniq) => {
|
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||||
cx.span_lint(DeprecatedOwnedVector, e.span,
|
ty::ty_vec(_, None) => {
|
||||||
"use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
|
cx.span_lint(DeprecatedOwnedVector, e.span,
|
||||||
}
|
"use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
|||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_uniq(_) |
|
ty::ty_uniq(_) |
|
||||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
ty::ty_trait(~ty::TyTrait { store: 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, ..}) => {
|
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||||
Some(deref_ptr(OwnedPtr))
|
Some(deref_ptr(OwnedPtr))
|
||||||
@ -180,13 +179,12 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
|||||||
let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
|
let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
|
||||||
Some(deref_ptr(BorrowedPtr(kind, r)))
|
Some(deref_ptr(BorrowedPtr(kind, r)))
|
||||||
}
|
}
|
||||||
ty::ty_vec(_, ty::VstoreSlice(r, mutbl)) |
|
|
||||||
ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(r, mutbl), .. }) => {
|
ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(r, mutbl), .. }) => {
|
||||||
let kind = ty::BorrowKind::from_mutbl(mutbl);
|
let kind = ty::BorrowKind::from_mutbl(mutbl);
|
||||||
Some(deref_ptr(BorrowedPtr(kind, r)))
|
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, _), ..}) => {
|
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(r, _), ..}) => {
|
||||||
Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
|
Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
|
||||||
}
|
}
|
||||||
@ -204,7 +202,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
|||||||
Some(deref_interior(InteriorField(PositionalField(0))))
|
Some(deref_interior(InteriorField(PositionalField(0))))
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_vec(_, ty::VstoreFixed(_)) |
|
ty::ty_vec(_, Some(_)) |
|
||||||
ty::ty_str(ty::VstoreFixed(_)) => {
|
ty::ty_str(ty::VstoreFixed(_)) => {
|
||||||
Some(deref_interior(InteriorElement(element_kind(t))))
|
Some(deref_interior(InteriorElement(element_kind(t))))
|
||||||
}
|
}
|
||||||
@ -483,8 +481,8 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
|||||||
expr_ty: ty::t,
|
expr_ty: ty::t,
|
||||||
def: ast::Def)
|
def: ast::Def)
|
||||||
-> McResult<cmt> {
|
-> McResult<cmt> {
|
||||||
debug!("cat_def: id={} expr={}",
|
debug!("cat_def: id={} expr={} def={:?}",
|
||||||
id, expr_ty.repr(self.tcx()));
|
id, expr_ty.repr(self.tcx()), def);
|
||||||
|
|
||||||
match def {
|
match def {
|
||||||
ast::DefStruct(..) | ast::DefVariant(..) => {
|
ast::DefStruct(..) | ast::DefVariant(..) => {
|
||||||
@ -785,7 +783,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
|||||||
//! the implicit index deref, if any (see above)
|
//! the implicit index deref, if any (see above)
|
||||||
|
|
||||||
let element_ty = match ty::index(base_cmt.ty) {
|
let element_ty = match ty::index(base_cmt.ty) {
|
||||||
Some(ty) => ty,
|
Some(ref mt) => mt.ty,
|
||||||
None => {
|
None => {
|
||||||
self.tcx().sess.span_bug(
|
self.tcx().sess.span_bug(
|
||||||
elt.span(),
|
elt.span(),
|
||||||
@ -868,13 +866,10 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
match ty::get(slice_ty).sty {
|
match ty::get(slice_ty).sty {
|
||||||
ty::ty_vec(_, ty::VstoreSlice(slice_r, mutbl)) => {
|
ty::ty_rptr(r, ref mt) => match ty::get(mt.ty).sty {
|
||||||
(mutbl, slice_r)
|
ty::ty_vec(slice_mt, None) => (slice_mt.mutbl, r),
|
||||||
}
|
_ => vec_slice_info(tcx, pat, mt.ty),
|
||||||
|
},
|
||||||
ty::ty_rptr(_, ref mt) => {
|
|
||||||
vec_slice_info(tcx, pat, mt.ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess.span_bug(
|
tcx.sess.span_bug(
|
||||||
@ -1307,6 +1302,11 @@ impl Repr for InteriorKind {
|
|||||||
|
|
||||||
fn element_kind(t: ty::t) -> ElementKind {
|
fn element_kind(t: ty::t) -> ElementKind {
|
||||||
match ty::get(t).sty {
|
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_vec(..) => VecElement,
|
||||||
ty::ty_str(..) => StrElement,
|
ty::ty_str(..) => StrElement,
|
||||||
_ => OtherElement
|
_ => OtherElement
|
||||||
|
@ -438,7 +438,8 @@ impl<'a,'b> Clone for ArmData<'a, 'b> {
|
|||||||
struct Match<'a,'b> {
|
struct Match<'a,'b> {
|
||||||
pats: Vec<@ast::Pat> ,
|
pats: Vec<@ast::Pat> ,
|
||||||
data: ArmData<'a,'b>,
|
data: ArmData<'a,'b>,
|
||||||
bound_ptrs: Vec<(Ident, ValueRef)> }
|
bound_ptrs: Vec<(Ident, ValueRef)>
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a,'b> Repr for Match<'a,'b> {
|
impl<'a,'b> Repr for Match<'a,'b> {
|
||||||
fn repr(&self, tcx: &ty::ctxt) -> ~str {
|
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_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset);
|
||||||
let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
|
let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
|
||||||
let slice_len = Sub(bcx, len, slice_len_offset);
|
let slice_len = Sub(bcx, len, slice_len_offset);
|
||||||
let slice_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty,
|
let slice_ty = ty::mk_slice(bcx.tcx(),
|
||||||
ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
|
ty::ReStatic,
|
||||||
|
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
|
||||||
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
|
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
|
||||||
Store(bcx, slice_begin,
|
Store(bcx, slice_begin,
|
||||||
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
|
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
|
||||||
|
@ -188,7 +188,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
|
|||||||
// FIXME #6750 ~Trait cannot be directly marked as
|
// FIXME #6750 ~Trait cannot be directly marked as
|
||||||
// noalias because the actual object pointer is nested.
|
// noalias because the actual object pointer is nested.
|
||||||
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
||||||
ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) => {
|
ty::ty_str(ty::VstoreUniq) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
|
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
|
// FIXME #6750 ~Trait cannot be directly marked as
|
||||||
// noalias because the actual object pointer is nested.
|
// noalias because the actual object pointer is nested.
|
||||||
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
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, ..}) => {
|
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
|
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_str(ty::VstoreFixed(n)) => {
|
||||||
ty::ty_vec(_, ty::VstoreFixed(n)) => {
|
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
|
||||||
|
let (base, len) = tvec::get_fixed_base_and_byte_len(cx, av, unit_ty, n);
|
||||||
|
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
|
||||||
|
}
|
||||||
|
ty::ty_vec(_, Some(n)) => {
|
||||||
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
|
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);
|
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);
|
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
|
||||||
|
@ -653,7 +653,7 @@ pub fn trans_call_inner<'a>(
|
|||||||
match ty::get(ret_ty).sty {
|
match ty::get(ret_ty).sty {
|
||||||
// `~` pointer return values never alias because ownership
|
// `~` pointer return values never alias because ownership
|
||||||
// is transferred
|
// is transferred
|
||||||
ty::ty_uniq(..) | ty::ty_vec(_, ty::VstoreUniq) => {
|
ty::ty_uniq(..) => {
|
||||||
attrs.push((0, NoAliasAttribute));
|
attrs.push((0, NoAliasAttribute));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -711,8 +711,12 @@ pub enum MonoDataClass {
|
|||||||
pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
|
pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_float(_) => MonoFloat,
|
ty::ty_float(_) => MonoFloat,
|
||||||
ty::ty_rptr(..) | ty::ty_uniq(..) | ty::ty_box(..) |
|
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||||
ty::ty_str(ty::VstoreUniq) | ty::ty_vec(_, ty::VstoreUniq) |
|
ty::ty_vec(_, None) => MonoBits,
|
||||||
|
_ => MonoNonNull,
|
||||||
|
},
|
||||||
|
ty::ty_uniq(..) | ty::ty_box(..) |
|
||||||
|
ty::ty_str(ty::VstoreUniq) |
|
||||||
ty::ty_bare_fn(..) => MonoNonNull,
|
ty::ty_bare_fn(..) => MonoNonNull,
|
||||||
// Is that everything? Would closures or slices qualify?
|
// Is that everything? Would closures or slices qualify?
|
||||||
_ => MonoBits
|
_ => MonoBits
|
||||||
|
@ -139,8 +139,11 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
|
|||||||
Some(ref mt) => {
|
Some(ref mt) => {
|
||||||
assert!(mt.mutbl != ast::MutMutable);
|
assert!(mt.mutbl != ast::MutMutable);
|
||||||
let dv = match ty::get(t).sty {
|
let dv = match ty::get(t).sty {
|
||||||
ty::ty_ptr(..) | ty::ty_rptr(..) => {
|
ty::ty_ptr(mt) | ty::ty_rptr(_, mt) => {
|
||||||
const_deref_ptr(cx, v)
|
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(..) => {
|
ty::ty_enum(..) | ty::ty_struct(..) => {
|
||||||
const_deref_newtype(cx, v, t)
|
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_base, 0);
|
||||||
assert_eq!(abi::slice_elt_len, 1);
|
assert_eq!(abi::slice_elt_len, 1);
|
||||||
match ty::get(ty).sty {
|
match ty::get(ty).sty {
|
||||||
ty::ty_vec(_, ty::VstoreFixed(len)) => {
|
ty::ty_vec(_, Some(len)) => {
|
||||||
llconst = C_struct(cx, [
|
llconst = C_struct(cx, [
|
||||||
llptr,
|
llptr,
|
||||||
C_uint(cx, len)
|
C_uint(cx, len)
|
||||||
@ -432,14 +435,21 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||||||
"index is not an integer-constant expression")
|
"index is not an integer-constant expression")
|
||||||
};
|
};
|
||||||
let (arr, len) = match ty::get(bt).sty {
|
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(..)) => {
|
ty::ty_str(ty::VstoreSlice(..)) => {
|
||||||
let e1 = const_get_elt(cx, bv, [0]);
|
let e1 = const_get_elt(cx, bv, [0]);
|
||||||
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
|
(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,
|
_ => 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;
|
let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
|
||||||
|
@ -2202,27 +2202,27 @@ fn type_metadata(cx: &CrateContext,
|
|||||||
ty::ty_box(typ) => {
|
ty::ty_box(typ) => {
|
||||||
create_pointer_to_box_metadata(cx, t, typ)
|
create_pointer_to_box_metadata(cx, t, typ)
|
||||||
},
|
},
|
||||||
ty::ty_vec(ty, ref vstore) => {
|
ty::ty_vec(ref mt, Some(len)) => fixed_vec_metadata(cx, mt.ty, len, usage_site_span),
|
||||||
match *vstore {
|
ty::ty_uniq(typ) => {
|
||||||
ty::VstoreFixed(len) => {
|
match ty::get(typ).sty {
|
||||||
fixed_vec_metadata(cx, ty, len, usage_site_span)
|
ty::ty_vec(ref mt, None) => {
|
||||||
}
|
let vec_metadata = vec_metadata(cx, mt.ty, usage_site_span);
|
||||||
ty::VstoreUniq => {
|
|
||||||
let vec_metadata = vec_metadata(cx, ty, usage_site_span);
|
|
||||||
pointer_type_metadata(cx, t, vec_metadata)
|
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) => {
|
ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
|
||||||
let pointee = type_metadata(cx, mt.ty, usage_site_span);
|
match ty::get(mt.ty).sty {
|
||||||
pointer_type_metadata(cx, t, pointee)
|
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) => {
|
ty::ty_bare_fn(ref barefnty) => {
|
||||||
subroutine_type_metadata(cx, &barefnty.sig, usage_site_span)
|
subroutine_type_metadata(cx, &barefnty.sig, usage_site_span)
|
||||||
|
@ -240,8 +240,8 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
|
|||||||
|
|
||||||
// this type may have a different region/mutability than the
|
// this type may have a different region/mutability than the
|
||||||
// real one, but it will have the same runtime representation
|
// real one, but it will have the same runtime representation
|
||||||
let slice_ty = ty::mk_vec(tcx, unit_ty,
|
let slice_ty = ty::mk_slice(tcx, ty::ReStatic,
|
||||||
ty::VstoreSlice(ty::ReStatic, ast::MutImmutable));
|
ty::mt { ty: unit_ty, mutbl: ast::MutImmutable });
|
||||||
|
|
||||||
let scratch = rvalue_scratch_datum(bcx, slice_ty, "__adjust");
|
let scratch = rvalue_scratch_datum(bcx, slice_ty, "__adjust");
|
||||||
Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
|
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 {
|
pub fn cast_type_kind(t: ty::t) -> cast_kind {
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_char => cast_integral,
|
ty::ty_char => cast_integral,
|
||||||
ty::ty_float(..) => cast_float,
|
ty::ty_float(..) => cast_float,
|
||||||
ty::ty_ptr(..) => cast_pointer,
|
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_bare_fn(..) => cast_pointer,
|
||||||
ty::ty_int(..) => cast_integral,
|
ty::ty_int(..) => cast_integral,
|
||||||
ty::ty_uint(..) => cast_integral,
|
ty::ty_uint(..) => cast_integral,
|
||||||
ty::ty_bool => cast_integral,
|
ty::ty_bool => cast_integral,
|
||||||
ty::ty_enum(..) => cast_enum,
|
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 {
|
let r = match ty::get(datum.ty).sty {
|
||||||
ty::ty_uniq(content_ty) => {
|
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) => {
|
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_ptr(ty::mt { ty: content_ty, .. }) |
|
||||||
ty::ty_rptr(_, 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
|
// Always generate an lvalue datum, even if datum.mode is
|
||||||
// an rvalue. This is because datum.mode is only an
|
// an rvalue. This is because datum.mode is only an
|
||||||
// rvalue for non-owning pointers like &T or *T, in which
|
// rvalue for non-owning pointers like &T or *T, in which
|
||||||
// case cleanup *is* scheduled elsewhere, by the true
|
// case cleanup *is* scheduled elsewhere, by the true
|
||||||
// owner (or, in the case of *T, by the user).
|
// owner (or, in the case of *T, by the user).
|
||||||
DatumBlock(bcx, Datum(ptr, content_ty, LvalueExpr))
|
DatumBlock(bcx, Datum(ptr, content_ty, LvalueExpr))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -83,19 +83,21 @@ fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
|
|||||||
ty::mk_box(tcx, ty::mk_i8()),
|
ty::mk_box(tcx, ty::mk_i8()),
|
||||||
|
|
||||||
ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ) => {
|
ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ) => {
|
||||||
let llty = sizing_type_of(ccx, typ);
|
match ty::get(typ).sty {
|
||||||
// Unique boxes do not allocate for zero-size types. The standard library may assume
|
ty::ty_vec(_, None) => t,
|
||||||
// that `free` is never called on the pointer returned for `~ZeroSizeType`.
|
_ => {
|
||||||
if llsize_of_alloc(ccx, llty) == 0 {
|
let llty = sizing_type_of(ccx, typ);
|
||||||
ty::mk_i8()
|
// Unique boxes do not allocate for zero-size types. The standard
|
||||||
} else {
|
// library may assume that `free` is never called on the pointer
|
||||||
ty::mk_uniq(tcx, ty::mk_i8())
|
// returned for `~ZeroSizeType`.
|
||||||
}
|
if llsize_of_alloc(ccx, llty) == 0 {
|
||||||
}
|
ty::mk_i8()
|
||||||
|
} else {
|
||||||
ty::ty_vec(ty, ty::VstoreUniq) if !ty::type_needs_drop(tcx, ty) =>
|
ty::mk_uniq(tcx, ty::mk_i8())
|
||||||
ty::mk_uniq(tcx, ty::mk_i8()),
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => t
|
_ => 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) => {
|
ty::ty_uniq(content_ty) => {
|
||||||
let llbox = Load(bcx, v0);
|
let llbox = Load(bcx, v0);
|
||||||
let not_null = IsNotNull(bcx, llbox);
|
let not_null = IsNotNull(bcx, llbox);
|
||||||
with_cond(bcx, not_null, |bcx| {
|
match ty::get(content_ty).sty {
|
||||||
let bcx = drop_ty(bcx, llbox, content_ty);
|
ty::ty_vec(mt, None) => {
|
||||||
trans_exchange_free(bcx, llbox)
|
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 llbox = Load(bcx, v0);
|
||||||
let not_null = IsNotNull(bcx, llbox);
|
let not_null = IsNotNull(bcx, llbox);
|
||||||
with_cond(bcx, not_null, |bcx| {
|
with_cond(bcx, not_null, |bcx| {
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> Reflector<'a> {
|
|||||||
// We're careful to not use first class aggregates here because that
|
// We're careful to not use first class aggregates here because that
|
||||||
// will kick us off fast isel. (Issue #4352.)
|
// will kick us off fast isel. (Issue #4352.)
|
||||||
let bcx = self.bcx;
|
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 str_ty = ty::mk_str(bcx.tcx(), str_vstore);
|
||||||
let scratch = rvalue_scratch_datum(bcx, str_ty, "");
|
let scratch = rvalue_scratch_datum(bcx, str_ty, "");
|
||||||
let len = C_uint(bcx.ccx(), s.get().len());
|
let len = C_uint(bcx.ccx(), s.get().len());
|
||||||
@ -121,10 +121,10 @@ impl<'a> Reflector<'a> {
|
|||||||
self.visit("leave_" + bracket_name, extra);
|
self.visit("leave_" + bracket_name, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vstore_name_and_extra<M>(&mut self,
|
pub fn vstore_name_and_extra(&mut self,
|
||||||
t: ty::t,
|
t: ty::t,
|
||||||
vstore: ty::Vstore<M>)
|
vstore: ty::Vstore)
|
||||||
-> (~str, Vec<ValueRef> ) {
|
-> (~str, Vec<ValueRef> ) {
|
||||||
match vstore {
|
match vstore {
|
||||||
ty::VstoreFixed(n) => {
|
ty::VstoreFixed(n) => {
|
||||||
let extra = (vec!(self.c_uint(n))).append(self.c_size_and_align(t).as_slice());
|
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);
|
let (name, extra) = self.vstore_name_and_extra(t, vst);
|
||||||
self.visit("estr_".to_owned() + name, extra.as_slice())
|
self.visit("estr_".to_owned() + name, extra.as_slice())
|
||||||
}
|
}
|
||||||
ty::ty_vec(ty, vst) => {
|
ty::ty_vec(ref mt, Some(sz)) => {
|
||||||
let (name, extra) = self.vstore_name_and_extra(t, vst);
|
let extra = (vec!(self.c_uint(sz))).append(self.c_size_and_align(t).as_slice());
|
||||||
let extra = extra.append(self.c_mt(&ty::mt {
|
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||||
ty: ty,
|
self.visit("evec_fixed".to_owned(), extra.as_slice())
|
||||||
mutbl: match vst {
|
|
||||||
ty::VstoreSlice(_, m) => m,
|
|
||||||
_ => ast::MutImmutable
|
|
||||||
}
|
|
||||||
}).as_slice());
|
|
||||||
self.visit("evec_".to_owned() + name, extra.as_slice())
|
|
||||||
}
|
}
|
||||||
|
ty::ty_vec(..) => fail!("unexpected unsized vec"),
|
||||||
// Should remove mt from box and uniq.
|
// Should remove mt from box and uniq.
|
||||||
ty::ty_box(typ) => {
|
ty::ty_box(typ) => {
|
||||||
let extra = self.c_mt(&ty::mt {
|
let extra = self.c_mt(&ty::mt {
|
||||||
@ -188,19 +183,37 @@ impl<'a> Reflector<'a> {
|
|||||||
self.visit("box", extra.as_slice())
|
self.visit("box", extra.as_slice())
|
||||||
}
|
}
|
||||||
ty::ty_uniq(typ) => {
|
ty::ty_uniq(typ) => {
|
||||||
let extra = self.c_mt(&ty::mt {
|
match ty::get(typ).sty {
|
||||||
ty: typ,
|
ty::ty_vec(ref mt, None) => {
|
||||||
mutbl: ast::MutImmutable,
|
let (name, extra) = (~"uniq", Vec::new());
|
||||||
});
|
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||||
self.visit("uniq", extra.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) => {
|
ty::ty_ptr(ref mt) => {
|
||||||
let extra = self.c_mt(mt);
|
let extra = self.c_mt(mt);
|
||||||
self.visit("ptr", extra.as_slice())
|
self.visit("ptr", extra.as_slice())
|
||||||
}
|
}
|
||||||
ty::ty_rptr(_, ref mt) => {
|
ty::ty_rptr(_, ref mt) => {
|
||||||
let extra = self.c_mt(mt);
|
match ty::get(mt.ty).sty {
|
||||||
self.visit("rptr", extra.as_slice())
|
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) => {
|
ty::ty_tup(ref tys) => {
|
||||||
|
@ -162,8 +162,10 @@ pub fn trans_slice_vstore<'a>(
|
|||||||
llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
|
llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
|
||||||
|
|
||||||
// Arrange for the backing array to be cleaned up.
|
// Arrange for the backing array to be cleaned up.
|
||||||
let fixed_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty,
|
let fixed_ty = ty::mk_vec(bcx.tcx(),
|
||||||
ty::VstoreFixed(count));
|
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_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to();
|
||||||
let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty);
|
let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty);
|
||||||
let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id);
|
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)
|
(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,
|
pub fn get_base_and_len(bcx: &Block,
|
||||||
llval: ValueRef,
|
llval: ValueRef,
|
||||||
vec_ty: ty::t)
|
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 vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
|
||||||
|
|
||||||
let vstore = match ty::get(vec_ty).sty {
|
let vstore = match ty::get(vec_ty).sty {
|
||||||
ty::ty_vec(_, vst) => vst,
|
ty::ty_str(vst) => vst,
|
||||||
ty::ty_str(vst) => {
|
ty::ty_vec(_, Some(n)) => ty::VstoreFixed(n),
|
||||||
// Convert from immutable-only-Vstore to Vstore.
|
ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty {
|
||||||
match vst {
|
ty::ty_vec(_, None) => ty::VstoreSlice(r),
|
||||||
ty::VstoreFixed(n) => ty::VstoreFixed(n),
|
_ => ccx.sess().bug("unexpected type (ty_rptr) in get_base_and_len"),
|
||||||
ty::VstoreSlice(r, ()) => ty::VstoreSlice(r, ast::MutImmutable),
|
},
|
||||||
ty::VstoreUniq => ty::VstoreUniq
|
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"),
|
||||||
_ => ty::VstoreUniq
|
},
|
||||||
|
_ => ccx.sess().bug("unexpected type in get_base_and_len"),
|
||||||
};
|
};
|
||||||
|
|
||||||
match vstore {
|
match vstore {
|
||||||
|
@ -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_float(t) => Type::float_from_ty(cx, t),
|
||||||
|
|
||||||
ty::ty_str(ty::VstoreUniq) |
|
ty::ty_str(ty::VstoreUniq) |
|
||||||
ty::ty_vec(_, ty::VstoreUniq) |
|
|
||||||
ty::ty_box(..) |
|
ty::ty_box(..) |
|
||||||
ty::ty_uniq(..) |
|
ty::ty_uniq(..) |
|
||||||
ty::ty_ptr(..) |
|
ty::ty_ptr(..) => Type::i8p(cx),
|
||||||
ty::ty_rptr(..) => 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_str(ty::VstoreSlice(..)) => {
|
||||||
ty::ty_vec(_, ty::VstoreSlice(..)) => {
|
|
||||||
Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
|
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_trait(..) => Type::opaque_trait(cx),
|
||||||
|
|
||||||
ty::ty_str(ty::VstoreFixed(size)) => Type::array(&Type::i8(cx), size as u64),
|
ty::ty_str(ty::VstoreFixed(size)) => Type::array(&Type::i8(cx), size as u64),
|
||||||
ty::ty_vec(ty, ty::VstoreFixed(size)) => {
|
ty::ty_vec(mt, Some(size)) => {
|
||||||
Type::array(&sizing_type_of(cx, ty), size as u64)
|
Type::array(&sizing_type_of(cx, mt.ty), size as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_tup(..) | ty::ty_enum(..) => {
|
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()",
|
cx.sess().bug(format!("fictitious type {:?} in sizing_type_of()",
|
||||||
ty::get(t).sty))
|
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()
|
Type::at_box(cx, type_of(cx, typ)).ptr_to()
|
||||||
}
|
}
|
||||||
ty::ty_uniq(typ) => {
|
ty::ty_uniq(typ) => {
|
||||||
type_of(cx, typ).ptr_to()
|
match ty::get(typ).sty {
|
||||||
}
|
ty::ty_vec(mt, None) => Type::vec(cx, &type_of(cx, mt.ty)).ptr_to(),
|
||||||
ty::ty_vec(ty, ty::VstoreUniq) => {
|
_ => type_of(cx, typ).ptr_to(),
|
||||||
Type::vec(cx, &type_of(cx, ty)).ptr_to()
|
}
|
||||||
}
|
}
|
||||||
ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),
|
ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),
|
||||||
ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(),
|
ty::ty_rptr(_, ref mt) => {
|
||||||
|
match ty::get(mt.ty).sty {
|
||||||
ty::ty_vec(ty, ty::VstoreSlice(..)) => {
|
ty::ty_vec(mt, None) => {
|
||||||
let p_ty = type_of(cx, ty).ptr_to();
|
let p_ty = type_of(cx, mt.ty).ptr_to();
|
||||||
let u_ty = Type::uint_from_ty(cx, ast::TyU);
|
let u_ty = Type::uint_from_ty(cx, ast::TyU);
|
||||||
Type::struct_(cx, [p_ty, u_ty], false)
|
Type::struct_(cx, [p_ty, u_ty], false)
|
||||||
|
}
|
||||||
|
_ => type_of(cx, mt.ty).ptr_to(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_str(ty::VstoreSlice(..)) => {
|
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)
|
Type::array(&Type::i8(cx), (n + 1u) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_vec(ty, ty::VstoreFixed(n)) => {
|
ty::ty_vec(ref mt, Some(n)) => {
|
||||||
Type::array(&type_of(cx, ty), n as u64)
|
Type::array(&type_of(cx, mt.ty), n as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_bare_fn(_) => {
|
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)
|
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_infer(..) => cx.sess().bug("type_of with ty_infer"),
|
||||||
ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
|
ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
|
||||||
ty::ty_err(..) => cx.sess().bug("type_of with ty_err")
|
ty::ty_err(..) => cx.sess().bug("type_of with ty_err")
|
||||||
|
@ -129,16 +129,14 @@ pub struct mt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
|
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
|
||||||
/// Describes the "storage mode" of a `[]`, whether it's fixed length or a slice.
|
/// Describes the "storage mode" of a str, whether it's fixed length or a slice.
|
||||||
///
|
pub enum Vstore {
|
||||||
/// Set M to () to disable mutable slices.
|
|
||||||
pub enum Vstore<M = ast::Mutability> {
|
|
||||||
/// [T, ..N]
|
/// [T, ..N]
|
||||||
VstoreFixed(uint),
|
VstoreFixed(uint),
|
||||||
/// ~[T]
|
/// ~[T]
|
||||||
VstoreUniq,
|
VstoreUniq,
|
||||||
/// &[T] and &mut [T]
|
/// &[T] and &mut [T]
|
||||||
VstoreSlice(Region, M)
|
VstoreSlice(Region)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
|
#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
|
||||||
@ -738,8 +736,8 @@ pub enum sty {
|
|||||||
ty_enum(DefId, substs),
|
ty_enum(DefId, substs),
|
||||||
ty_box(t),
|
ty_box(t),
|
||||||
ty_uniq(t),
|
ty_uniq(t),
|
||||||
ty_str(Vstore<()>),
|
ty_str(Vstore),
|
||||||
ty_vec(t, Vstore),
|
ty_vec(mt, Option<uint>),
|
||||||
ty_ptr(mt),
|
ty_ptr(mt),
|
||||||
ty_rptr(Region, mt),
|
ty_rptr(Region, mt),
|
||||||
ty_bare_fn(BareFnTy),
|
ty_bare_fn(BareFnTy),
|
||||||
@ -816,7 +814,7 @@ pub enum type_err {
|
|||||||
terr_regions_no_overlap(Region, Region),
|
terr_regions_no_overlap(Region, Region),
|
||||||
terr_regions_insufficiently_polymorphic(BoundRegion, Region),
|
terr_regions_insufficiently_polymorphic(BoundRegion, Region),
|
||||||
terr_regions_overly_polymorphic(BoundRegion, Region),
|
terr_regions_overly_polymorphic(BoundRegion, Region),
|
||||||
terr_vstores_differ(terr_vstore_kind, expected_found<Vstore<()>>),
|
terr_vstores_differ(terr_vstore_kind, expected_found<Vstore>),
|
||||||
terr_trait_stores_differ(terr_vstore_kind, expected_found<TraitStore>),
|
terr_trait_stores_differ(terr_vstore_kind, expected_found<TraitStore>),
|
||||||
terr_in_field(@type_err, ast::Ident),
|
terr_in_field(@type_err, ast::Ident),
|
||||||
terr_sorts(expected_found<t>),
|
terr_sorts(expected_found<t>),
|
||||||
@ -1184,13 +1182,9 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
match &st {
|
match &st {
|
||||||
&ty_str(VstoreSlice(r, ())) => {
|
&ty_str(VstoreSlice(r)) => {
|
||||||
flags |= rflags(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_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
|
||||||
&ty_str(_) => {}
|
&ty_str(_) => {}
|
||||||
// You might think that we could just return ty_err for
|
// You might think that we could just return ty_err for
|
||||||
@ -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
|
flags |= get(tt).flags
|
||||||
}
|
}
|
||||||
&ty_ptr(ref m) => {
|
&ty_ptr(ref m) | &ty_vec(ref m, _) => {
|
||||||
flags |= get(m.ty).flags;
|
flags |= get(m.ty).flags;
|
||||||
}
|
}
|
||||||
&ty_rptr(r, ref m) => {
|
&ty_rptr(r, ref m) => {
|
||||||
@ -1354,7 +1348,7 @@ pub fn mk_mach_float(tm: ast::FloatTy) -> t {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) }
|
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))
|
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})
|
mk_ptr(cx, mt {ty: mk_nil(), mutbl: ast::MutImmutable})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_vec(cx: &ctxt, ty: t, v: Vstore) -> t {
|
pub fn mk_vec(cx: &ctxt, tm: mt, sz: Option<uint>) -> t {
|
||||||
mk_t(cx, ty_vec(ty, v))
|
mk_t(cx, ty_vec(tm, sz))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mk_slice(cx: &ctxt, r: Region, tm: mt) -> t {
|
||||||
|
mk_rptr(cx, r,
|
||||||
|
mt {
|
||||||
|
ty: mk_vec(cx, tm, None),
|
||||||
|
mutbl: tm.mutbl
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
|
pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> 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_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||||
ty_str(_) | ty_self(_) |
|
ty_str(_) | ty_self(_) |
|
||||||
ty_infer(_) | ty_param(_) | ty_err => {}
|
ty_infer(_) | ty_param(_) | ty_err => {}
|
||||||
ty_box(ty) | ty_uniq(ty) | ty_vec(ty, _) => maybe_walk_ty(ty, f),
|
ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
|
||||||
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
|
ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_vec(ref tm, _) => {
|
||||||
maybe_walk_ty(tm.ty, f);
|
maybe_walk_ty(tm.ty, f);
|
||||||
}
|
}
|
||||||
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
|
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 {
|
pub fn type_is_structural(ty: t) -> bool {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
|
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
|
||||||
ty_vec(_, VstoreFixed(_)) | ty_str(VstoreFixed(_)) |
|
ty_vec(_, Some(_)) |
|
||||||
ty_vec(_, VstoreSlice(..)) | ty_str(VstoreSlice(..))
|
ty_str(VstoreFixed(_)) | ty_str(VstoreSlice(_))
|
||||||
=> true,
|
=> 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 {
|
pub fn sequence_element_type(cx: &ctxt, ty: t) -> t {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_str(_) => mk_mach_uint(ast::TyU8),
|
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"),
|
_ => 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 {
|
pub fn type_is_region_ptr(ty: t) -> bool {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_rptr(_, _) => true,
|
ty_rptr(_, mt) => match get(mt.ty).sty {
|
||||||
_ => false
|
// 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 {
|
pub fn type_is_unique(ty: t) -> bool {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_uniq(_) | ty_vec(_, VstoreUniq) | ty_str(VstoreUniq) => true,
|
ty_uniq(_) | ty_str(VstoreUniq) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1748,8 +1770,7 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t,
|
|||||||
!needs_unwind_cleanup
|
!needs_unwind_cleanup
|
||||||
}
|
}
|
||||||
ty_uniq(_) |
|
ty_uniq(_) |
|
||||||
ty_str(VstoreUniq) |
|
ty_str(VstoreUniq) => {
|
||||||
ty_vec(_, VstoreUniq) => {
|
|
||||||
// Once we're inside a box, the annihilator will find
|
// Once we're inside a box, the annihilator will find
|
||||||
// it and destroy it.
|
// it and destroy it.
|
||||||
if !encountered_box {
|
if !encountered_box {
|
||||||
@ -2091,19 +2112,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
|||||||
borrowed_contents(r, mt.mutbl))
|
borrowed_contents(r, mt.mutbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
ty_vec(ty, VstoreUniq) => {
|
ty_vec(mt, _) => {
|
||||||
tc_ty(cx, ty, cache).owned_pointer()
|
tc_mt(cx, mt, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty_vec(ty, VstoreSlice(r, mutbl)) => {
|
ty_str(VstoreSlice(r)) => {
|
||||||
tc_ty(cx, ty, cache).reference(borrowed_contents(r, mutbl))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty_vec(ty, VstoreFixed(_)) => {
|
|
||||||
tc_ty(cx, ty, cache)
|
|
||||||
}
|
|
||||||
|
|
||||||
ty_str(VstoreSlice(r, ())) => {
|
|
||||||
borrowed_contents(r, ast::MutImmutable)
|
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
|
// fixed length vectors need special treatment compared to
|
||||||
// normal vectors, since they don't necessarily have the
|
// normal vectors, since they don't necessarily have the
|
||||||
// possibilty to have length zero.
|
// possibilty to have length zero.
|
||||||
ty_vec(_, VstoreFixed(0)) => false, // don't need no contents
|
ty_vec(_, Some(0)) => false, // don't need no contents
|
||||||
ty_vec(ty, VstoreFixed(_)) => type_requires(cx, seen, r_ty, ty),
|
ty_vec(mt, Some(_)) => type_requires(cx, seen, r_ty, mt.ty),
|
||||||
|
|
||||||
ty_nil |
|
ty_nil |
|
||||||
ty_bot |
|
ty_bot |
|
||||||
@ -2343,7 +2356,7 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
|
|||||||
ty_err |
|
ty_err |
|
||||||
ty_param(_) |
|
ty_param(_) |
|
||||||
ty_self(_) |
|
ty_self(_) |
|
||||||
ty_vec(_, _) => {
|
ty_vec(_, None) => {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
ty_box(typ) | ty_uniq(typ) => {
|
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.
|
// Fixed-length vectors.
|
||||||
// FIXME(#11924) Behavior undecided for zero-length vectors.
|
// FIXME(#11924) Behavior undecided for zero-length vectors.
|
||||||
ty_vec(ty, VstoreFixed(_)) => {
|
ty_vec(mt, Some(_)) => {
|
||||||
type_structurally_recursive(cx, sp, seen, ty)
|
type_structurally_recursive(cx, sp, seen, mt.ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push struct and enum def-ids onto `seen` before recursing.
|
// 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.
|
// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
|
||||||
pub fn deref(t: t, explicit: bool) -> Option<mt> {
|
pub fn deref(t: t, explicit: bool) -> Option<mt> {
|
||||||
match get(t).sty {
|
match get(t).sty {
|
||||||
ty_box(typ) | ty_uniq(typ) => Some(mt {
|
ty_box(typ) | ty_uniq(typ) => match get(typ).sty {
|
||||||
ty: typ,
|
// Don't deref ~[] etc., might need to generalise this to all DST.
|
||||||
mutbl: ast::MutImmutable,
|
ty_vec(_, None) => None,
|
||||||
}),
|
_ => Some(mt {
|
||||||
ty_rptr(_, mt) => 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),
|
ty_ptr(mt) if explicit => Some(mt),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the type of t[i]
|
// Returns the type of t[i]
|
||||||
pub fn index(t: t) -> Option<t> {
|
pub fn index(t: t) -> Option<mt> {
|
||||||
match get(t).sty {
|
match get(t).sty {
|
||||||
ty_vec(ty, _) => Some(ty),
|
ty_vec(mt, _) => Some(mt),
|
||||||
ty_str(_) => Some(mk_u8()),
|
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
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2728,8 +2754,7 @@ pub fn ty_region(tcx: &ctxt,
|
|||||||
ty: t) -> Region {
|
ty: t) -> Region {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_rptr(r, _) => r,
|
ty_rptr(r, _) => r,
|
||||||
ty_vec(_, VstoreSlice(r, _)) => r,
|
ty_str(VstoreSlice(r)) => r,
|
||||||
ty_str(VstoreSlice(r, ())) => r,
|
|
||||||
ref s => {
|
ref s => {
|
||||||
tcx.sess.span_bug(
|
tcx.sess.span_bug(
|
||||||
span,
|
span,
|
||||||
@ -2934,12 +2959,22 @@ pub fn adjust_ty(cx: &ctxt,
|
|||||||
r: Region, m: ast::Mutability,
|
r: Region, m: ast::Mutability,
|
||||||
ty: ty::t) -> ty::t {
|
ty: ty::t) -> ty::t {
|
||||||
match get(ty).sty {
|
match get(ty).sty {
|
||||||
ty_vec(ty, _) => {
|
ty_uniq(t) | ty_ptr(mt{ty: t, ..}) |
|
||||||
ty::mk_vec(cx, ty, VstoreSlice(r, m))
|
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_str(_) => {
|
||||||
ty::mk_str(cx, VstoreSlice(r, ()))
|
ty::mk_str(cx, VstoreSlice(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
ref s => {
|
ref s => {
|
||||||
@ -4168,10 +4203,10 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t {
|
|||||||
return t_norm;
|
return t_norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_vstore<M>(&mut self, vstore: Vstore<M>) -> Vstore<M> {
|
fn fold_vstore(&mut self, vstore: Vstore) -> Vstore {
|
||||||
match vstore {
|
match vstore {
|
||||||
VstoreFixed(..) | VstoreUniq => 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(_) => {
|
ty_uniq(_) => {
|
||||||
byte!(10);
|
byte!(10);
|
||||||
}
|
}
|
||||||
ty_vec(_, v) => {
|
ty_vec(m, Some(_)) => {
|
||||||
byte!(11);
|
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) => {
|
ty_ptr(m) => {
|
||||||
byte!(12);
|
byte!(12);
|
||||||
|
@ -68,7 +68,7 @@ pub trait TypeFolder {
|
|||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_vstore<M>(&mut self, vstore: ty::Vstore<M>) -> ty::Vstore<M> {
|
fn fold_vstore(&mut self, vstore: ty::Vstore) -> ty::Vstore {
|
||||||
super_fold_vstore(self, vstore)
|
super_fold_vstore(self, vstore)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +147,8 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
|
|||||||
ty::ty_ptr(ref tm) => {
|
ty::ty_ptr(ref tm) => {
|
||||||
ty::ty_ptr(this.fold_mt(tm))
|
ty::ty_ptr(this.fold_mt(tm))
|
||||||
}
|
}
|
||||||
ty::ty_vec(ty, vst) => {
|
ty::ty_vec(ref tm, sz) => {
|
||||||
ty::ty_vec(this.fold_ty(ty), this.fold_vstore(vst))
|
ty::ty_vec(this.fold_mt(tm), sz)
|
||||||
}
|
}
|
||||||
ty::ty_enum(tid, ref substs) => {
|
ty::ty_enum(tid, ref substs) => {
|
||||||
ty::ty_enum(tid, this.fold_substs(substs))
|
ty::ty_enum(tid, this.fold_substs(substs))
|
||||||
@ -191,13 +191,13 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn super_fold_vstore<T:TypeFolder, M>(this: &mut T,
|
pub fn super_fold_vstore<T:TypeFolder>(this: &mut T,
|
||||||
vstore: ty::Vstore<M>)
|
vstore: ty::Vstore)
|
||||||
-> ty::Vstore<M> {
|
-> ty::Vstore {
|
||||||
match vstore {
|
match vstore {
|
||||||
ty::VstoreFixed(i) => ty::VstoreFixed(i),
|
ty::VstoreFixed(i) => ty::VstoreFixed(i),
|
||||||
ty::VstoreUniq => ty::VstoreUniq,
|
ty::VstoreUniq => ty::VstoreUniq,
|
||||||
ty::VstoreSlice(r, m) => ty::VstoreSlice(this.fold_region(r), m),
|
ty::VstoreSlice(r) => ty::VstoreSlice(this.fold_region(r)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,6 +389,12 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
|
||||||
|
rscope: &RS,
|
||||||
|
ty: &ast::Ty) -> ty::mt {
|
||||||
|
ty::mt {ty: ast_ty_to_ty(this, rscope, ty), mutbl: ast::MutImmutable}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle ~, and & being able to mean strs and vecs.
|
// Handle ~, and & being able to mean strs and vecs.
|
||||||
// If a_seq_ty is a str or a vec, make it a str/vec.
|
// If a_seq_ty is a str or a vec, make it a str/vec.
|
||||||
// Also handle first-class trait types.
|
// Also handle first-class trait types.
|
||||||
@ -396,18 +402,20 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
RS:RegionScope>(
|
RS:RegionScope>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
a_seq_ty: &ast::Ty,
|
a_seq_ty: &ast::MutTy,
|
||||||
ptr_ty: PointerTy,
|
ptr_ty: PointerTy,
|
||||||
constr: |ty::t| -> ty::t)
|
constr: |ty::t| -> ty::t)
|
||||||
-> ty::t {
|
-> ty::t {
|
||||||
let tcx = this.tcx();
|
let tcx = this.tcx();
|
||||||
debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
|
debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
|
||||||
|
|
||||||
match a_seq_ty.node {
|
match a_seq_ty.ty.node {
|
||||||
ast::TyVec(ty) => {
|
ast::TyVec(ty) => {
|
||||||
let vst = ptr_ty.expect_vstore(tcx, a_seq_ty.span, "vectors");
|
let mut mt = ast_ty_to_mt(this, rscope, ty);
|
||||||
debug!("&[]: vst={:?}", vst);
|
if a_seq_ty.mutbl == ast::MutMutable {
|
||||||
return ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty), vst);
|
mt.mutbl = ast::MutMutable;
|
||||||
|
}
|
||||||
|
return constr(ty::mk_vec(tcx, mt, None));
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path, ref bounds, id) => {
|
ast::TyPath(ref path, ref bounds, id) => {
|
||||||
// Note that the "bounds must be empty if path is not a trait"
|
// Note that the "bounds must be empty if path is not a trait"
|
||||||
@ -421,8 +429,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
ty::VstoreUniq => {
|
ty::VstoreUniq => {
|
||||||
return ty::mk_str(tcx, ty::VstoreUniq);
|
return ty::mk_str(tcx, ty::VstoreUniq);
|
||||||
}
|
}
|
||||||
ty::VstoreSlice(r, ast::MutImmutable) => {
|
ty::VstoreSlice(r) => {
|
||||||
return ty::mk_str(tcx, ty::VstoreSlice(r, ()));
|
return ty::mk_str(tcx, ty::VstoreSlice(r));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -432,8 +440,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
this, rscope, trait_def_id, None, path);
|
this, rscope, trait_def_id, None, path);
|
||||||
let trait_store = match ptr_ty {
|
let trait_store = match ptr_ty {
|
||||||
VStore(ty::VstoreUniq) => ty::UniqTraitStore,
|
VStore(ty::VstoreUniq) => ty::UniqTraitStore,
|
||||||
VStore(ty::VstoreSlice(r, m)) => {
|
VStore(ty::VstoreSlice(r)) => {
|
||||||
ty::RegionTraitStore(r, m)
|
ty::RegionTraitStore(r, a_seq_ty.mutbl)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess.span_err(
|
tcx.sess.span_err(
|
||||||
@ -456,7 +464,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
let tcx = this.tcx();
|
||||||
@ -479,16 +487,19 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
ast::TyNil => ty::mk_nil(),
|
ast::TyNil => ty::mk_nil(),
|
||||||
ast::TyBot => ty::mk_bot(),
|
ast::TyBot => ty::mk_bot(),
|
||||||
ast::TyBox(ty) => {
|
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) => {
|
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))
|
|ty| ty::mk_uniq(tcx, ty))
|
||||||
}
|
}
|
||||||
ast::TyVec(ty) => {
|
ast::TyVec(ty) => {
|
||||||
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
|
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
|
||||||
// return /something/ so they can at least get more errors
|
// 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) => {
|
ast::TyPtr(ref mt) => {
|
||||||
ty::mk_ptr(tcx, ty::mt {
|
ty::mk_ptr(tcx, ty::mt {
|
||||||
@ -499,7 +510,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
ast::TyRptr(ref region, ref mt) => {
|
ast::TyRptr(ref region, ref mt) => {
|
||||||
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
|
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
|
||||||
debug!("ty_rptr r={}", r.repr(this.tcx()));
|
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}))
|
|ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
|
||||||
}
|
}
|
||||||
ast::TyTup(ref fields) => {
|
ast::TyTup(ref fields) => {
|
||||||
@ -612,11 +623,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
|||||||
Ok(ref r) => {
|
Ok(ref r) => {
|
||||||
match *r {
|
match *r {
|
||||||
const_eval::const_int(i) =>
|
const_eval::const_int(i) =>
|
||||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
|
ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
|
||||||
ty::VstoreFixed(i as uint)),
|
Some(i as uint)),
|
||||||
const_eval::const_uint(i) =>
|
const_eval::const_uint(i) =>
|
||||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, ty),
|
ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
|
||||||
ty::VstoreFixed(i as uint)),
|
Some(i as uint)),
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess.span_fatal(
|
tcx.sess.span_fatal(
|
||||||
ast_ty.span, "expected constant expr for vector length");
|
ast_ty.span, "expected constant expr for vector length");
|
||||||
|
@ -616,48 +616,58 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||||||
fcx.infcx().next_region_var(
|
fcx.infcx().next_region_var(
|
||||||
infer::PatternRegion(pat.span));
|
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,
|
let (elt_type, region_var, mutbl) = match *structure_of(fcx,
|
||||||
pat.span,
|
pat.span,
|
||||||
expected) {
|
expected) {
|
||||||
ty::ty_vec(ty, vstore) => {
|
ty::ty_vec(mt, Some(_)) => (mt.ty, default_region_var, ast::MutImmutable),
|
||||||
match vstore {
|
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||||
ty::VstoreSlice(r, m) => (ty, r, m),
|
ty::ty_vec(mt, None) => {
|
||||||
ty::VstoreUniq => {
|
fcx.type_error_message(pat.span,
|
||||||
fcx.type_error_message(pat.span,
|
|_| {
|
||||||
|_| {
|
~"unique vector patterns are no \
|
||||||
~"unique vector patterns are no \
|
longer supported"
|
||||||
longer supported"
|
},
|
||||||
},
|
expected,
|
||||||
expected,
|
None);
|
||||||
None);
|
(mt.ty, default_region_var, ast::MutImmutable)
|
||||||
(ty, default_region_var, ast::MutImmutable)
|
}
|
||||||
}
|
_ => {
|
||||||
ty::VstoreFixed(_) => {
|
check_err();
|
||||||
(ty, default_region_var, ast::MutImmutable)
|
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_err();
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -666,10 +676,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||||||
}
|
}
|
||||||
match slice {
|
match slice {
|
||||||
Some(slice_pat) => {
|
Some(slice_pat) => {
|
||||||
let slice_ty = ty::mk_vec(tcx,
|
let slice_ty = ty::mk_slice(tcx,
|
||||||
elt_type,
|
region_var,
|
||||||
ty::VstoreSlice(region_var, mutbl)
|
ty::mt {ty: elt_type, mutbl: mutbl});
|
||||||
);
|
|
||||||
check_pat(pcx, slice_pat, slice_ty);
|
check_pat(pcx, slice_pat, slice_ty);
|
||||||
}
|
}
|
||||||
None => ()
|
None => ()
|
||||||
|
@ -93,6 +93,7 @@ use middle::typeck::{MethodStatic, MethodObject};
|
|||||||
use middle::typeck::{param_numbered, param_self, param_index};
|
use middle::typeck::{param_numbered, param_self, param_index};
|
||||||
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
||||||
use util::common::indenter;
|
use util::common::indenter;
|
||||||
|
use util::ppaux;
|
||||||
use util::ppaux::Repr;
|
use util::ppaux::Repr;
|
||||||
|
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
@ -332,6 +333,7 @@ impl<'a> LookupContext<'a> {
|
|||||||
fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
|
fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
|
||||||
let span = self.self_expr.map_or(self.span, |e| e.span);
|
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_expr_id = self.self_expr.map(|e| e.id);
|
||||||
|
|
||||||
let (self_ty, autoderefs, result) =
|
let (self_ty, autoderefs, result) =
|
||||||
check::autoderef(
|
check::autoderef(
|
||||||
self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
|
self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
|
||||||
@ -721,7 +723,7 @@ impl<'a> LookupContext<'a> {
|
|||||||
None => None,
|
None => None,
|
||||||
Some(method) => {
|
Some(method) => {
|
||||||
debug!("(searching for autoderef'd method) writing \
|
debug!("(searching for autoderef'd method) writing \
|
||||||
adjustment {:?}", adjustment);
|
adjustment {:?} for {}", adjustment, self.ty_to_str( self_ty));
|
||||||
match adjustment {
|
match adjustment {
|
||||||
Some((self_expr_id, adj)) => {
|
Some((self_expr_id, adj)) => {
|
||||||
self.fcx.write_adjustment(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) => {
|
ty::ty_rptr(_, self_mt) => {
|
||||||
let region =
|
let region =
|
||||||
self.infcx().next_region_var(infer::Autoref(self.span));
|
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::mk_rptr(tcx, region, self_mt),
|
||||||
ty::AutoDerefRef {
|
ty::AutoDerefRef {
|
||||||
autoderefs: autoderefs+1,
|
autoderefs: autoderefs + extra_derefs,
|
||||||
autoref: Some(ty::AutoPtr(region, self_mt.mutbl))})
|
autoref: Some(auto)})
|
||||||
}
|
|
||||||
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))})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_trait(~ty::TyTrait {
|
ty::ty_trait(~ty::TyTrait {
|
||||||
def_id, ref substs, store: ty::RegionTraitStore(_, mutbl), bounds
|
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<MethodCallee> {
|
||||||
|
let tcx = self.tcx();
|
||||||
|
debug!("auto_slice_vec {}", ppaux::ty_to_str(tcx, mt.ty));
|
||||||
|
|
||||||
|
// First try to borrow to a slice
|
||||||
|
let entry = self.search_for_some_kind_of_autorefd_method(
|
||||||
|
AutoBorrowVec, autoderefs, [MutImmutable, MutMutable],
|
||||||
|
|m,r| ty::mk_slice(tcx, r,
|
||||||
|
ty::mt {ty:mt.ty, mutbl:m}));
|
||||||
|
|
||||||
|
if entry.is_some() {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then try to borrow to a slice *and* borrow a pointer.
|
||||||
|
self.search_for_some_kind_of_autorefd_method(
|
||||||
|
AutoBorrowVecRef, autoderefs, [MutImmutable, MutMutable],
|
||||||
|
|m,r| {
|
||||||
|
let slice_ty = ty::mk_slice(tcx, r,
|
||||||
|
ty::mt {ty:mt.ty, mutbl:m});
|
||||||
|
// NB: we do not try to autoref to a mutable
|
||||||
|
// pointer. That would be creating a pointer
|
||||||
|
// to a temporary pointer (the borrowed
|
||||||
|
// slice), so any update the callee makes to
|
||||||
|
// it can't be observed.
|
||||||
|
ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn search_for_autosliced_method(&self,
|
fn search_for_autosliced_method(&self,
|
||||||
self_ty: ty::t,
|
self_ty: ty::t,
|
||||||
autoderefs: uint)
|
autoderefs: uint)
|
||||||
@ -818,44 +846,32 @@ impl<'a> LookupContext<'a> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
debug!("search_for_autosliced_method {}", ppaux::ty_to_str(tcx, self_ty));
|
||||||
|
|
||||||
let sty = ty::get(self_ty).sty.clone();
|
let sty = ty::get(self_ty).sty.clone();
|
||||||
match sty {
|
match sty {
|
||||||
ty_vec(ty, VstoreUniq) |
|
ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||||
ty_vec(ty, VstoreSlice(..)) |
|
ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
|
||||||
ty_vec(ty, VstoreFixed(_)) => {
|
_ => None
|
||||||
// First try to borrow to a slice
|
},
|
||||||
let entry = self.search_for_some_kind_of_autorefd_method(
|
ty_uniq(t) => match ty::get(t).sty {
|
||||||
AutoBorrowVec, autoderefs, [MutImmutable, MutMutable],
|
ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
|
||||||
|m,r| ty::mk_vec(tcx, ty, VstoreSlice(r, m)));
|
_ => None
|
||||||
|
},
|
||||||
if entry.is_some() { return entry; }
|
ty_vec(mt, Some(_)) => self.auto_slice_vec(mt, autoderefs),
|
||||||
|
|
||||||
// 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_str(VstoreUniq) |
|
ty_str(VstoreUniq) |
|
||||||
ty_str(VstoreFixed(_)) => {
|
ty_str(VstoreFixed(_)) => {
|
||||||
let entry = self.search_for_some_kind_of_autorefd_method(
|
let entry = self.search_for_some_kind_of_autorefd_method(
|
||||||
AutoBorrowVec, autoderefs, [MutImmutable],
|
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; }
|
if entry.is_some() { return entry; }
|
||||||
|
|
||||||
self.search_for_some_kind_of_autorefd_method(
|
self.search_for_some_kind_of_autorefd_method(
|
||||||
AutoBorrowVecRef, autoderefs, [MutImmutable],
|
AutoBorrowVecRef, autoderefs, [MutImmutable],
|
||||||
|m,r| {
|
|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})
|
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));
|
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
|
// of rcvr_ty; now we actually make it so (this may cause
|
||||||
// variables to unify etc). Since we checked beforehand, and
|
// variables to unify etc). Since we checked beforehand, and
|
||||||
// nothing has changed in the meantime, this unification
|
// nothing has changed in the meantime, this unification
|
||||||
@ -1293,8 +1309,11 @@ impl<'a> LookupContext<'a> {
|
|||||||
debug!("(is relevant?) explicit self is a region");
|
debug!("(is relevant?) explicit self is a region");
|
||||||
match ty::get(rcvr_ty).sty {
|
match ty::get(rcvr_ty).sty {
|
||||||
ty::ty_rptr(_, mt) => {
|
ty::ty_rptr(_, mt) => {
|
||||||
mutability_matches(mt.mutbl, m) &&
|
match ty::get(mt.ty).sty {
|
||||||
rcvr_matches_ty(self.fcx, mt.ty, candidate)
|
ty::ty_vec(_, None) => false,
|
||||||
|
_ => mutability_matches(mt.mutbl, m) &&
|
||||||
|
rcvr_matches_ty(self.fcx, mt.ty, candidate),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_trait(~ty::TyTrait {
|
ty::ty_trait(~ty::TyTrait {
|
||||||
@ -1312,7 +1331,10 @@ impl<'a> LookupContext<'a> {
|
|||||||
debug!("(is relevant?) explicit self is a unique pointer");
|
debug!("(is relevant?) explicit self is a unique pointer");
|
||||||
match ty::get(rcvr_ty).sty {
|
match ty::get(rcvr_ty).sty {
|
||||||
ty::ty_uniq(typ) => {
|
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 {
|
ty::ty_trait(~ty::TyTrait {
|
||||||
|
@ -1341,10 +1341,9 @@ pub fn check_lit(fcx: &FnCtxt, lit: &ast::Lit) -> ty::t {
|
|||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
|
|
||||||
match lit.node {
|
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(..) => {
|
ast::LitBinary(..) => {
|
||||||
ty::mk_vec(tcx, ty::mk_u8(),
|
ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable })
|
||||||
ty::VstoreSlice(ty::ReStatic, ast::MutImmutable))
|
|
||||||
}
|
}
|
||||||
ast::LitChar(_) => ty::mk_char(),
|
ast::LitChar(_) => ty::mk_char(),
|
||||||
ast::LitInt(_, t) => ty::mk_mach_int(t),
|
ast::LitInt(_, t) => ty::mk_mach_int(t),
|
||||||
@ -2513,7 +2512,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
ast::ExprVstore(ev, vst) => {
|
ast::ExprVstore(ev, vst) => {
|
||||||
let typ = match ev.node {
|
let typ = match ev.node {
|
||||||
ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
|
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)
|
ty::mk_str(tcx, v)
|
||||||
}
|
}
|
||||||
ast::ExprVec(ref args) => {
|
ast::ExprVec(ref args) => {
|
||||||
@ -2521,7 +2520,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
ast::ExprVstoreMutSlice => ast::MutMutable,
|
ast::ExprVstoreMutSlice => ast::MutMutable,
|
||||||
_ => ast::MutImmutable,
|
_ => 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_error = false;
|
||||||
let mut any_bot = false;
|
let mut any_bot = false;
|
||||||
let t: ty::t = fcx.infcx().next_ty_var();
|
let t: ty::t = fcx.infcx().next_ty_var();
|
||||||
@ -2540,7 +2539,23 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
} else if any_bot {
|
} else if any_bot {
|
||||||
ty::mk_bot()
|
ty::mk_bot()
|
||||||
} else {
|
} 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) => {
|
ast::ExprRepeat(element, count_expr) => {
|
||||||
@ -2550,7 +2565,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
ast::ExprVstoreMutSlice => ast::MutMutable,
|
ast::ExprVstoreMutSlice => ast::MutMutable,
|
||||||
_ => ast::MutImmutable,
|
_ => 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();
|
let t = fcx.infcx().next_ty_var();
|
||||||
check_expr_has_type(fcx, element, t);
|
check_expr_has_type(fcx, element, t);
|
||||||
let arg_t = fcx.expr_ty(element);
|
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) {
|
} else if ty::type_is_bot(arg_t) {
|
||||||
ty::mk_bot()
|
ty::mk_bot()
|
||||||
} else {
|
} 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 {
|
fn is_vec(t: ty::t) -> bool {
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_vec(..) => true,
|
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
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3060,7 +3090,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
for e in args.iter() {
|
for e in args.iter() {
|
||||||
check_expr_has_type(fcx, *e, t);
|
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);
|
fcx.write_ty(id, typ);
|
||||||
}
|
}
|
||||||
ast::ExprRepeat(element, count_expr) => {
|
ast::ExprRepeat(element, count_expr) => {
|
||||||
@ -3076,7 +3107,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||||||
fcx.write_bot(id);
|
fcx.write_bot(id);
|
||||||
}
|
}
|
||||||
else {
|
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);
|
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),
|
autoderef(fcx, expr.span, raw_base_t, Some(base.id),
|
||||||
lvalue_pref, |base_t, _| ty::index(base_t));
|
lvalue_pref, |base_t, _| ty::index(base_t));
|
||||||
match field_ty {
|
match field_ty {
|
||||||
Some(ty) => {
|
Some(mt) => {
|
||||||
check_expr_has_type(fcx, idx, ty::mk_uint());
|
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);
|
fcx.write_autoderef_adjustment(base.id, autoderefs);
|
||||||
}
|
}
|
||||||
None => {
|
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);
|
return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_expr_vstore_to_vstore<M>(fcx: &FnCtxt,
|
pub fn ast_expr_vstore_to_vstore(fcx: &FnCtxt,
|
||||||
e: &ast::Expr,
|
e: &ast::Expr,
|
||||||
v: ast::ExprVstore,
|
v: ast::ExprVstore)
|
||||||
m: M)
|
-> ty::Vstore {
|
||||||
-> ty::Vstore<M> {
|
|
||||||
match v {
|
match v {
|
||||||
ast::ExprVstoreUniq => ty::VstoreUniq,
|
ast::ExprVstoreUniq => ty::VstoreUniq,
|
||||||
ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
|
ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprLit(..) => {
|
ast::ExprLit(..) => {
|
||||||
// string literals and *empty slices* live in static memory
|
// 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 => {
|
ast::ExprVec(ref elements) if elements.len() == 0 => {
|
||||||
// string literals and *empty slices* live in static memory
|
// string literals and *empty slices* live in static memory
|
||||||
ty::VstoreSlice(ty::ReStatic, m)
|
ty::VstoreSlice(ty::ReStatic)
|
||||||
}
|
}
|
||||||
ast::ExprRepeat(..) |
|
ast::ExprRepeat(..) |
|
||||||
ast::ExprVec(..) => {
|
ast::ExprVec(..) => {
|
||||||
// vector literals are temporaries on the stack
|
// vector literals are temporaries on the stack
|
||||||
match fcx.tcx().region_maps.temporary_scope(e.id) {
|
match fcx.tcx().region_maps.temporary_scope(e.id) {
|
||||||
Some(scope) => {
|
Some(scope) => {
|
||||||
ty::VstoreSlice(ty::ReScope(scope), m)
|
ty::VstoreSlice(ty::ReScope(scope))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// this slice occurs in a static somewhere
|
// this slice occurs in a static somewhere
|
||||||
ty::VstoreSlice(ty::ReStatic, m)
|
ty::VstoreSlice(ty::ReStatic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -928,11 +928,17 @@ fn constrain_index(rcx: &mut Rcx,
|
|||||||
|
|
||||||
let r_index_expr = ty::ReScope(index_expr.id);
|
let r_index_expr = ty::ReScope(index_expr.id);
|
||||||
match ty::get(indexed_ty).sty {
|
match ty::get(indexed_ty).sty {
|
||||||
ty::ty_str(ty::VstoreSlice(r_ptr, ())) |
|
ty::ty_str(ty::VstoreSlice(r_ptr)) => {
|
||||||
ty::ty_vec(_, ty::VstoreSlice(r_ptr, _)) => {
|
|
||||||
rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
|
rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
|
||||||
r_index_expr, r_ptr);
|
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);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,7 @@ pub fn relate_nested_regions(tcx: &ty::ctxt,
|
|||||||
|
|
||||||
fn fold_ty(&mut self, ty: ty::t) -> ty::t {
|
fn fold_ty(&mut self, ty: ty::t) -> ty::t {
|
||||||
match ty::get(ty).sty {
|
match ty::get(ty).sty {
|
||||||
ty::ty_rptr(r, ty::mt {ty, ..}) |
|
ty::ty_rptr(r, ty::mt {ty, ..}) => {
|
||||||
ty::ty_vec(ty, ty::VstoreSlice(r, _)) => {
|
|
||||||
self.relate(r);
|
self.relate(r);
|
||||||
self.stack.push(r);
|
self.stack.push(r);
|
||||||
ty_fold::super_fold_ty(self, ty);
|
ty_fold::super_fold_ty(self, ty);
|
||||||
|
@ -102,9 +102,19 @@ impl<'f> Coerce<'f> {
|
|||||||
// See above for details.
|
// See above for details.
|
||||||
match ty::get(b).sty {
|
match ty::get(b).sty {
|
||||||
ty::ty_rptr(_, mt_b) => {
|
ty::ty_rptr(_, mt_b) => {
|
||||||
return self.unpack_actual_value(a, |sty_a| {
|
match ty::get(mt_b.ty).sty {
|
||||||
self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
|
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(..)) => {
|
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(..), ..}) => {
|
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
|
||||||
return self.unpack_actual_value(a, |sty_a| {
|
return self.unpack_actual_value(a, |sty_a| {
|
||||||
self.coerce_borrowed_fn(a, sty_a, b)
|
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 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));
|
if_ok!(self.subtype(a_borrowed, b));
|
||||||
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
||||||
autoderefs: 0,
|
autoderefs: 0,
|
||||||
@ -287,14 +291,21 @@ impl<'f> Coerce<'f> {
|
|||||||
let sub = Sub(*self.get_ref());
|
let sub = Sub(*self.get_ref());
|
||||||
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
|
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
|
||||||
let ty_inner = match *sty_a {
|
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);
|
return self.subtype(a, b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let a_borrowed = ty::mk_vec(self.get_ref().infcx.tcx, ty_inner,
|
let a_borrowed = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow,
|
||||||
VstoreSlice(r_borrow, mutbl_b));
|
mt {ty: ty_inner, mutbl: mutbl_b});
|
||||||
if_ok!(sub.tys(a_borrowed, b));
|
if_ok!(sub.tys(a_borrowed, b));
|
||||||
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
||||||
autoderefs: 0,
|
autoderefs: 0,
|
||||||
|
@ -270,15 +270,15 @@ pub trait Combine {
|
|||||||
|
|
||||||
fn vstores(&self,
|
fn vstores(&self,
|
||||||
vk: ty::terr_vstore_kind,
|
vk: ty::terr_vstore_kind,
|
||||||
a: ty::Vstore<()>,
|
a: ty::Vstore,
|
||||||
b: ty::Vstore<()>)
|
b: ty::Vstore)
|
||||||
-> cres<ty::Vstore<()>> {
|
-> cres<ty::Vstore> {
|
||||||
debug!("{}.vstores(a={:?}, b={:?})", self.tag(), a, b);
|
debug!("{}.vstores(a={:?}, b={:?})", self.tag(), a, b);
|
||||||
|
|
||||||
match (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| {
|
self.contraregions(a_r, b_r).and_then(|r| {
|
||||||
Ok(ty::VstoreSlice(r, ()))
|
Ok(ty::VstoreSlice(r))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,48 +510,49 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
|
(&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)) => {
|
(&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)) => {
|
(&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 r = if_ok!(this.contraregions(a_r, b_r));
|
||||||
let mt = if_ok!(this.mts(a_mt, b_mt));
|
let mt = if_ok!(this.mts(a_mt, b_mt));
|
||||||
Ok(ty::mk_rptr(tcx, r, 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)) => {
|
(&ty::ty_vec(ref a_mt, sz_a), &ty::ty_vec(ref b_mt, sz_b)) => {
|
||||||
// This could be nicer if we didn't have to go through .mts(a, b).
|
this.mts(a_mt, b_mt).and_then(|mt| {
|
||||||
let (vs_a, mutbl_a) = match vs_a {
|
if sz_a == sz_b {
|
||||||
ty::VstoreFixed(n) => (ty::VstoreFixed(n), ast::MutImmutable),
|
Ok(ty::mk_vec(tcx, mt, sz_a))
|
||||||
ty::VstoreSlice(r, m) => (ty::VstoreSlice(r, ()), m),
|
} else {
|
||||||
ty::VstoreUniq => (ty::VstoreUniq, ast::MutImmutable)
|
Err(ty::terr_sorts(expected_found(this, a, b)))
|
||||||
};
|
}
|
||||||
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))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,16 +717,8 @@ impl<'a> ConstraintContext<'a> {
|
|||||||
self.add_constraints_from_vstore(vstore, variance);
|
self.add_constraints_from_vstore(vstore, variance);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_vec(ty, vstore) => {
|
ty::ty_vec(ref mt, _) => {
|
||||||
self.add_constraints_from_vstore(vstore, variance);
|
self.add_constraints_from_mt(mt, variance);
|
||||||
let mt = ty::mt {
|
|
||||||
ty: ty,
|
|
||||||
mutbl: match vstore {
|
|
||||||
ty::VstoreSlice(_, m) => m,
|
|
||||||
_ => ast::MutImmutable
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.add_constraints_from_mt(&mt, variance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_uniq(typ) | ty::ty_box(typ) => {
|
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`
|
/// Adds constraints appropriate for a vector with Vstore `vstore`
|
||||||
/// appearing in a context with ambient variance `variance`
|
/// appearing in a context with ambient variance `variance`
|
||||||
fn add_constraints_from_vstore<M>(&mut self,
|
fn add_constraints_from_vstore(&mut self,
|
||||||
vstore: ty::Vstore<M>,
|
vstore: ty::Vstore,
|
||||||
variance: VarianceTermPtr<'a>) {
|
variance: VarianceTermPtr<'a>) {
|
||||||
match vstore {
|
match vstore {
|
||||||
ty::VstoreSlice(r, _) => {
|
ty::VstoreSlice(r) => {
|
||||||
let contra = self.contravariant(variance);
|
let contra = self.contravariant(variance);
|
||||||
self.add_constraints_from_region(r, contra);
|
self.add_constraints_from_region(r, contra);
|
||||||
}
|
}
|
||||||
|
@ -395,23 +395,23 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
|
|||||||
let bound_str = bounds.repr(cx);
|
let bound_str = bounds.repr(cx);
|
||||||
format!("{}{}{}{}", trait_store_to_str(cx, store), ty, bound_sep, bound_str)
|
format!("{}{}{}{}", trait_store_to_str(cx, store), ty, bound_sep, bound_str)
|
||||||
}
|
}
|
||||||
ty_vec(ty, vs) => {
|
|
||||||
match vs {
|
|
||||||
ty::VstoreFixed(n) => {
|
|
||||||
format!("[{}, .. {}]", ty_to_str(cx, ty), n)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
format!("{}[{}]", vs.repr(cx), ty_to_str(cx, ty))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty_str(vs) => {
|
ty_str(vs) => {
|
||||||
match vs {
|
match vs {
|
||||||
ty::VstoreFixed(n) => format!("str/{}", n),
|
ty::VstoreFixed(n) => format!("str/{}", n),
|
||||||
ty::VstoreUniq => "~str".to_owned(),
|
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 {
|
match *self {
|
||||||
ty::VstoreFixed(n) => format!("{}", n),
|
ty::VstoreFixed(n) => format!("{}", n),
|
||||||
ty::VstoreUniq => "~".to_owned(),
|
ty::VstoreUniq => "~".to_owned(),
|
||||||
ty::VstoreSlice(r, m) => {
|
ty::VstoreSlice(r) => region_ptr_to_str(tcx, r)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user