Refactor ty_str to use a ~(str) representation.
Similar to my recent changes to ~[T]/&[T], these changes remove the vstore abstraction and represent str types as ~(str) and &(str). The Option<uint> in ty_str is the length of the string, None if the string is dynamically sized.
This commit is contained in:
parent
7a19a82d11
commit
c0ff3caae1
src
librustc
test/compile-fail
@ -138,23 +138,6 @@ pub fn parse_substs_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx:
|
||||
parse_substs(&mut st, conv)
|
||||
}
|
||||
|
||||
fn parse_vstore(st: &mut PState, conv: conv_did) -> ty::Vstore {
|
||||
assert_eq!(next(st), '/');
|
||||
|
||||
let c = peek(st);
|
||||
if '0' <= c && c <= '9' {
|
||||
let n = parse_uint(st);
|
||||
assert_eq!(next(st), '|');
|
||||
return ty::VstoreFixed(n);
|
||||
}
|
||||
|
||||
match next(st) {
|
||||
'~' => ty::VstoreUniq,
|
||||
'&' => ty::VstoreSlice(parse_region(st, conv)),
|
||||
c => st.tcx.sess.bug(format!("parse_vstore(): bad input '{}'", c))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_size(st: &mut PState) -> Option<uint> {
|
||||
assert_eq!(next(st), '/');
|
||||
|
||||
@ -361,8 +344,8 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
||||
return ty::mk_vec(st.tcx, mt, sz);
|
||||
}
|
||||
'v' => {
|
||||
let v = parse_vstore(st, |x,y| conv(x,y));
|
||||
return ty::mk_str(st.tcx, v);
|
||||
let sz = parse_size(st);
|
||||
return ty::mk_str(st.tcx, sz);
|
||||
}
|
||||
'T' => {
|
||||
assert_eq!(next(st), '[');
|
||||
|
@ -177,21 +177,6 @@ fn enc_bound_region(w: &mut MemWriter, cx: &ctxt, br: ty::BoundRegion) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enc_vstore(w: &mut MemWriter, cx: &ctxt,
|
||||
v: ty::Vstore,
|
||||
enc_mut: |&mut MemWriter|) {
|
||||
mywrite!(w, "/");
|
||||
match v {
|
||||
ty::VstoreFixed(u) => mywrite!(w, "{}|", u),
|
||||
ty::VstoreUniq => mywrite!(w, "~"),
|
||||
ty::VstoreSlice(r) => {
|
||||
mywrite!(w, "&");
|
||||
enc_region(w, cx, r);
|
||||
enc_mut(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enc_trait_ref(w: &mut MemWriter, cx: &ctxt, s: &ty::TraitRef) {
|
||||
mywrite!(w, "{}|", (cx.ds)(s.def_id));
|
||||
enc_substs(w, cx, &s.substs);
|
||||
@ -275,9 +260,13 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
|
||||
None => mywrite!(w, "|"),
|
||||
}
|
||||
}
|
||||
ty::ty_str(v) => {
|
||||
ty::ty_str(sz) => {
|
||||
mywrite!(w, "v");
|
||||
enc_vstore(w, cx, v, |_| {});
|
||||
mywrite!(w, "/");
|
||||
match sz {
|
||||
Some(n) => mywrite!(w, "{}|", n),
|
||||
None => mywrite!(w, "|"),
|
||||
}
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
mywrite!(w, "f");
|
||||
|
@ -405,6 +405,7 @@ fn missing_ctor(cx: &MatchCheckCtxt,
|
||||
ty::ty_struct(..) => check_matrix_for_wild(cx, m),
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty: ty, ..}) => match ty::get(ty).sty {
|
||||
ty::ty_vec(_, None) => ctor_for_slice(m),
|
||||
ty::ty_str(None) => Some(single),
|
||||
_ => check_matrix_for_wild(cx, m),
|
||||
},
|
||||
ty::ty_enum(eid, _) => {
|
||||
|
@ -68,6 +68,13 @@ impl<'a> EffectCheckVisitor<'a> {
|
||||
debug!("effect: checking index with base type {}",
|
||||
ppaux::ty_to_str(self.tcx, base_type));
|
||||
match ty::get(base_type).sty {
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
||||
ty::ty_str(None) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"modification of string types is not allowed");
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
ty::ty_str(..) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"modification of string types is not allowed");
|
||||
|
@ -911,7 +911,7 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
|
||||
ty::ty_box(_) => {
|
||||
n_box += 1;
|
||||
}
|
||||
ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_uniq(_) |
|
||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||
ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
|
||||
n_uniq += 1;
|
||||
|
@ -174,7 +174,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
match ty::get(t).sty {
|
||||
ty::ty_uniq(_) |
|
||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||
ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||
Some(deref_ptr(OwnedPtr))
|
||||
}
|
||||
@ -188,7 +187,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
Some(deref_ptr(BorrowedPtr(kind, r)))
|
||||
}
|
||||
|
||||
ty::ty_str(ty::VstoreSlice(r)) |
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(r, _), ..}) => {
|
||||
Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
|
||||
}
|
||||
@ -207,7 +205,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
}
|
||||
|
||||
ty::ty_vec(_, Some(_)) |
|
||||
ty::ty_str(ty::VstoreFixed(_)) => {
|
||||
ty::ty_str(Some(_)) => {
|
||||
Some(deref_interior(InteriorElement(element_kind(t))))
|
||||
}
|
||||
|
||||
@ -1306,6 +1304,7 @@ fn element_kind(t: ty::t) -> ElementKind {
|
||||
ty::ty_rptr(_, ty::mt{ty:ty, ..}) |
|
||||
ty::ty_uniq(ty) => match ty::get(ty).sty {
|
||||
ty::ty_vec(_, None) => VecElement,
|
||||
ty::ty_str(None) => StrElement,
|
||||
_ => OtherElement
|
||||
},
|
||||
ty::ty_vec(..) => VecElement,
|
||||
|
@ -1293,40 +1293,51 @@ fn compare_values<'a>(
|
||||
rhs: ValueRef,
|
||||
rhs_t: ty::t)
|
||||
-> Result<'a> {
|
||||
fn compare_str<'a>(cx: &'a Block<'a>,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
rhs_t: ty::t)
|
||||
-> Result<'a> {
|
||||
let did = langcall(cx, None,
|
||||
format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
|
||||
StrEqFnLangItem);
|
||||
let result = callee::trans_lang_call(cx, did, [lhs, rhs], None);
|
||||
Result {
|
||||
bcx: result.bcx,
|
||||
val: bool_to_i1(result.bcx, result.val)
|
||||
}
|
||||
}
|
||||
|
||||
let _icx = push_ctxt("compare_values");
|
||||
if ty::type_is_scalar(rhs_t) {
|
||||
let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq);
|
||||
return rslt(rs.bcx, rs.val);
|
||||
let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq);
|
||||
return rslt(rs.bcx, rs.val);
|
||||
}
|
||||
|
||||
match ty::get(rhs_t).sty {
|
||||
ty::ty_str(ty::VstoreUniq) => {
|
||||
let scratch_lhs = alloca(cx, val_ty(lhs), "__lhs");
|
||||
Store(cx, lhs, scratch_lhs);
|
||||
let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
|
||||
Store(cx, rhs, scratch_rhs);
|
||||
let did = langcall(cx, None,
|
||||
format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
|
||||
UniqStrEqFnLangItem);
|
||||
let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
|
||||
Result {
|
||||
bcx: result.bcx,
|
||||
val: bool_to_i1(result.bcx, result.val)
|
||||
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||
ty::ty_str(None) => {
|
||||
let scratch_lhs = alloca(cx, val_ty(lhs), "__lhs");
|
||||
Store(cx, lhs, scratch_lhs);
|
||||
let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
|
||||
Store(cx, rhs, scratch_rhs);
|
||||
let did = langcall(cx, None,
|
||||
format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
|
||||
UniqStrEqFnLangItem);
|
||||
let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
|
||||
Result {
|
||||
bcx: result.bcx,
|
||||
val: bool_to_i1(result.bcx, result.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_str(_) => {
|
||||
let did = langcall(cx, None,
|
||||
format!("comparison of `{}`", cx.ty_to_str(rhs_t)),
|
||||
StrEqFnLangItem);
|
||||
let result = callee::trans_lang_call(cx, did, [lhs, rhs], None);
|
||||
Result {
|
||||
bcx: result.bcx,
|
||||
val: bool_to_i1(result.bcx, result.val)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
cx.sess().bug("only scalars and strings supported in compare_values");
|
||||
}
|
||||
_ => cx.sess().bug("only scalars and strings supported in compare_values"),
|
||||
},
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_str(None) => compare_str(cx, lhs, rhs, rhs_t),
|
||||
_ => cx.sess().bug("only scalars and strings supported in compare_values"),
|
||||
},
|
||||
ty::ty_str(Some(_)) => compare_str(cx, lhs, rhs, rhs_t),
|
||||
_ => cx.sess().bug("only scalars and strings supported in compare_values"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,11 +270,10 @@ impl Case {
|
||||
self.tys.iter().position(|&ty| {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => false,
|
||||
ty::ty_vec(_, None) | ty::ty_str(None)=> false,
|
||||
_ => true,
|
||||
},
|
||||
ty::ty_uniq(..) | ty::ty_box(..) |
|
||||
ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_bare_fn(..) => true,
|
||||
// Is that everything? Would closures or slices qualify?
|
||||
_ => false
|
||||
|
@ -188,8 +188,8 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
|
||||
// `~` pointer return values never alias because ownership is transferred
|
||||
// FIXME #6750 ~Trait cannot be directly marked as
|
||||
// noalias because the actual object pointer is nested.
|
||||
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
||||
ty::ty_str(ty::VstoreUniq) => {
|
||||
ty::ty_uniq(..) // | ty::ty_trait(_, _, ty::UniqTraitStore, _, _)
|
||||
=> {
|
||||
unsafe {
|
||||
llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
|
||||
}
|
||||
@ -261,7 +261,6 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
|
||||
// FIXME #6750 ~Trait cannot be directly marked as
|
||||
// noalias because the actual object pointer is nested.
|
||||
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
||||
ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||
unsafe {
|
||||
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
|
||||
@ -665,7 +664,7 @@ pub fn iter_structural_ty<'r,
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::ty_str(ty::VstoreFixed(n)) => {
|
||||
ty::ty_str(Some(n)) => {
|
||||
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
|
||||
let (base, len) = tvec::get_fixed_base_and_byte_len(cx, av, unit_ty, n);
|
||||
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
|
||||
|
@ -659,9 +659,10 @@ pub fn trans_call_inner<'a>(
|
||||
match ty::get(ret_ty).sty {
|
||||
// `~` pointer return values never alias because ownership
|
||||
// is transferred
|
||||
ty::ty_uniq(..) => {
|
||||
attrs.push((0, NoAliasAttribute));
|
||||
}
|
||||
ty::ty_uniq(ty) => match ty::get(ty).sty {
|
||||
ty::ty_str(None) => {}
|
||||
_ => attrs.push((0, NoAliasAttribute)),
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
|
||||
let dv = match ty::get(t).sty {
|
||||
ty::ty_ptr(mt) | ty::ty_rptr(_, mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => cx.sess().bug("unexpected slice"),
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => cx.sess().bug("unexpected slice"),
|
||||
_ => const_deref_ptr(cx, v),
|
||||
}
|
||||
}
|
||||
@ -432,13 +432,9 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
"index is not an integer-constant expression")
|
||||
};
|
||||
let (arr, len) = match ty::get(bt).sty {
|
||||
ty::ty_str(ty::VstoreSlice(..)) => {
|
||||
let e1 = const_get_elt(cx, bv, [0]);
|
||||
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
|
||||
},
|
||||
ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)),
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => {
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => {
|
||||
let e1 = const_get_elt(cx, bv, [0]);
|
||||
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
|
||||
},
|
||||
@ -451,7 +447,17 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
|
||||
let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
|
||||
let len = match ty::get(bt).sty {
|
||||
ty::ty_str(..) => {assert!(len > 0); len - 1},
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
||||
ty::ty_str(None) => {
|
||||
assert!(len > 0);
|
||||
len - 1
|
||||
}
|
||||
_ => len
|
||||
},
|
||||
ty::ty_str(Some(_)) => {
|
||||
assert!(len > 0);
|
||||
len - 1
|
||||
},
|
||||
_ => len
|
||||
};
|
||||
if iv >= len {
|
||||
|
@ -2182,28 +2182,17 @@ fn type_metadata(cx: &CrateContext,
|
||||
ty::ty_uint(_) |
|
||||
ty::ty_float(_) => {
|
||||
basic_type_metadata(cx, t)
|
||||
},
|
||||
ty::ty_str(ref vstore) => {
|
||||
}
|
||||
ty::ty_str(Some(len)) => {
|
||||
let i8_t = ty::mk_i8();
|
||||
match *vstore {
|
||||
ty::VstoreFixed(len) => {
|
||||
fixed_vec_metadata(cx, i8_t, len, usage_site_span)
|
||||
},
|
||||
ty::VstoreUniq => {
|
||||
let vec_metadata = vec_metadata(cx, i8_t, usage_site_span);
|
||||
pointer_type_metadata(cx, t, vec_metadata)
|
||||
}
|
||||
ty::VstoreSlice(..) => {
|
||||
vec_slice_metadata(cx, t, i8_t, usage_site_span)
|
||||
}
|
||||
}
|
||||
},
|
||||
fixed_vec_metadata(cx, i8_t, len, usage_site_span)
|
||||
}
|
||||
ty::ty_enum(def_id, _) => {
|
||||
prepare_enum_metadata(cx, t, def_id, usage_site_span).finalize(cx)
|
||||
},
|
||||
}
|
||||
ty::ty_box(typ) => {
|
||||
create_pointer_to_box_metadata(cx, t, typ)
|
||||
},
|
||||
}
|
||||
ty::ty_vec(ref mt, Some(len)) => fixed_vec_metadata(cx, mt.ty, len, usage_site_span),
|
||||
ty::ty_uniq(typ) => {
|
||||
match ty::get(typ).sty {
|
||||
@ -2211,6 +2200,11 @@ fn type_metadata(cx: &CrateContext,
|
||||
let vec_metadata = vec_metadata(cx, mt.ty, usage_site_span);
|
||||
pointer_type_metadata(cx, t, vec_metadata)
|
||||
}
|
||||
ty::ty_str(None) => {
|
||||
let i8_t = ty::mk_i8();
|
||||
let vec_metadata = vec_metadata(cx, i8_t, usage_site_span);
|
||||
pointer_type_metadata(cx, t, vec_metadata)
|
||||
}
|
||||
_ => {
|
||||
let pointee = type_metadata(cx, typ, usage_site_span);
|
||||
pointer_type_metadata(cx, t, pointee)
|
||||
@ -2220,21 +2214,25 @@ fn type_metadata(cx: &CrateContext,
|
||||
ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(ref mt, None) => vec_slice_metadata(cx, t, mt.ty, usage_site_span),
|
||||
ty::ty_str(None) => {
|
||||
let i8_t = ty::mk_i8();
|
||||
vec_slice_metadata(cx, t, i8_t, usage_site_span)
|
||||
}
|
||||
_ => {
|
||||
let pointee = type_metadata(cx, mt.ty, usage_site_span);
|
||||
pointer_type_metadata(cx, t, pointee)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
ty::ty_bare_fn(ref barefnty) => {
|
||||
subroutine_type_metadata(cx, &barefnty.sig, usage_site_span)
|
||||
},
|
||||
}
|
||||
ty::ty_closure(ref closurety) => {
|
||||
subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
|
||||
},
|
||||
}
|
||||
ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, ref bounds }) => {
|
||||
trait_metadata(cx, def_id, t, substs, store, bounds)
|
||||
},
|
||||
}
|
||||
ty::ty_struct(def_id, ref substs) => {
|
||||
if ty::type_is_simd(cx.tcx(), t) {
|
||||
let element_type = ty::simd_type(cx.tcx(), t);
|
||||
@ -2243,7 +2241,7 @@ fn type_metadata(cx: &CrateContext,
|
||||
} else {
|
||||
prepare_struct_metadata(cx, t, def_id, substs, usage_site_span).finalize(cx)
|
||||
}
|
||||
},
|
||||
}
|
||||
ty::ty_tup(ref elements) => {
|
||||
prepare_tuple_metadata(cx,
|
||||
t,
|
||||
|
@ -1507,7 +1507,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind {
|
||||
ty::ty_float(..) => cast_float,
|
||||
ty::ty_ptr(..) => cast_pointer,
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty{
|
||||
ty::ty_vec(_, None) => cast_other,
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => cast_other,
|
||||
_ => cast_pointer,
|
||||
},
|
||||
ty::ty_bare_fn(..) => cast_pointer,
|
||||
@ -1717,7 +1717,8 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
|
||||
let r = match ty::get(datum.ty).sty {
|
||||
ty::ty_uniq(content_ty) => {
|
||||
match ty::get(content_ty).sty {
|
||||
ty::ty_vec(_, None) => bcx.tcx().sess.span_bug(expr.span, "unexpected ~[T]"),
|
||||
ty::ty_vec(_, None) | ty::ty_str(None)
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected ~[T]"),
|
||||
_ => deref_owned_pointer(bcx, expr, datum, content_ty),
|
||||
}
|
||||
}
|
||||
@ -1734,7 +1735,8 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
|
||||
ty::ty_ptr(ty::mt { ty: content_ty, .. }) |
|
||||
ty::ty_rptr(_, ty::mt { ty: content_ty, .. }) => {
|
||||
match ty::get(content_ty).sty {
|
||||
ty::ty_vec(_, None) => bcx.tcx().sess.span_bug(expr.span, "unexpected &[T]"),
|
||||
ty::ty_vec(_, None) | ty::ty_str(None)
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected &[T]"),
|
||||
_ => {
|
||||
assert!(!ty::type_needs_drop(bcx.tcx(), datum.ty));
|
||||
|
||||
|
@ -84,7 +84,7 @@ fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
|
||||
|
||||
ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ) => {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(_, None) => t,
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => t,
|
||||
_ => {
|
||||
let llty = sizing_type_of(ccx, typ);
|
||||
// Unique boxes do not allocate for zero-size types. The standard
|
||||
@ -288,6 +288,13 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
trans_exchange_free(bcx, llbox)
|
||||
})
|
||||
}
|
||||
ty::ty_str(None) => {
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
|
||||
let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, unit_ty);
|
||||
trans_exchange_free(bcx, llbox)
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = drop_ty(bcx, llbox, content_ty);
|
||||
@ -296,15 +303,6 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_str(ty::VstoreUniq) => {
|
||||
let llbox = Load(bcx, v0);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
|
||||
let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, unit_ty);
|
||||
trans_exchange_free(bcx, llbox)
|
||||
})
|
||||
}
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
let tcx = bcx.tcx();
|
||||
match ty::ty_dtor(tcx, did) {
|
||||
|
@ -55,8 +55,7 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
// We're careful to not use first class aggregates here because that
|
||||
// will kick us off fast isel. (Issue #4352.)
|
||||
let bcx = self.bcx;
|
||||
let str_vstore = ty::VstoreSlice(ty::ReStatic);
|
||||
let str_ty = ty::mk_str(bcx.tcx(), str_vstore);
|
||||
let str_ty = ty::mk_str_slice(bcx.tcx(), ty::ReStatic, ast::MutImmutable);
|
||||
let scratch = rvalue_scratch_datum(bcx, str_ty, "");
|
||||
let len = C_uint(bcx.ccx(), s.get().len());
|
||||
let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s, false), Type::i8p(bcx.ccx()));
|
||||
@ -122,20 +121,6 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
self.visit("leave_" + bracket_name, extra);
|
||||
}
|
||||
|
||||
pub fn vstore_name_and_extra(&mut self,
|
||||
t: ty::t,
|
||||
vstore: ty::Vstore)
|
||||
-> (~str, Vec<ValueRef> ) {
|
||||
match vstore {
|
||||
ty::VstoreFixed(n) => {
|
||||
let extra = (vec!(self.c_uint(n))).append(self.c_size_and_align(t).as_slice());
|
||||
("fixed".to_owned(), extra)
|
||||
}
|
||||
ty::VstoreSlice(..) => ("slice".to_owned(), Vec::new()),
|
||||
ty::VstoreUniq => ("uniq".to_owned(), Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn leaf(&mut self, name: &str) {
|
||||
self.visit(name, []);
|
||||
}
|
||||
@ -166,16 +151,16 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
ty::ty_float(ast::TyF128) => self.leaf("f128"),
|
||||
|
||||
// Should rename to str_*/vec_*.
|
||||
ty::ty_str(vst) => {
|
||||
let (name, extra) = self.vstore_name_and_extra(t, vst);
|
||||
self.visit("estr_".to_owned() + name, extra.as_slice())
|
||||
ty::ty_str(Some(n)) => {
|
||||
let extra = (vec!(self.c_uint(n))).append(self.c_size_and_align(t).as_slice());
|
||||
self.visit("estr_fixed".to_owned(), extra.as_slice())
|
||||
}
|
||||
ty::ty_vec(ref mt, Some(sz)) => {
|
||||
let extra = (vec!(self.c_uint(sz))).append(self.c_size_and_align(t).as_slice());
|
||||
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||
self.visit("evec_fixed".to_owned(), extra.as_slice())
|
||||
}
|
||||
ty::ty_vec(..) => fail!("unexpected unsized vec"),
|
||||
ty::ty_vec(..) | ty::ty_str(..) => fail!("unexpected unsized type"),
|
||||
// Should remove mt from box and uniq.
|
||||
ty::ty_box(typ) => {
|
||||
let extra = self.c_mt(&ty::mt {
|
||||
@ -187,10 +172,11 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
ty::ty_uniq(typ) => {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(ref mt, None) => {
|
||||
let (name, extra) = (~"uniq", Vec::new());
|
||||
let extra = Vec::new();
|
||||
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||
self.visit(~"evec_" + name, extra.as_slice())
|
||||
self.visit("evec_uniq".to_owned(), extra.as_slice())
|
||||
}
|
||||
ty::ty_str(None) => self.visit("estr_uniq".to_owned(), &[]),
|
||||
_ => {
|
||||
let extra = self.c_mt(&ty::mt {
|
||||
ty: typ,
|
||||
@ -211,6 +197,7 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||
self.visit(~"evec_" + name, extra.as_slice())
|
||||
}
|
||||
ty::ty_str(None) => self.visit("estr_slice".to_owned(), &[]),
|
||||
_ => {
|
||||
let extra = self.c_mt(mt);
|
||||
self.visit("rptr", extra.as_slice())
|
||||
|
@ -244,7 +244,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
|
||||
let llptrval = C_cstr(ccx, (*s).clone(), false);
|
||||
let llptrval = PointerCast(bcx, llptrval, Type::i8p(ccx));
|
||||
let llsizeval = C_uint(ccx, s.get().len());
|
||||
let typ = ty::mk_str(bcx.tcx(), ty::VstoreUniq);
|
||||
let typ = ty::mk_uniq(bcx.tcx(), ty::mk_str(bcx.tcx(), None));
|
||||
let lldestval = rvalue_scratch_datum(bcx,
|
||||
typ,
|
||||
"");
|
||||
@ -463,35 +463,6 @@ pub fn get_fixed_base_and_byte_len(bcx: &Block,
|
||||
(base, len)
|
||||
}
|
||||
|
||||
pub fn get_base_and_byte_len_for_vec(bcx: &Block,
|
||||
llval: ValueRef,
|
||||
vec_ty: ty::t)
|
||||
-> (ValueRef, ValueRef) {
|
||||
/*!
|
||||
* Converts a vector into the slice pair. The vector should be
|
||||
* stored in `llval` which should be by ref. If you have a datum,
|
||||
* you would probably prefer to call
|
||||
* `Datum::get_base_and_byte_len()`.
|
||||
*/
|
||||
|
||||
let ccx = bcx.ccx();
|
||||
let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
|
||||
|
||||
let size = match ty::get(vec_ty).sty {
|
||||
ty::ty_vec(_, size) => size,
|
||||
_ => ccx.sess().bug("non-vector in get_base_and_byte_len_for_vec"),
|
||||
};
|
||||
|
||||
match size {
|
||||
Some(n) => {
|
||||
let base = GEPi(bcx, llval, [0u, 0u]);
|
||||
let len = Mul(bcx, C_uint(ccx, n), vt.llunit_size);
|
||||
(base, len)
|
||||
}
|
||||
None => ccx.sess().bug("unsized vector in get_base_and_byte_len_for_vec")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_base_and_len(bcx: &Block,
|
||||
llval: ValueRef,
|
||||
vec_ty: ty::t)
|
||||
@ -505,38 +476,32 @@ pub fn get_base_and_len(bcx: &Block,
|
||||
*/
|
||||
|
||||
let ccx = bcx.ccx();
|
||||
let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
|
||||
|
||||
let vstore = match ty::get(vec_ty).sty {
|
||||
ty::ty_str(vst) => vst,
|
||||
ty::ty_vec(_, Some(n)) => ty::VstoreFixed(n),
|
||||
ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => ty::VstoreSlice(r),
|
||||
_ => ccx.sess().bug("unexpected type (ty_rptr) in get_base_and_len"),
|
||||
},
|
||||
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||
ty::ty_vec(_, None) => ty::VstoreUniq,
|
||||
_ => ccx.sess().bug("unexpected type (ty_uniq) in get_base_and_len"),
|
||||
},
|
||||
_ => ccx.sess().bug("unexpected type in get_base_and_len"),
|
||||
};
|
||||
|
||||
match vstore {
|
||||
ty::VstoreFixed(n) => {
|
||||
match ty::get(vec_ty).sty {
|
||||
ty::ty_str(Some(n)) |
|
||||
ty::ty_vec(_, Some(n)) => {
|
||||
let base = GEPi(bcx, llval, [0u, 0u]);
|
||||
(base, C_uint(ccx, n))
|
||||
}
|
||||
ty::VstoreSlice(..) => {
|
||||
assert!(!type_is_immediate(bcx.ccx(), vec_ty));
|
||||
let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
|
||||
let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
|
||||
(base, count)
|
||||
}
|
||||
ty::VstoreUniq => {
|
||||
assert!(type_is_immediate(bcx.ccx(), vec_ty));
|
||||
let body = Load(bcx, llval);
|
||||
(get_dataptr(bcx, body), UDiv(bcx, get_fill(bcx, body), vt.llunit_size))
|
||||
}
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => {
|
||||
assert!(!type_is_immediate(bcx.ccx(), vec_ty));
|
||||
let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
|
||||
let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
|
||||
(base, count)
|
||||
}
|
||||
_ => ccx.sess().bug("unexpected type (ty_rptr) in get_base_and_len"),
|
||||
},
|
||||
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => {
|
||||
assert!(type_is_immediate(bcx.ccx(), vec_ty));
|
||||
let vt = vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));
|
||||
let body = Load(bcx, llval);
|
||||
(get_dataptr(bcx, body), UDiv(bcx, get_fill(bcx, body), vt.llunit_size))
|
||||
}
|
||||
_ => ccx.sess().bug("unexpected type (ty_uniq) in get_base_and_len"),
|
||||
},
|
||||
_ => ccx.sess().bug("unexpected type in get_base_and_len"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,26 +116,23 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
ty::ty_uint(t) => Type::uint_from_ty(cx, t),
|
||||
ty::ty_float(t) => Type::float_from_ty(cx, t),
|
||||
|
||||
ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_box(..) |
|
||||
ty::ty_uniq(..) |
|
||||
ty::ty_ptr(..) => Type::i8p(cx),
|
||||
ty::ty_rptr(_, mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false),
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => {
|
||||
Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
|
||||
}
|
||||
_ => Type::i8p(cx),
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_str(ty::VstoreSlice(..)) => {
|
||||
Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
|
||||
}
|
||||
|
||||
ty::ty_bare_fn(..) => Type::i8p(cx),
|
||||
ty::ty_closure(..) => Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false),
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
|
||||
ty::ty_str(ty::VstoreFixed(size)) => Type::array(&Type::i8(cx), size as u64),
|
||||
ty::ty_str(Some(size)) => Type::array(&Type::i8(cx), size as u64),
|
||||
ty::ty_vec(mt, Some(size)) => {
|
||||
Type::array(&sizing_type_of(cx, mt.ty), size as u64)
|
||||
}
|
||||
@ -157,7 +154,7 @@ 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_vec(_, None) => {
|
||||
ty::ty_err(..) | ty::ty_vec(_, None) | ty::ty_str(None) => {
|
||||
cx.sess().bug(format!("fictitious type {:?} in sizing_type_of()",
|
||||
ty::get(t).sty))
|
||||
}
|
||||
@ -203,9 +200,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
ty::ty_int(t) => Type::int_from_ty(cx, t),
|
||||
ty::ty_uint(t) => Type::uint_from_ty(cx, t),
|
||||
ty::ty_float(t) => Type::float_from_ty(cx, t),
|
||||
ty::ty_str(ty::VstoreUniq) => {
|
||||
Type::vec(cx, &Type::i8(cx)).ptr_to()
|
||||
}
|
||||
ty::ty_enum(did, ref substs) => {
|
||||
// Only create the named struct, but don't fill it in. We
|
||||
// fill it in *after* placing it into the type cache. This
|
||||
@ -221,6 +215,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
ty::ty_uniq(typ) => {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(mt, None) => Type::vec(cx, &type_of(cx, mt.ty)).ptr_to(),
|
||||
ty::ty_str(None) => Type::vec(cx, &Type::i8(cx)).ptr_to(),
|
||||
_ => type_of(cx, typ).ptr_to(),
|
||||
}
|
||||
}
|
||||
@ -232,16 +227,15 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
let u_ty = Type::uint_from_ty(cx, ast::TyU);
|
||||
Type::struct_(cx, [p_ty, u_ty], false)
|
||||
}
|
||||
ty::ty_str(None) => {
|
||||
// This means we get a nicer name in the output
|
||||
cx.tn.find_type("str_slice").unwrap()
|
||||
}
|
||||
_ => type_of(cx, mt.ty).ptr_to(),
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_str(ty::VstoreSlice(..)) => {
|
||||
// This means we get a nicer name in the output
|
||||
cx.tn.find_type("str_slice").unwrap()
|
||||
}
|
||||
|
||||
ty::ty_str(ty::VstoreFixed(n)) => {
|
||||
ty::ty_str(Some(n)) => {
|
||||
Type::array(&Type::i8(cx), (n + 1u) as u64)
|
||||
}
|
||||
|
||||
@ -279,7 +273,8 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_vec(_, None) => cx.sess().bug("type_of with unszied ty_vec"),
|
||||
ty::ty_vec(_, None) => cx.sess().bug("type_of with unsized ty_vec"),
|
||||
ty::ty_str(None) => cx.sess().bug("type_of with unsized ty_str"),
|
||||
ty::ty_self(..) => cx.sess().unimpl("type_of with ty_self"),
|
||||
ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
|
||||
ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
|
||||
|
@ -124,17 +124,6 @@ pub struct mt {
|
||||
pub mutbl: ast::Mutability,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
|
||||
/// Describes the "storage mode" of a str, whether it's fixed length or a slice.
|
||||
pub enum Vstore {
|
||||
/// [T, ..N]
|
||||
VstoreFixed(uint),
|
||||
/// ~[T]
|
||||
VstoreUniq,
|
||||
/// &[T] and &mut [T]
|
||||
VstoreSlice(Region)
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
|
||||
pub enum TraitStore {
|
||||
/// ~Trait
|
||||
@ -737,7 +726,8 @@ pub enum sty {
|
||||
ty_enum(DefId, substs),
|
||||
ty_box(t),
|
||||
ty_uniq(t),
|
||||
ty_str(Vstore),
|
||||
// ty_str and ty_vec have an optional length.
|
||||
ty_str(Option<uint>),
|
||||
ty_vec(mt, Option<uint>),
|
||||
ty_ptr(mt),
|
||||
ty_rptr(Region, mt),
|
||||
@ -815,7 +805,6 @@ pub enum type_err {
|
||||
terr_regions_no_overlap(Region, Region),
|
||||
terr_regions_insufficiently_polymorphic(BoundRegion, Region),
|
||||
terr_regions_overly_polymorphic(BoundRegion, Region),
|
||||
terr_vstores_differ(terr_vstore_kind, expected_found<Vstore>),
|
||||
terr_trait_stores_differ(terr_vstore_kind, expected_found<TraitStore>),
|
||||
terr_sorts(expected_found<t>),
|
||||
terr_integer_as_char,
|
||||
@ -1185,9 +1174,6 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
||||
return f;
|
||||
}
|
||||
match &st {
|
||||
&ty_str(VstoreSlice(r)) => {
|
||||
flags |= rflags(r);
|
||||
}
|
||||
&ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
|
||||
&ty_str(_) => {}
|
||||
// You might think that we could just return ty_err for
|
||||
@ -1355,8 +1341,16 @@ pub fn mk_mach_float(tm: ast::FloatTy) -> t {
|
||||
#[inline]
|
||||
pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) }
|
||||
|
||||
pub fn mk_str(cx: &ctxt, v: Vstore) -> t {
|
||||
mk_t(cx, ty_str(v))
|
||||
pub fn mk_str(cx: &ctxt, sz: Option<uint>) -> t {
|
||||
mk_t(cx, ty_str(sz))
|
||||
}
|
||||
|
||||
pub fn mk_str_slice(cx: &ctxt, r: Region, m: ast::Mutability) -> t {
|
||||
mk_rptr(cx, r,
|
||||
mt {
|
||||
ty: mk_t(cx, ty_str(None)),
|
||||
mutbl: m
|
||||
})
|
||||
}
|
||||
|
||||
pub fn mk_enum(cx: &ctxt, did: ast::DefId, substs: substs) -> t {
|
||||
@ -1618,7 +1612,7 @@ 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,
|
||||
ty_vec(_, None) | ty_str(None) => true,
|
||||
_ => false,
|
||||
},
|
||||
_ => false
|
||||
@ -1629,8 +1623,7 @@ pub fn type_is_structural(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
|
||||
ty_vec(_, Some(_)) |
|
||||
ty_str(VstoreFixed(_)) | ty_str(VstoreSlice(_))
|
||||
=> true,
|
||||
ty_str(Some(_)) => true,
|
||||
_ => type_is_slice(ty)
|
||||
}
|
||||
}
|
||||
@ -1644,11 +1637,12 @@ pub fn type_is_simd(cx: &ctxt, ty: t) -> bool {
|
||||
|
||||
pub fn sequence_element_type(cx: &ctxt, ty: t) -> t {
|
||||
match get(ty).sty {
|
||||
ty_str(_) => mk_mach_uint(ast::TyU8),
|
||||
ty_vec(mt, _) => mt.ty,
|
||||
ty_str(Some(_)) => mk_mach_uint(ast::TyU8),
|
||||
ty_vec(mt, Some(_)) => 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,
|
||||
ty_str(None) => mk_mach_uint(ast::TyU8),
|
||||
_ => cx.sess.bug("sequence_element_type called on non-sequence value"),
|
||||
},
|
||||
_ => cx.sess.bug("sequence_element_type called on non-sequence value"),
|
||||
@ -1687,7 +1681,7 @@ pub fn type_is_region_ptr(ty: t) -> bool {
|
||||
ty_rptr(_, mt) => match get(mt.ty).sty {
|
||||
// FIXME(nrc, DST) slices weren't regarded as rptrs, so we preserve this
|
||||
// odd behaviour for now. (But ~[] were unique. I have no idea why).
|
||||
ty_vec(_, None) => false,
|
||||
ty_vec(_, None) | ty_str(None) => false,
|
||||
_ => true
|
||||
},
|
||||
_ => false
|
||||
@ -1703,7 +1697,7 @@ pub fn type_is_unsafe_ptr(ty: t) -> bool {
|
||||
|
||||
pub fn type_is_unique(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_uniq(_) | ty_str(VstoreUniq) => true,
|
||||
ty_uniq(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -1776,8 +1770,7 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t,
|
||||
}
|
||||
!needs_unwind_cleanup
|
||||
}
|
||||
ty_uniq(_) |
|
||||
ty_str(VstoreUniq) => {
|
||||
ty_uniq(_) => {
|
||||
// Once we're inside a box, the annihilator will find
|
||||
// it and destroy it.
|
||||
if !encountered_box {
|
||||
@ -2090,10 +2083,6 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
TC::None
|
||||
}
|
||||
|
||||
ty_str(VstoreUniq) => {
|
||||
TC::OwnsOwned
|
||||
}
|
||||
|
||||
ty_closure(ref c) => {
|
||||
closure_contents(cx, *c)
|
||||
}
|
||||
@ -2103,7 +2092,10 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
ty_uniq(typ) => {
|
||||
tc_ty(cx, typ, cache).owned_pointer()
|
||||
match get(typ).sty {
|
||||
ty_str(None) => TC::OwnsOwned,
|
||||
_ => tc_ty(cx, typ, cache).owned_pointer(),
|
||||
}
|
||||
}
|
||||
|
||||
ty_trait(~ty::TyTrait { store, bounds, .. }) => {
|
||||
@ -2115,19 +2107,17 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
ty_rptr(r, ref mt) => {
|
||||
tc_ty(cx, mt.ty, cache).reference(
|
||||
borrowed_contents(r, mt.mutbl))
|
||||
match get(mt.ty).sty {
|
||||
ty_str(None) => borrowed_contents(r, ast::MutImmutable),
|
||||
_ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(r, mt.mutbl)),
|
||||
}
|
||||
}
|
||||
|
||||
ty_vec(mt, _) => {
|
||||
tc_mt(cx, mt, cache)
|
||||
}
|
||||
|
||||
ty_str(VstoreSlice(r)) => {
|
||||
borrowed_contents(r, ast::MutImmutable)
|
||||
}
|
||||
|
||||
ty_str(VstoreFixed(_)) => {
|
||||
ty_str(_) => {
|
||||
TC::None
|
||||
}
|
||||
|
||||
@ -2622,7 +2612,7 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
|
||||
match get(t).sty {
|
||||
ty_box(typ) | ty_uniq(typ) => match get(typ).sty {
|
||||
// Don't deref ~[] etc., might need to generalise this to all DST.
|
||||
ty_vec(_, None) => None,
|
||||
ty_vec(_, None) | ty_str(None) => None,
|
||||
_ => Some(mt {
|
||||
ty: typ,
|
||||
mutbl: ast::MutImmutable,
|
||||
@ -2630,7 +2620,7 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
|
||||
},
|
||||
ty_rptr(_, mt) => match get(mt.ty).sty {
|
||||
// Don't deref &[], might need to generalise this to all DST.
|
||||
ty_vec(_, None) => None,
|
||||
ty_vec(_, None) | ty_str(None) => None,
|
||||
_ => Some(mt),
|
||||
},
|
||||
ty_ptr(mt) if explicit => Some(mt),
|
||||
@ -2641,13 +2631,14 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
|
||||
// Returns the type of t[i]
|
||||
pub fn index(t: t) -> Option<mt> {
|
||||
match get(t).sty {
|
||||
ty_vec(mt, _) => Some(mt),
|
||||
ty_vec(mt, Some(_)) => Some(mt),
|
||||
ty_ptr(mt{ty: t, ..}) | ty_rptr(_, mt{ty: t, ..}) |
|
||||
ty_box(t) | ty_uniq(t) => match get(t).sty {
|
||||
ty_vec(mt, None) => Some(mt),
|
||||
ty_str(None) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}),
|
||||
_ => None,
|
||||
},
|
||||
ty_str(_) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}),
|
||||
ty_str(Some(_)) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
@ -2752,7 +2743,6 @@ pub fn ty_region(tcx: &ctxt,
|
||||
ty: t) -> Region {
|
||||
match get(ty).sty {
|
||||
ty_rptr(r, _) => r,
|
||||
ty_str(VstoreSlice(r)) => r,
|
||||
ref s => {
|
||||
tcx.sess.span_bug(
|
||||
span,
|
||||
@ -2949,33 +2939,29 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
None => unadjusted_ty
|
||||
};
|
||||
|
||||
fn borrow_vec(cx: &ctxt, span: Span,
|
||||
r: Region, m: ast::Mutability,
|
||||
fn borrow_vec(cx: &ctxt,
|
||||
span: Span,
|
||||
r: Region,
|
||||
m: ast::Mutability,
|
||||
ty: ty::t) -> ty::t {
|
||||
match get(ty).sty {
|
||||
ty_uniq(t) | ty_ptr(mt{ty: t, ..}) |
|
||||
ty_rptr(_, mt{ty: t, ..}) => match get(t).sty {
|
||||
ty::ty_vec(mt, None) => ty::mk_slice(cx, r, ty::mt {ty: mt.ty, mutbl: m}),
|
||||
ref s => {
|
||||
ty::ty_str(None) => ty::mk_str_slice(cx, r, m),
|
||||
_ => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
format!("borrow-vec associated with bad sty: {:?}",
|
||||
s));
|
||||
format!("borrow-vec associated with bad sty: {:?}", get(ty).sty));
|
||||
}
|
||||
},
|
||||
ty_vec(mt, Some(_)) => {
|
||||
ty::mk_slice(cx, r, ty::mt {ty: mt.ty, mutbl: m})
|
||||
}
|
||||
|
||||
ty_str(_) => {
|
||||
ty::mk_str(cx, VstoreSlice(r))
|
||||
}
|
||||
ty_vec(mt, Some(_)) => ty::mk_slice(cx, r, ty::mt {ty: mt.ty, mutbl: m}),
|
||||
ty_str(Some(_)) => ty::mk_str_slice(cx, r, m),
|
||||
|
||||
ref s => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
format!("borrow-vec associated with bad sty: {:?}",
|
||||
s));
|
||||
format!("borrow-vec associated with bad sty: {:?}", s));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3310,15 +3296,6 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
|
||||
* to present additional details, particularly when
|
||||
* it comes to lifetime-related errors. */
|
||||
|
||||
fn terr_vstore_kind_to_str(k: terr_vstore_kind) -> ~str {
|
||||
match k {
|
||||
terr_vec => "[]".to_owned(),
|
||||
terr_str => "str".to_owned(),
|
||||
terr_fn => "fn".to_owned(),
|
||||
terr_trait => "trait".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn tstore_to_closure(s: &TraitStore) -> ~str {
|
||||
match s {
|
||||
&UniqTraitStore => "proc".to_owned(),
|
||||
@ -3394,12 +3371,6 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
|
||||
but found bound lifetime parameter {}",
|
||||
bound_region_ptr_to_str(cx, br))
|
||||
}
|
||||
terr_vstores_differ(k, ref values) => {
|
||||
format!("{} storage differs: expected `{}` but found `{}`",
|
||||
terr_vstore_kind_to_str(k),
|
||||
(*values).expected.repr(cx),
|
||||
(*values).found.repr(cx))
|
||||
}
|
||||
terr_trait_stores_differ(_, ref values) => {
|
||||
format!("trait storage differs: expected `{}` but found `{}`",
|
||||
trait_store_to_str(cx, (*values).expected),
|
||||
@ -4168,13 +4139,6 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t {
|
||||
return t_norm;
|
||||
}
|
||||
|
||||
fn fold_vstore(&mut self, vstore: Vstore) -> Vstore {
|
||||
match vstore {
|
||||
VstoreFixed(..) | VstoreUniq => vstore,
|
||||
VstoreSlice(_) => VstoreSlice(ReStatic)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, _: ty::Region) -> ty::Region {
|
||||
ty::ReStatic
|
||||
}
|
||||
@ -4564,9 +4528,13 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
|
||||
byte!(6);
|
||||
hash!(f);
|
||||
}
|
||||
ty_str(v) => {
|
||||
ty_str(Some(_)) => {
|
||||
byte!(7);
|
||||
hash!(v);
|
||||
1u8.hash(&mut state);
|
||||
}
|
||||
ty_str(None) => {
|
||||
byte!(7);
|
||||
0u8.hash(&mut state);
|
||||
}
|
||||
ty_enum(d, _) => {
|
||||
byte!(8);
|
||||
|
@ -68,10 +68,6 @@ pub trait TypeFolder {
|
||||
r
|
||||
}
|
||||
|
||||
fn fold_vstore(&mut self, vstore: ty::Vstore) -> ty::Vstore {
|
||||
super_fold_vstore(self, vstore)
|
||||
}
|
||||
|
||||
fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore {
|
||||
super_fold_trait_store(self, s)
|
||||
}
|
||||
@ -179,8 +175,8 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
|
||||
ty::ty_struct(did,
|
||||
this.fold_substs(substs))
|
||||
}
|
||||
ty::ty_str(vst) => {
|
||||
ty::ty_str(this.fold_vstore(vst))
|
||||
ty::ty_str(sz) => {
|
||||
ty::ty_str(sz)
|
||||
}
|
||||
ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char |
|
||||
ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
|
||||
@ -191,16 +187,6 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_fold_vstore<T:TypeFolder>(this: &mut T,
|
||||
vstore: ty::Vstore)
|
||||
-> ty::Vstore {
|
||||
match vstore {
|
||||
ty::VstoreFixed(i) => ty::VstoreFixed(i),
|
||||
ty::VstoreUniq => ty::VstoreUniq,
|
||||
ty::VstoreSlice(r) => ty::VstoreSlice(this.fold_region(r)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
|
||||
trait_store: ty::TraitStore)
|
||||
-> ty::TraitStore {
|
||||
|
@ -355,7 +355,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
|
||||
tcx.sess.span_err(ast_ty.span,
|
||||
"bare `str` is not a type");
|
||||
// return /something/ so they can at least get more errors
|
||||
Some(ty::mk_str(tcx, ty::VstoreUniq))
|
||||
Some(ty::mk_uniq(tcx, ty::mk_str(tcx, None)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,19 +373,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
|
||||
enum PointerTy {
|
||||
Box,
|
||||
VStore(ty::Vstore)
|
||||
}
|
||||
impl PointerTy {
|
||||
fn expect_vstore(&self, tcx: &ty::ctxt, span: Span, ty: &str) -> ty::Vstore {
|
||||
match *self {
|
||||
Box => {
|
||||
tcx.sess.span_err(span, format!("managed {} are not supported", ty));
|
||||
// everything can be ~, so this is a worth substitute
|
||||
ty::VstoreUniq
|
||||
}
|
||||
VStore(vst) => vst
|
||||
}
|
||||
}
|
||||
RPtr(ty::Region),
|
||||
Uniq
|
||||
}
|
||||
|
||||
fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
|
||||
@ -423,23 +412,23 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
match tcx.def_map.borrow().find(&id) {
|
||||
Some(&ast::DefPrimTy(ast::TyStr)) => {
|
||||
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
|
||||
let vst = ptr_ty.expect_vstore(tcx, path.span, "strings");
|
||||
match vst {
|
||||
ty::VstoreUniq => {
|
||||
return ty::mk_str(tcx, ty::VstoreUniq);
|
||||
match ptr_ty {
|
||||
Uniq => {
|
||||
return ty::mk_uniq(tcx, ty::mk_str(tcx, None));
|
||||
}
|
||||
ty::VstoreSlice(r) => {
|
||||
return ty::mk_str(tcx, ty::VstoreSlice(r));
|
||||
RPtr(r) => {
|
||||
return ty::mk_str_slice(tcx, r, ast::MutImmutable);
|
||||
}
|
||||
_ => {}
|
||||
_ => tcx.sess.span_err(path.span,
|
||||
format!("managed strings are not supported")),
|
||||
}
|
||||
}
|
||||
Some(&ast::DefTrait(trait_def_id)) => {
|
||||
let result = ast_path_to_trait_ref(
|
||||
this, rscope, trait_def_id, None, path);
|
||||
let trait_store = match ptr_ty {
|
||||
VStore(ty::VstoreUniq) => ty::UniqTraitStore,
|
||||
VStore(ty::VstoreSlice(r)) => {
|
||||
Uniq => ty::UniqTraitStore,
|
||||
RPtr(r) => {
|
||||
ty::RegionTraitStore(r, a_seq_ty.mutbl)
|
||||
}
|
||||
_ => {
|
||||
@ -491,7 +480,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
}
|
||||
ast::TyUniq(ty) => {
|
||||
let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
|
||||
mk_pointer(this, rscope, &mt, VStore(ty::VstoreUniq),
|
||||
mk_pointer(this, rscope, &mt, Uniq,
|
||||
|ty| ty::mk_uniq(tcx, ty))
|
||||
}
|
||||
ast::TyVec(ty) => {
|
||||
@ -509,7 +498,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
ast::TyRptr(ref region, ref mt) => {
|
||||
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
|
||||
debug!("ty_rptr r={}", r.repr(this.tcx()));
|
||||
mk_pointer(this, rscope, mt, VStore(ty::VstoreSlice(r)),
|
||||
mk_pointer(this, rscope, mt, RPtr(r),
|
||||
|ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
|
||||
}
|
||||
ast::TyTup(ref fields) => {
|
||||
|
@ -769,6 +769,7 @@ impl<'a> LookupContext<'a> {
|
||||
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)),
|
||||
ty::ty_str(None) => (0, ty::AutoBorrowVec(region, self_mt.mutbl)),
|
||||
_ => (1, ty::AutoPtr(region, self_mt.mutbl)),
|
||||
};
|
||||
(ty::mk_rptr(tcx, region, self_mt),
|
||||
@ -836,6 +837,27 @@ impl<'a> LookupContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
fn auto_slice_str(&self, autoderefs: uint) -> Option<MethodCallee> {
|
||||
let tcx = self.tcx();
|
||||
debug!("auto_slice_str");
|
||||
|
||||
let entry = self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowVec, autoderefs, [MutImmutable],
|
||||
|_m,r| ty::mk_str_slice(tcx, r, MutImmutable));
|
||||
|
||||
if entry.is_some() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowVecRef, autoderefs, [MutImmutable],
|
||||
|m,r| {
|
||||
let slice_ty = ty::mk_str_slice(tcx, r, m);
|
||||
ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
|
||||
})
|
||||
}
|
||||
|
||||
fn search_for_autosliced_method(&self,
|
||||
self_ty: ty::t,
|
||||
autoderefs: uint)
|
||||
@ -856,25 +878,11 @@ impl<'a> LookupContext<'a> {
|
||||
},
|
||||
ty_uniq(t) => match ty::get(t).sty {
|
||||
ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
|
||||
ty_str(None) => self.auto_slice_str(autoderefs),
|
||||
_ => None
|
||||
},
|
||||
ty_vec(mt, Some(_)) => self.auto_slice_vec(mt, autoderefs),
|
||||
|
||||
ty_str(VstoreUniq) |
|
||||
ty_str(VstoreFixed(_)) => {
|
||||
let entry = self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowVec, autoderefs, [MutImmutable],
|
||||
|_m,r| ty::mk_str(tcx, VstoreSlice(r)));
|
||||
|
||||
if entry.is_some() { return entry; }
|
||||
|
||||
self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowVecRef, autoderefs, [MutImmutable],
|
||||
|m,r| {
|
||||
let slice_ty = ty::mk_str(tcx, VstoreSlice(r));
|
||||
ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
|
||||
})
|
||||
}
|
||||
ty_str(Some(_)) => self.auto_slice_str(autoderefs),
|
||||
|
||||
ty_trait(~ty::TyTrait { def_id: trt_did, substs: trt_substs, bounds: b, .. }) => {
|
||||
// Coerce ~/&Trait instances to &Trait.
|
||||
@ -1310,7 +1318,7 @@ impl<'a> LookupContext<'a> {
|
||||
match ty::get(rcvr_ty).sty {
|
||||
ty::ty_rptr(_, mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => false,
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => false,
|
||||
_ => mutability_matches(mt.mutbl, m) &&
|
||||
rcvr_matches_ty(self.fcx, mt.ty, candidate),
|
||||
}
|
||||
@ -1332,7 +1340,7 @@ impl<'a> LookupContext<'a> {
|
||||
match ty::get(rcvr_ty).sty {
|
||||
ty::ty_uniq(typ) => {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(_, None) => false,
|
||||
ty::ty_vec(_, None) | ty::ty_str(None) => false,
|
||||
_ => rcvr_matches_ty(self.fcx, typ, candidate),
|
||||
}
|
||||
}
|
||||
|
@ -1395,7 +1395,7 @@ pub fn check_lit(fcx: &FnCtxt, lit: &ast::Lit) -> ty::t {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
match lit.node {
|
||||
ast::LitStr(..) => ty::mk_str(tcx, ty::VstoreSlice(ty::ReStatic)),
|
||||
ast::LitStr(..) => ty::mk_str_slice(tcx, ty::ReStatic, ast::MutImmutable),
|
||||
ast::LitBinary(..) => {
|
||||
ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable })
|
||||
}
|
||||
@ -2567,15 +2567,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::ExprVstore(ev, vst) => {
|
||||
let typ = match ev.node {
|
||||
ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
|
||||
let v = ast_expr_vstore_to_vstore(fcx, ev, vst);
|
||||
ty::mk_str(tcx, v)
|
||||
ast_expr_vstore_to_ty(fcx, ev, vst, || ty::mt{ ty: ty::mk_str(tcx, None),
|
||||
mutbl: ast::MutImmutable })
|
||||
}
|
||||
ast::ExprVec(ref args) => {
|
||||
let mutability = match vst {
|
||||
ast::ExprVstoreMutSlice => ast::MutMutable,
|
||||
_ => ast::MutImmutable,
|
||||
};
|
||||
let v = ast_expr_vstore_to_vstore(fcx, ev, vst);
|
||||
let mut any_error = false;
|
||||
let mut any_bot = false;
|
||||
let t: ty::t = fcx.infcx().next_ty_var();
|
||||
@ -2594,23 +2593,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
} else if any_bot {
|
||||
ty::mk_bot()
|
||||
} else {
|
||||
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 throw 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_expr_vstore_to_ty(fcx, ev, vst, ||
|
||||
ty::mt{ ty: ty::mk_vec(tcx,
|
||||
ty::mt {ty: t, mutbl: mutability},
|
||||
None),
|
||||
mutbl: mutability })
|
||||
}
|
||||
}
|
||||
ast::ExprRepeat(element, count_expr) => {
|
||||
@ -2620,7 +2607,6 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::ExprVstoreMutSlice => ast::MutMutable,
|
||||
_ => ast::MutImmutable,
|
||||
};
|
||||
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
|
||||
let t = fcx.infcx().next_ty_var();
|
||||
check_expr_has_type(fcx, element, t);
|
||||
let arg_t = fcx.expr_ty(element);
|
||||
@ -2629,17 +2615,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
} else if ty::type_is_bot(arg_t) {
|
||||
ty::mk_bot()
|
||||
} else {
|
||||
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}),
|
||||
}
|
||||
ast_expr_vstore_to_ty(fcx, ev, vst, ||
|
||||
ty::mt{ ty: ty::mk_vec(tcx,
|
||||
ty::mt {ty: t, mutbl: mutability},
|
||||
None),
|
||||
mutbl: mutability})
|
||||
}
|
||||
}
|
||||
_ =>
|
||||
@ -4013,33 +3993,29 @@ pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
|
||||
}
|
||||
|
||||
pub fn ast_expr_vstore_to_vstore(fcx: &FnCtxt,
|
||||
e: &ast::Expr,
|
||||
v: ast::ExprVstore)
|
||||
-> ty::Vstore {
|
||||
pub fn ast_expr_vstore_to_ty(fcx: &FnCtxt,
|
||||
e: &ast::Expr,
|
||||
v: ast::ExprVstore,
|
||||
mk_inner: || -> ty::mt)
|
||||
-> ty::t {
|
||||
match v {
|
||||
ast::ExprVstoreUniq => ty::VstoreUniq,
|
||||
ast::ExprVstoreUniq => ty::mk_uniq(fcx.ccx.tcx, mk_inner().ty),
|
||||
ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
|
||||
match e.node {
|
||||
ast::ExprLit(..) => {
|
||||
// string literals and *empty slices* live in static memory
|
||||
ty::VstoreSlice(ty::ReStatic)
|
||||
ty::mk_rptr(fcx.ccx.tcx, ty::ReStatic, mk_inner())
|
||||
}
|
||||
ast::ExprVec(ref elements) if elements.len() == 0 => {
|
||||
// string literals and *empty slices* live in static memory
|
||||
ty::VstoreSlice(ty::ReStatic)
|
||||
ty::mk_rptr(fcx.ccx.tcx, ty::ReStatic, mk_inner())
|
||||
}
|
||||
ast::ExprRepeat(..) |
|
||||
ast::ExprVec(..) => {
|
||||
// vector literals are temporaries on the stack
|
||||
match fcx.tcx().region_maps.temporary_scope(e.id) {
|
||||
Some(scope) => {
|
||||
ty::VstoreSlice(ty::ReScope(scope))
|
||||
}
|
||||
None => {
|
||||
// this slice occurs in a static somewhere
|
||||
ty::VstoreSlice(ty::ReStatic)
|
||||
}
|
||||
Some(scope) => ty::mk_rptr(fcx.ccx.tcx, ty::ReScope(scope), mk_inner()),
|
||||
None => ty::mk_rptr(fcx.ccx.tcx, ty::ReStatic, mk_inner()),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -939,12 +939,8 @@ fn constrain_index(rcx: &mut Rcx,
|
||||
|
||||
let r_index_expr = ty::ReScope(index_expr.id);
|
||||
match ty::get(indexed_ty).sty {
|
||||
ty::ty_str(ty::VstoreSlice(r_ptr)) => {
|
||||
rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
|
||||
r_index_expr, r_ptr);
|
||||
}
|
||||
ty::ty_rptr(r_ptr, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) => {
|
||||
ty::ty_vec(_, None) | ty::ty_str(None)=> {
|
||||
rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span),
|
||||
r_index_expr, r_ptr);
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ we may want to adjust precisely when coercions occur.
|
||||
|
||||
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowObj, AutoDerefRef};
|
||||
use middle::ty::{VstoreSlice, VstoreUniq};
|
||||
use middle::ty::{mt};
|
||||
use middle::ty;
|
||||
use middle::typeck::infer::{CoerceResult, resolve_type, Coercion};
|
||||
@ -109,6 +108,11 @@ impl<'f> Coerce<'f> {
|
||||
});
|
||||
}
|
||||
ty::ty_vec(_, _) => {},
|
||||
ty::ty_str(None) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_string(a, sty_a, b)
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
|
||||
@ -117,12 +121,6 @@ impl<'f> Coerce<'f> {
|
||||
};
|
||||
}
|
||||
|
||||
ty::ty_str(VstoreSlice(..)) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_string(a, sty_a, b)
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_fn(a, sty_a, b)
|
||||
@ -264,7 +262,10 @@ impl<'f> Coerce<'f> {
|
||||
b.inf_str(self.get_ref().infcx));
|
||||
|
||||
match *sty_a {
|
||||
ty::ty_str(VstoreUniq) => {}
|
||||
ty::ty_uniq(t) => match ty::get(t).sty {
|
||||
ty::ty_str(None) => {}
|
||||
_ => return self.subtype(a, b),
|
||||
},
|
||||
_ => {
|
||||
return self.subtype(a, b);
|
||||
}
|
||||
@ -272,7 +273,7 @@ impl<'f> Coerce<'f> {
|
||||
|
||||
let coercion = Coercion(self.get_ref().trace.clone());
|
||||
let r_a = self.get_ref().infcx.next_region_var(coercion);
|
||||
let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, VstoreSlice(r_a));
|
||||
let a_borrowed = ty::mk_str_slice(self.get_ref().infcx.tcx, r_a, ast::MutImmutable);
|
||||
if_ok!(self.subtype(a_borrowed, b));
|
||||
Ok(Some(AutoDerefRef(AutoDerefRef {
|
||||
autoderefs: 0,
|
||||
|
@ -255,30 +255,6 @@ pub trait Combine {
|
||||
-> cres<ty::Region>;
|
||||
fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
|
||||
|
||||
fn vstores(&self,
|
||||
vk: ty::terr_vstore_kind,
|
||||
a: ty::Vstore,
|
||||
b: ty::Vstore)
|
||||
-> cres<ty::Vstore> {
|
||||
debug!("{}.vstores(a={:?}, b={:?})", self.tag(), a, b);
|
||||
|
||||
match (a, b) {
|
||||
(ty::VstoreSlice(a_r), ty::VstoreSlice(b_r)) => {
|
||||
self.contraregions(a_r, b_r).and_then(|r| {
|
||||
Ok(ty::VstoreSlice(r))
|
||||
})
|
||||
}
|
||||
|
||||
_ if a == b => {
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
_ => {
|
||||
Err(ty::terr_vstores_differ(vk, expected_found(self, a, b)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn trait_stores(&self,
|
||||
vk: ty::terr_vstore_kind,
|
||||
a: ty::TraitStore,
|
||||
@ -394,6 +370,27 @@ pub fn super_fn_sigs<C:Combine>(this: &C, a: &ty::FnSig, b: &ty::FnSig) -> cres<
|
||||
}
|
||||
|
||||
pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
|
||||
// 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.
|
||||
fn check_ptr_to_vec<C:Combine>(this: &C,
|
||||
a: ty::t,
|
||||
b: ty::t,
|
||||
a_inner: ty::t,
|
||||
b_inner: ty::t,
|
||||
result: ty::t) -> cres<ty::t> {
|
||||
match (&ty::get(a_inner).sty, &ty::get(b_inner).sty) {
|
||||
(&ty::ty_vec(_, None), &ty::ty_vec(_, None)) |
|
||||
(&ty::ty_str(None), &ty::ty_str(None)) => Ok(result),
|
||||
(&ty::ty_vec(_, None), _) | (_, &ty::ty_vec(_, None)) |
|
||||
(&ty::ty_str(None), _) | (_, &ty::ty_str(None))
|
||||
=> Err(ty::terr_sorts(expected_found(this, a, b))),
|
||||
_ => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
let tcx = this.infcx().tcx;
|
||||
let a_sty = &ty::get(a).sty;
|
||||
let b_sty = &ty::get(b).sty;
|
||||
@ -499,39 +496,18 @@ 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)) => {
|
||||
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)),
|
||||
}
|
||||
check_ptr_to_vec(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
|
||||
}
|
||||
|
||||
(&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_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)),
|
||||
}
|
||||
check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
|
||||
}
|
||||
|
||||
(&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
|
||||
let r = if_ok!(this.contraregions(a_r, b_r));
|
||||
let mt = if_ok!(this.mts(a_mt, b_mt));
|
||||
|
||||
// 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)),
|
||||
}
|
||||
check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
|
||||
}
|
||||
|
||||
(&ty::ty_vec(ref a_mt, sz_a), &ty::ty_vec(ref b_mt, sz_b)) => {
|
||||
@ -544,9 +520,12 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
})
|
||||
}
|
||||
|
||||
(&ty::ty_str(vs_a), &ty::ty_str(vs_b)) => {
|
||||
let vs = if_ok!(this.vstores(ty::terr_str, vs_a, vs_b));
|
||||
Ok(ty::mk_str(tcx,vs))
|
||||
(&ty::ty_str(sz_a), &ty::ty_str(sz_b)) => {
|
||||
if sz_a == sz_b {
|
||||
Ok(ty::mk_str(tcx,sz_a))
|
||||
} else {
|
||||
Err(ty::terr_sorts(expected_found(this, a, b)))
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => {
|
||||
|
@ -706,7 +706,7 @@ impl<'a> ConstraintContext<'a> {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_nil | ty::ty_bot | ty::ty_bool |
|
||||
ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) |
|
||||
ty::ty_float(_) => {
|
||||
ty::ty_float(_) | ty::ty_str(_) => {
|
||||
/* leaf type -- noop */
|
||||
}
|
||||
|
||||
@ -716,10 +716,6 @@ impl<'a> ConstraintContext<'a> {
|
||||
self.add_constraints_from_mt(mt, variance);
|
||||
}
|
||||
|
||||
ty::ty_str(vstore) => {
|
||||
self.add_constraints_from_vstore(vstore, variance);
|
||||
}
|
||||
|
||||
ty::ty_vec(ref mt, _) => {
|
||||
self.add_constraints_from_mt(mt, variance);
|
||||
}
|
||||
@ -792,20 +788,6 @@ impl<'a> ConstraintContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a vector with Vstore `vstore`
|
||||
/// appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_vstore(&mut self,
|
||||
vstore: ty::Vstore,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
match vstore {
|
||||
ty::VstoreSlice(r) => {
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(r, contra);
|
||||
}
|
||||
|
||||
ty::VstoreFixed(_) | ty::VstoreUniq => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a nominal type (enum, struct,
|
||||
/// object, etc) appearing in a context with ambient variance `variance`
|
||||
|
@ -395,21 +395,16 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
|
||||
let bound_str = bounds.repr(cx);
|
||||
format!("{}{}{}{}", trait_store_to_str(cx, store), ty, bound_sep, bound_str)
|
||||
}
|
||||
ty_str(vs) => {
|
||||
match vs {
|
||||
ty::VstoreFixed(n) => format!("str/{}", n),
|
||||
ty::VstoreUniq => "~str".to_owned(),
|
||||
ty::VstoreSlice(r) => format!("{}str", region_ptr_to_str(cx, r))
|
||||
ty_str(sz) => {
|
||||
match sz {
|
||||
Some(n) => format!("str/{}", n),
|
||||
None => "str".to_owned(),
|
||||
}
|
||||
}
|
||||
ty_vec(ref mt, sz) => {
|
||||
match sz {
|
||||
Some(n) => {
|
||||
format!("[{}, .. {}]", mt_to_str(cx, mt), n)
|
||||
}
|
||||
None => {
|
||||
format!("[{}]", ty_to_str(cx, mt.ty))
|
||||
}
|
||||
Some(n) => format!("[{}, .. {}]", mt_to_str(cx, mt), n),
|
||||
None => format!("[{}]", ty_to_str(cx, mt.ty)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -854,16 +849,6 @@ impl Repr for ty::TraitStore {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for ty::BuiltinBound {
|
||||
fn repr(&self, _tcx: &ctxt) -> ~str {
|
||||
format!("{:?}", *self)
|
||||
|
@ -17,7 +17,7 @@ fn has_uniq(x: ~str) {
|
||||
}
|
||||
|
||||
fn has_slice(x: &str) {
|
||||
wants_uniq(x); //~ ERROR str storage differs: expected `~` but found `&`
|
||||
wants_uniq(x); //~ ERROR mismatched types: expected `~str` but found `&str` (expected ~-ptr but f
|
||||
wants_slice(x);
|
||||
}
|
||||
|
||||
|
@ -10,5 +10,5 @@
|
||||
|
||||
fn main() {
|
||||
format!("{0, select, other{}}", 2);
|
||||
//~^ ERROR: expected &str but found integral
|
||||
//~^ ERROR: mismatched types: expected `&&str` but found `&<generic integer #0>` (expected &-ptr
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user