auto merge of #14869 : nick29581/rust/tstore, r=nmatsakis
Use ty_rptr/ty_uniq(ty_trait) rather than TraitStore to represent trait types. Also addresses (but doesn't close) #12470. Part of the work towards DST (#12938).
This commit is contained in:
commit
5c81a186e9
@ -346,10 +346,9 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
||||
assert_eq!(next(st), '[');
|
||||
let def = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
let store = parse_trait_store(st, |x,y| conv(x,y));
|
||||
let bounds = parse_bounds(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_trait(st.tcx, def, substs, store, bounds.builtin_bounds);
|
||||
return ty::mk_trait(st.tcx, def, substs, bounds.builtin_bounds);
|
||||
}
|
||||
'p' => {
|
||||
let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
|
||||
|
@ -232,12 +232,10 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
store,
|
||||
bounds
|
||||
}) => {
|
||||
mywrite!(w, "x[{}|", (cx.ds)(def_id));
|
||||
enc_substs(w, cx, substs);
|
||||
enc_trait_store(w, cx, store);
|
||||
let bounds = ty::ParamBounds {builtin_bounds: bounds,
|
||||
trait_bounds: Vec::new()};
|
||||
enc_bounds(w, cx, &bounds);
|
||||
|
@ -361,9 +361,12 @@ fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) {
|
||||
fn check_trait_cast(cx: &mut Context, source_ty: ty::t, target_ty: ty::t, span: Span) {
|
||||
check_cast_for_escaping_regions(cx, source_ty, target_ty, span);
|
||||
match ty::get(target_ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
|
||||
check_trait_cast_bounds(cx, span, source_ty, bounds);
|
||||
}
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ ty, .. }) => match ty::get(ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
|
||||
check_trait_cast_bounds(cx, span, source_ty, bounds);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -530,9 +533,8 @@ pub fn check_cast_for_escaping_regions(
|
||||
{
|
||||
// Determine what type we are casting to; if it is not a trait, then no
|
||||
// worries.
|
||||
match ty::get(target_ty).sty {
|
||||
ty::ty_trait(..) => {}
|
||||
_ => { return; }
|
||||
if !ty::type_is_trait(target_ty) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect up the regions that appear in the target type. We want to
|
||||
|
@ -980,9 +980,6 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
|
||||
n_box += 1;
|
||||
}
|
||||
ty::ty_uniq(_) |
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
store: ty::UniqTraitStore, ..
|
||||
}) |
|
||||
ty::ty_closure(box ty::ClosureTy {
|
||||
store: ty::UniqTraitStore,
|
||||
..
|
||||
|
@ -174,7 +174,6 @@ pub enum deref_kind {
|
||||
pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
match ty::get(t).sty {
|
||||
ty::ty_uniq(_) |
|
||||
ty::ty_trait(box ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||
ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||
Some(deref_ptr(OwnedPtr))
|
||||
}
|
||||
@ -183,13 +182,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
|
||||
Some(deref_ptr(BorrowedPtr(kind, r)))
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
store: ty::RegionTraitStore(r, mutbl),
|
||||
..
|
||||
}) => {
|
||||
let kind = ty::BorrowKind::from_mutbl(mutbl);
|
||||
Some(deref_ptr(BorrowedPtr(kind, r)))
|
||||
}
|
||||
|
||||
ty::ty_closure(box ty::ClosureTy {
|
||||
store: ty::RegionTraitStore(r, _),
|
||||
|
@ -292,12 +292,11 @@ impl Case {
|
||||
fn find_ptr(&self) -> Option<uint> {
|
||||
self.tys.iter().position(|&ty| {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => false,
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str| ty::ty_trait(..) => false,
|
||||
_ => true,
|
||||
},
|
||||
ty::ty_uniq(..) | ty::ty_box(..) |
|
||||
ty::ty_bare_fn(..) => true,
|
||||
ty::ty_box(..) | ty::ty_bare_fn(..) => true,
|
||||
// Is that everything? Would closures or slices qualify?
|
||||
_ => false
|
||||
}
|
||||
|
@ -1794,6 +1794,9 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
|
||||
match ty::get(ret_ty).sty {
|
||||
// `~` pointer return values never alias because ownership
|
||||
// is transferred
|
||||
ty::ty_uniq(it) if match ty::get(it).sty {
|
||||
ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
|
||||
} => {}
|
||||
ty::ty_uniq(_) => {
|
||||
attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NoAliasAttribute as u64));
|
||||
}
|
||||
@ -1803,9 +1806,9 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
|
||||
// We can also mark the return value as `nonnull` in certain cases
|
||||
match ty::get(ret_ty).sty {
|
||||
// These are not really pointers but pairs, (pointer, len)
|
||||
ty::ty_rptr(_, ty::mt { ty: it, .. }) |
|
||||
ty::ty_uniq(it) |
|
||||
ty::ty_rptr(_, ty::mt { ty: it, .. }) if match ty::get(it).sty {
|
||||
ty::ty_str | ty::ty_vec(..) => true, _ => false
|
||||
ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
|
||||
} => {}
|
||||
ty::ty_uniq(_) | ty::ty_rptr(_, _) => {
|
||||
attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NonNullAttribute as u64));
|
||||
|
@ -67,7 +67,7 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
|
||||
ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
|
||||
type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
|
||||
ty::type_is_simd(tcx, ty);
|
||||
if simple {
|
||||
if simple && !ty::type_is_trait(ty) {
|
||||
return true;
|
||||
}
|
||||
match ty::get(ty).sty {
|
||||
|
@ -143,7 +143,9 @@ 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) | ty::ty_str => cx.sess().bug("unexpected slice"),
|
||||
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => {
|
||||
cx.sess().bug("unexpected unsized type")
|
||||
}
|
||||
_ => const_deref_ptr(cx, v),
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +157,7 @@ pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode {
|
||||
* on whether type is immediate or not.
|
||||
*/
|
||||
|
||||
if type_is_zero_size(ccx, ty) {
|
||||
ByValue
|
||||
} else if type_is_immediate(ccx, ty) {
|
||||
if type_is_immediate(ccx, ty) {
|
||||
ByValue
|
||||
} else {
|
||||
ByRef
|
||||
|
@ -285,8 +285,8 @@ impl TypeMap {
|
||||
// unique ptr (~) -> {~ :pointee-uid:}
|
||||
// @-ptr (@) -> {@ :pointee-uid:}
|
||||
// sized vec ([T, ..x]) -> {[:size:] :element-uid:}
|
||||
// vec slice (&[T]) -> {&<mut> [] :element-uid:}
|
||||
// trait (~ | &[mut] T) -> {:sigil: trait_:svh: / :node-id:_<(:param-uid:),*> }
|
||||
// unsized vec ([T]) -> {[] :element-uid:}
|
||||
// trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
|
||||
// closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
|
||||
// :return-type-uid: : (:bounds:)*}
|
||||
// function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
|
||||
@ -361,18 +361,12 @@ impl TypeMap {
|
||||
let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
|
||||
unique_type_id.push_str(inner_type_id.as_slice());
|
||||
},
|
||||
ty::ty_vec(ty::mt { ty: inner_type, mutbl }, optional_length) => {
|
||||
ty::ty_vec(ty::mt { ty: inner_type, .. }, optional_length) => {
|
||||
match optional_length {
|
||||
Some(len) => {
|
||||
unique_type_id.push_str(format!("[{}]", len).as_slice());
|
||||
}
|
||||
None => {
|
||||
unique_type_id.push_char('&');
|
||||
|
||||
if mutbl == ast::MutMutable {
|
||||
unique_type_id.push_str("mut");
|
||||
}
|
||||
|
||||
unique_type_id.push_str("[]");
|
||||
}
|
||||
};
|
||||
@ -382,12 +376,6 @@ impl TypeMap {
|
||||
unique_type_id.push_str(inner_type_id.as_slice());
|
||||
},
|
||||
ty::ty_trait(ref trait_data) => {
|
||||
match trait_data.store {
|
||||
ty::UniqTraitStore => unique_type_id.push_char('~'),
|
||||
ty::RegionTraitStore(_, ast::MutMutable) => unique_type_id.push_str("&mut"),
|
||||
ty::RegionTraitStore(_, ast::MutImmutable) => unique_type_id.push_char('&'),
|
||||
};
|
||||
|
||||
unique_type_id.push_str("trait ");
|
||||
|
||||
from_def_id_and_substs(self,
|
||||
@ -2901,6 +2889,16 @@ fn type_metadata(cx: &CrateContext,
|
||||
let i8_t = ty::mk_i8();
|
||||
heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
ref bounds
|
||||
}) => {
|
||||
MetadataCreationResult::new(
|
||||
trait_metadata(cx, def_id, t, substs, ty::UniqTraitStore,
|
||||
bounds, unique_type_id),
|
||||
false)
|
||||
}
|
||||
_ => {
|
||||
let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
|
||||
return_if_created_in_meantime!();
|
||||
@ -2917,6 +2915,17 @@ fn type_metadata(cx: &CrateContext,
|
||||
ty::ty_str => {
|
||||
vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
ref bounds
|
||||
}) => {
|
||||
MetadataCreationResult::new(
|
||||
trait_metadata(cx, def_id, t, substs,
|
||||
ty::RegionTraitStore(ty::ReStatic, mt.mutbl),
|
||||
bounds, unique_type_id),
|
||||
false)
|
||||
}
|
||||
_ => {
|
||||
let pointee = type_metadata(cx, mt.ty, usage_site_span);
|
||||
return_if_created_in_meantime!();
|
||||
@ -2930,16 +2939,6 @@ fn type_metadata(cx: &CrateContext,
|
||||
ty::ty_closure(ref closurety) => {
|
||||
subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
store,
|
||||
ref bounds
|
||||
}) => {
|
||||
MetadataCreationResult::new(
|
||||
trait_metadata(cx, def_id, t, substs, store, bounds, unique_type_id),
|
||||
false)
|
||||
}
|
||||
ty::ty_struct(def_id, ref substs) => {
|
||||
prepare_struct_metadata(cx,
|
||||
t,
|
||||
|
@ -769,15 +769,12 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
ast::ExprCast(ref val, _) => {
|
||||
// DPS output mode means this is a trait cast:
|
||||
match ty::get(node_id_type(bcx, expr.id)).sty {
|
||||
ty::ty_trait(..) => {
|
||||
let datum = unpack_datum!(bcx, trans(bcx, &**val));
|
||||
meth::trans_trait_cast(bcx, datum, expr.id, dest)
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(expr.span,
|
||||
"expr_cast of non-trait");
|
||||
}
|
||||
if ty::type_is_trait(node_id_type(bcx, expr.id)) {
|
||||
let datum = unpack_datum!(bcx, trans(bcx, &**val));
|
||||
meth::trans_trait_cast(bcx, datum, expr.id, dest)
|
||||
} else {
|
||||
bcx.tcx().sess.span_bug(expr.span,
|
||||
"expr_cast of non-trait");
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, ref dst, ref src) => {
|
||||
@ -1578,7 +1575,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) | ty::ty_str => cast_other,
|
||||
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => cast_other,
|
||||
_ => cast_pointer,
|
||||
},
|
||||
ty::ty_bare_fn(..) => cast_pointer,
|
||||
@ -1794,8 +1791,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) | ty::ty_str
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected ~[T]"),
|
||||
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..)
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected unsized box"),
|
||||
_ => deref_owned_pointer(bcx, expr, datum, content_ty),
|
||||
}
|
||||
}
|
||||
@ -1812,8 +1809,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) | ty::ty_str
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected &[T]"),
|
||||
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..)
|
||||
=> bcx.tcx().sess.span_bug(expr.span, "unexpected unsized reference"),
|
||||
_ => {
|
||||
assert!(!ty::type_needs_drop(bcx.tcx(), datum.ty));
|
||||
|
||||
|
@ -100,7 +100,7 @@ pub 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) | ty::ty_str => t,
|
||||
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => t,
|
||||
_ => {
|
||||
let llty = sizing_type_of(ccx, typ);
|
||||
// `Box<ZeroSizeType>` does not allocate.
|
||||
@ -295,10 +295,10 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
decr_refcnt_maybe_free(bcx, v0, body_ty)
|
||||
}
|
||||
ty::ty_uniq(content_ty) => {
|
||||
let llbox = Load(bcx, v0);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
match ty::get(content_ty).sty {
|
||||
ty::ty_vec(mt, None) => {
|
||||
let llbox = Load(bcx, v0);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, mt.ty);
|
||||
// FIXME: #13994: the old `Box<[T]>` will not support sized deallocation
|
||||
@ -306,6 +306,8 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
})
|
||||
}
|
||||
ty::ty_str => {
|
||||
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);
|
||||
@ -313,7 +315,22 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
trans_exchange_free(bcx, llbox, 0, 8)
|
||||
})
|
||||
}
|
||||
ty::ty_trait(..) => {
|
||||
let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
|
||||
// Only drop the value when it is non-null
|
||||
with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
|
||||
let dtor = Load(bcx, dtor_ptr);
|
||||
Call(bcx,
|
||||
dtor,
|
||||
[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
|
||||
[]);
|
||||
bcx
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
let llbox = Load(bcx, v0);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = drop_ty(bcx, llbox, content_ty);
|
||||
trans_exchange_free_ty(bcx, llbox, content_ty)
|
||||
@ -336,16 +353,6 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
|
||||
let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
|
||||
// Only drop the value when it is non-null
|
||||
with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
|
||||
let dtor = Load(bcx, dtor_ptr);
|
||||
Call(bcx, dtor, [PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))], []);
|
||||
bcx
|
||||
})
|
||||
}
|
||||
ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
|
||||
let box_cell_v = GEPi(bcx, v0, [0u, abi::fn_field_box]);
|
||||
let env = Load(bcx, box_cell_v);
|
||||
|
@ -157,7 +157,7 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
let extra = extra.append(self.c_mt(mt).as_slice());
|
||||
self.visit("evec_fixed", extra.as_slice())
|
||||
}
|
||||
ty::ty_vec(..) | ty::ty_str => fail!("unexpected unsized type"),
|
||||
ty::ty_vec(..) | ty::ty_str | ty::ty_trait(..) => fail!("unexpected unsized type"),
|
||||
// Should remove mt from box and uniq.
|
||||
ty::ty_box(typ) => {
|
||||
let extra = self.c_mt(&ty::mt {
|
||||
@ -174,6 +174,13 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
self.visit("evec_uniq", extra.as_slice())
|
||||
}
|
||||
ty::ty_str => self.visit("estr_uniq", &[]),
|
||||
ty::ty_trait(..) => {
|
||||
let extra = [
|
||||
self.c_slice(token::intern_and_get_ident(
|
||||
ty_to_str(tcx, t).as_slice()))
|
||||
];
|
||||
self.visit("trait", extra);
|
||||
}
|
||||
_ => {
|
||||
let extra = self.c_mt(&ty::mt {
|
||||
ty: typ,
|
||||
@ -196,6 +203,13 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
extra.as_slice())
|
||||
}
|
||||
ty::ty_str => self.visit("estr_slice", &[]),
|
||||
ty::ty_trait(..) => {
|
||||
let extra = [
|
||||
self.c_slice(token::intern_and_get_ident(
|
||||
ty_to_str(tcx, t).as_slice()))
|
||||
];
|
||||
self.visit("trait", extra);
|
||||
}
|
||||
_ => {
|
||||
let extra = self.c_mt(mt);
|
||||
self.visit("rptr", extra.as_slice())
|
||||
@ -351,14 +365,6 @@ impl<'a, 'b> Reflector<'a, 'b> {
|
||||
})
|
||||
}
|
||||
|
||||
ty::ty_trait(..) => {
|
||||
let extra = [
|
||||
self.c_slice(token::intern_and_get_ident(
|
||||
ty_to_str(tcx, t).as_slice()))
|
||||
];
|
||||
self.visit("trait", extra);
|
||||
}
|
||||
|
||||
// Miscellaneous extra types
|
||||
ty::ty_infer(_) => self.leaf("infer"),
|
||||
ty::ty_err => self.leaf("err"),
|
||||
|
@ -116,20 +116,25 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
ty::ty_float(t) => Type::float_from_ty(cx, t),
|
||||
|
||||
ty::ty_box(..) |
|
||||
ty::ty_uniq(..) |
|
||||
ty::ty_ptr(..) => Type::i8p(cx),
|
||||
ty::ty_uniq(ty) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ => Type::i8p(cx),
|
||||
}
|
||||
}
|
||||
ty::ty_rptr(_, mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => {
|
||||
Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
|
||||
}
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ => Type::i8p(cx),
|
||||
}
|
||||
}
|
||||
|
||||
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_vec(mt, Some(size)) => {
|
||||
Type::array(&sizing_type_of(cx, mt.ty), size as u64)
|
||||
@ -152,7 +157,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
}
|
||||
|
||||
ty::ty_infer(..) | ty::ty_param(..) |
|
||||
ty::ty_err(..) | ty::ty_vec(_, None) | ty::ty_str => {
|
||||
ty::ty_err(..) | ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => {
|
||||
cx.sess().bug(format!("fictitious type {:?} in sizing_type_of()",
|
||||
ty::get(t).sty).as_slice())
|
||||
}
|
||||
@ -215,6 +220,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(mt, None) => Type::vec(cx, &type_of(cx, mt.ty)).ptr_to(),
|
||||
ty::ty_str => Type::vec(cx, &Type::i8(cx)).ptr_to(),
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ => type_of(cx, typ).ptr_to(),
|
||||
}
|
||||
}
|
||||
@ -230,6 +236,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
// This means we get a nicer name in the output
|
||||
cx.tn.find_type("str_slice").unwrap()
|
||||
}
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ => type_of(cx, mt.ty).ptr_to(),
|
||||
}
|
||||
}
|
||||
@ -245,7 +252,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
let fn_ty = type_of_fn_from_ty(cx, t).ptr_to();
|
||||
Type::struct_(cx, [fn_ty, Type::i8p(cx)], false)
|
||||
}
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
ty::ty_tup(..) => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
adt::type_of(cx, &*repr)
|
||||
@ -268,6 +274,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
|
||||
|
||||
ty::ty_vec(_, None) => cx.sess().bug("type_of with unsized ty_vec"),
|
||||
ty::ty_str => cx.sess().bug("type_of with unsized (bare) ty_str"),
|
||||
ty::ty_trait(..) => cx.sess().bug("type_of with unsized ty_trait"),
|
||||
ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
|
||||
ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
|
||||
ty::ty_err(..) => cx.sess().bug("type_of with ty_err")
|
||||
|
@ -742,7 +742,6 @@ pub enum sty {
|
||||
pub struct TyTrait {
|
||||
pub def_id: DefId,
|
||||
pub substs: Substs,
|
||||
pub store: TraitStore,
|
||||
pub bounds: BuiltinBounds
|
||||
}
|
||||
|
||||
@ -1196,14 +1195,8 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
||||
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
|
||||
flags |= sflags(substs);
|
||||
}
|
||||
&ty_trait(box ty::TyTrait { ref substs, store, .. }) => {
|
||||
&ty_trait(box ty::TyTrait { ref substs, .. }) => {
|
||||
flags |= sflags(substs);
|
||||
match store {
|
||||
RegionTraitStore(r, _) => {
|
||||
flags |= rflags(r);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
&ty_box(tt) | &ty_uniq(tt) => {
|
||||
flags |= get(tt).flags
|
||||
@ -1434,14 +1427,12 @@ pub fn mk_ctor_fn(cx: &ctxt,
|
||||
pub fn mk_trait(cx: &ctxt,
|
||||
did: ast::DefId,
|
||||
substs: Substs,
|
||||
store: TraitStore,
|
||||
bounds: BuiltinBounds)
|
||||
-> t {
|
||||
// take a copy of substs so that we own the vectors inside
|
||||
let inner = box TyTrait {
|
||||
def_id: did,
|
||||
substs: substs,
|
||||
store: store,
|
||||
bounds: bounds
|
||||
};
|
||||
mk_t(cx, ty_trait(inner))
|
||||
@ -1577,9 +1568,9 @@ fn type_is_slice(ty:t) -> bool {
|
||||
|
||||
pub fn type_is_structural(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
|
||||
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) |
|
||||
ty_vec(_, Some(_)) => true,
|
||||
_ => type_is_slice(ty)
|
||||
_ => type_is_slice(ty) | type_is_trait(ty)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1635,7 +1626,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) | ty_str => false,
|
||||
ty_vec(_, None) | ty_str | ty_trait(..) => false,
|
||||
_ => true
|
||||
},
|
||||
_ => false
|
||||
@ -1651,7 +1642,10 @@ pub fn type_is_unsafe_ptr(ty: t) -> bool {
|
||||
|
||||
pub fn type_is_unique(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_uniq(_) => true,
|
||||
ty_uniq(_) => match get(ty).sty {
|
||||
ty_trait(..) => false,
|
||||
_ => true
|
||||
},
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -2060,8 +2054,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
}
|
||||
|
||||
ty_trait(box ty::TyTrait { store, bounds, .. }) => {
|
||||
object_contents(cx, store, bounds)
|
||||
ty_trait(box ty::TyTrait { bounds, .. }) => {
|
||||
object_contents(cx, bounds)
|
||||
}
|
||||
|
||||
ty_ptr(ref mt) => {
|
||||
@ -2185,7 +2179,16 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> TypeContents {
|
||||
// Closure contents are just like trait contents, but with potentially
|
||||
// even more stuff.
|
||||
let st = object_contents(cx, cty.store, cty.bounds);
|
||||
let st = object_contents(cx, cty.bounds);
|
||||
|
||||
let st = match cty.store {
|
||||
UniqTraitStore => {
|
||||
st.owned_pointer()
|
||||
}
|
||||
RegionTraitStore(r, mutbl) => {
|
||||
st.reference(borrowed_contents(r, mutbl))
|
||||
}
|
||||
};
|
||||
|
||||
// This also prohibits "@once fn" from being copied, which allows it to
|
||||
// be called. Neither way really makes much sense.
|
||||
@ -2198,20 +2201,10 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
fn object_contents(cx: &ctxt,
|
||||
store: TraitStore,
|
||||
bounds: BuiltinBounds)
|
||||
-> TypeContents {
|
||||
// These are the type contents of the (opaque) interior
|
||||
let contents = kind_bounds_to_contents(cx, bounds, []);
|
||||
|
||||
match store {
|
||||
UniqTraitStore => {
|
||||
contents.owned_pointer()
|
||||
}
|
||||
RegionTraitStore(r, mutbl) => {
|
||||
contents.reference(borrowed_contents(r, mutbl))
|
||||
}
|
||||
}
|
||||
kind_bounds_to_contents(cx, bounds, [])
|
||||
}
|
||||
|
||||
fn kind_bounds_to_contents(cx: &ctxt,
|
||||
@ -2470,6 +2463,10 @@ pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability {
|
||||
|
||||
pub fn type_is_trait(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) => match get(ty).sty {
|
||||
ty_trait(..) => true,
|
||||
_ => false
|
||||
},
|
||||
ty_trait(..) => true,
|
||||
_ => false
|
||||
}
|
||||
@ -2559,7 +2556,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) | ty_str => None,
|
||||
ty_vec(_, None) | ty_str | ty_trait(..) => None,
|
||||
_ => Some(mt {
|
||||
ty: typ,
|
||||
mutbl: ast::MutImmutable,
|
||||
@ -2567,7 +2564,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) | ty_str => None,
|
||||
ty_vec(_, None) | ty_str | ty_trait(..) => None,
|
||||
_ => Some(mt),
|
||||
},
|
||||
ty_ptr(mt) if explicit => Some(mt),
|
||||
@ -2888,7 +2885,19 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
}
|
||||
|
||||
AutoObject(store, bounds, def_id, ref substs) => {
|
||||
mk_trait(cx, def_id, substs.clone(), store, bounds)
|
||||
|
||||
let tr = mk_trait(cx, def_id, substs.clone(), bounds);
|
||||
match store {
|
||||
UniqTraitStore => {
|
||||
mk_uniq(cx, tr)
|
||||
}
|
||||
RegionTraitStore(r, m) => {
|
||||
mk_rptr(cx, r, mt {
|
||||
ty: tr,
|
||||
mutbl: m
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2926,10 +2935,20 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
fn borrow_obj(cx: &ctxt, span: Span, r: Region,
|
||||
m: ast::Mutability, ty: ty::t) -> ty::t {
|
||||
match get(ty).sty {
|
||||
ty_trait(box ty::TyTrait {def_id, ref substs, bounds, .. }) => {
|
||||
ty::mk_trait(cx, def_id, substs.clone(),
|
||||
RegionTraitStore(r, m), bounds)
|
||||
}
|
||||
ty_uniq(t) | ty_rptr(_, mt{ty: t, ..}) => match get(t).sty {
|
||||
ty_trait(box ty::TyTrait {def_id, ref substs, bounds, .. }) => {
|
||||
mk_rptr(cx, r, mt {
|
||||
ty: ty::mk_trait(cx, def_id, substs.clone(), bounds),
|
||||
mutbl: m
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
format!("borrow-trait-obj associated with bad sty: {:?}",
|
||||
get(ty).sty).as_slice());
|
||||
}
|
||||
},
|
||||
ref s => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
@ -4264,11 +4283,11 @@ pub fn visitor_object_ty(tcx: &ctxt,
|
||||
let substs = Substs::empty();
|
||||
let trait_ref = Rc::new(TraitRef { def_id: trait_lang_item, substs: substs });
|
||||
Ok((trait_ref.clone(),
|
||||
mk_trait(tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.substs.clone(),
|
||||
RegionTraitStore(region, ast::MutMutable),
|
||||
empty_builtin_bounds())))
|
||||
mk_rptr(tcx, region, mt {mutbl: ast::MutMutable,
|
||||
ty: mk_trait(tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.substs.clone(),
|
||||
empty_builtin_bounds()) })))
|
||||
}
|
||||
|
||||
pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
|
||||
@ -4562,17 +4581,9 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_trait(box ty::TyTrait { def_id: d, store, bounds, .. }) => {
|
||||
ty_trait(box ty::TyTrait { def_id: d, bounds, .. }) => {
|
||||
byte!(17);
|
||||
did(&mut state, d);
|
||||
match store {
|
||||
UniqTraitStore => byte!(0),
|
||||
RegionTraitStore(r, m) => {
|
||||
byte!(1)
|
||||
region(&mut state, r);
|
||||
hash!(m);
|
||||
}
|
||||
}
|
||||
hash!(bounds);
|
||||
}
|
||||
ty_struct(d, _) => {
|
||||
|
@ -364,13 +364,11 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
store,
|
||||
bounds
|
||||
}) => {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: def_id,
|
||||
substs: substs.fold_with(this),
|
||||
store: store.fold_with(this),
|
||||
bounds: bounds
|
||||
})
|
||||
}
|
||||
|
@ -584,10 +584,25 @@ fn mk_pointer<AC:AstConv,
|
||||
return constr(ty::mk_vec(tcx, mt, None));
|
||||
}
|
||||
ast::TyUnboxedFn(ref unboxed_function) => {
|
||||
let trait_store = match ptr_ty {
|
||||
Uniq => ty::UniqTraitStore,
|
||||
let ty::TraitRef {
|
||||
def_id,
|
||||
substs
|
||||
} = trait_ref_for_unboxed_function(this,
|
||||
rscope,
|
||||
&**unboxed_function,
|
||||
None);
|
||||
let tr = ty::mk_trait(this.tcx(),
|
||||
def_id,
|
||||
substs,
|
||||
ty::empty_builtin_bounds());
|
||||
match ptr_ty {
|
||||
Uniq => {
|
||||
return ty::mk_uniq(this.tcx(), tr);
|
||||
}
|
||||
RPtr(r) => {
|
||||
ty::RegionTraitStore(r, a_seq_ty.mutbl)
|
||||
return ty::mk_rptr(this.tcx(),
|
||||
r,
|
||||
ty::mt {mutbl: a_seq_ty.mutbl, ty: tr});
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_err(
|
||||
@ -596,19 +611,8 @@ fn mk_pointer<AC:AstConv,
|
||||
forms of casting-to-trait");
|
||||
return ty::mk_err();
|
||||
}
|
||||
};
|
||||
let ty::TraitRef {
|
||||
def_id,
|
||||
substs
|
||||
} = trait_ref_for_unboxed_function(this,
|
||||
rscope,
|
||||
&**unboxed_function,
|
||||
None);
|
||||
return ty::mk_trait(this.tcx(),
|
||||
def_id,
|
||||
substs,
|
||||
trait_store,
|
||||
ty::empty_builtin_bounds());
|
||||
|
||||
}
|
||||
}
|
||||
ast::TyPath(ref path, ref bounds, id) => {
|
||||
// Note that the "bounds must be empty if path is not a trait"
|
||||
@ -651,11 +655,20 @@ fn mk_pointer<AC:AstConv,
|
||||
path.span,
|
||||
bounds,
|
||||
trait_store);
|
||||
return ty::mk_trait(tcx,
|
||||
result.def_id,
|
||||
result.substs.clone(),
|
||||
trait_store,
|
||||
bounds);
|
||||
let tr = ty::mk_trait(tcx,
|
||||
result.def_id,
|
||||
result.substs.clone(),
|
||||
bounds);
|
||||
// We could just match on ptr_ty, but we need to pass a trait
|
||||
// store to conv_builtin_bounds, so mathc twice for now.
|
||||
return match trait_store {
|
||||
ty::UniqTraitStore => {
|
||||
return ty::mk_uniq(tcx, tr);
|
||||
}
|
||||
ty::RegionTraitStore(r, m) => {
|
||||
return ty::mk_rptr(tcx, r, ty::mt{mutbl: m, ty: tr});
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -725,10 +725,10 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
|
||||
fcx.write_ty(pat_id, expected);
|
||||
};
|
||||
match *structure_of(fcx, span, expected) {
|
||||
ty::ty_uniq(e_inner) if pointer_kind == Send => {
|
||||
ty::ty_uniq(e_inner) if pointer_kind == Send && !ty::type_is_trait(e_inner) => {
|
||||
check_inner(e_inner);
|
||||
}
|
||||
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
|
||||
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed && !ty::type_is_trait(e_inner.ty) => {
|
||||
check_inner(e_inner.ty);
|
||||
}
|
||||
_ => {
|
||||
|
@ -277,14 +277,14 @@ fn construct_transformed_self_ty_for_object(
|
||||
match ty::get(transformed_self_ty).sty {
|
||||
ty::ty_rptr(r, mt) => { // must be SelfRegion
|
||||
let r = r.subst(tcx, rcvr_substs); // handle Early-Bound lifetime
|
||||
ty::mk_trait(tcx, trait_def_id, obj_substs,
|
||||
RegionTraitStore(r, mt.mutbl),
|
||||
ty::empty_builtin_bounds())
|
||||
let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
|
||||
ty::empty_builtin_bounds());
|
||||
ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: mt.mutbl })
|
||||
}
|
||||
ty::ty_uniq(_) => { // must be SelfUniq
|
||||
ty::mk_trait(tcx, trait_def_id, obj_substs,
|
||||
UniqTraitStore,
|
||||
ty::empty_builtin_bounds())
|
||||
let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
|
||||
ty::empty_builtin_bounds());
|
||||
ty::mk_uniq(tcx, tr)
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_bug(span,
|
||||
@ -433,10 +433,13 @@ impl<'a> LookupContext<'a> {
|
||||
let span = self.self_expr.map_or(self.span, |e| e.span);
|
||||
check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
|
||||
match get(self_ty).sty {
|
||||
ty_trait(box TyTrait { def_id, ref substs, .. }) => {
|
||||
self.push_inherent_candidates_from_object(def_id, substs);
|
||||
self.push_inherent_impl_candidates_for_type(def_id);
|
||||
}
|
||||
ty_uniq(ty) | ty_rptr(_, mt {ty, ..}) => match get(ty).sty{
|
||||
ty_trait(box TyTrait { def_id, ref substs, .. }) => {
|
||||
self.push_inherent_candidates_from_object(def_id, substs);
|
||||
self.push_inherent_impl_candidates_for_type(def_id);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
ty_enum(did, _) | ty_struct(did, _) => {
|
||||
if self.check_traits == CheckTraitsAndInherentMethods {
|
||||
self.push_inherent_impl_candidates_for_type(did);
|
||||
@ -774,6 +777,7 @@ impl<'a> LookupContext<'a> {
|
||||
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 => (0, ty::AutoBorrowVec(region, self_mt.mutbl)),
|
||||
ty::ty_trait(..) => (0, ty::AutoBorrowObj(region, self_mt.mutbl)),
|
||||
_ => (1, ty::AutoPtr(region, self_mt.mutbl)),
|
||||
};
|
||||
(ty::mk_rptr(tcx, region, self_mt),
|
||||
@ -781,18 +785,6 @@ impl<'a> LookupContext<'a> {
|
||||
autoderefs: autoderefs + extra_derefs,
|
||||
autoref: Some(auto)})
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id, ref substs, store: ty::RegionTraitStore(_, mutbl), bounds
|
||||
}) => {
|
||||
let region =
|
||||
self.infcx().next_region_var(infer::Autoref(self.span));
|
||||
(ty::mk_trait(tcx, def_id, substs.clone(),
|
||||
ty::RegionTraitStore(region, mutbl), bounds),
|
||||
ty::AutoDerefRef {
|
||||
autoderefs: autoderefs,
|
||||
autoref: Some(ty::AutoBorrowObj(region, mutbl))})
|
||||
}
|
||||
_ => {
|
||||
(self_ty,
|
||||
ty::AutoDerefRef {
|
||||
@ -862,6 +854,26 @@ impl<'a> LookupContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
// Coerce Box/&Trait instances to &Trait.
|
||||
fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
|
||||
match ty::get(ty).sty {
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: trt_did,
|
||||
substs: ref trt_substs,
|
||||
bounds: b,
|
||||
.. }) => {
|
||||
let tcx = self.tcx();
|
||||
self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
|
||||
|m, r| {
|
||||
let tr = ty::mk_trait(tcx, trt_did, trt_substs.clone(), b);
|
||||
ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
|
||||
})
|
||||
}
|
||||
_ => fail!("Expected ty_trait in auto_slice_trait")
|
||||
}
|
||||
}
|
||||
|
||||
fn search_for_autosliced_method(&self,
|
||||
self_ty: ty::t,
|
||||
autoderefs: uint)
|
||||
@ -871,38 +883,23 @@ impl<'a> LookupContext<'a> {
|
||||
* `~[]` to `&[]`.
|
||||
*/
|
||||
|
||||
let tcx = self.tcx();
|
||||
debug!("search_for_autosliced_method {}", ppaux::ty_to_str(tcx, self_ty));
|
||||
debug!("search_for_autosliced_method {}", ppaux::ty_to_str(self.tcx(), self_ty));
|
||||
|
||||
let sty = ty::get(self_ty).sty.clone();
|
||||
match sty {
|
||||
ty_rptr(_, mt) => match ty::get(mt.ty).sty {
|
||||
ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
|
||||
ty_trait(..) => self.auto_slice_trait(mt.ty, autoderefs),
|
||||
_ => None
|
||||
},
|
||||
ty_uniq(t) => match ty::get(t).sty {
|
||||
ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
|
||||
ty_str => self.auto_slice_str(autoderefs),
|
||||
ty_trait(..) => self.auto_slice_trait(t, autoderefs),
|
||||
_ => None
|
||||
},
|
||||
ty_vec(mt, Some(_)) => self.auto_slice_vec(mt, autoderefs),
|
||||
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: trt_did,
|
||||
substs: trt_substs,
|
||||
bounds: b,
|
||||
..
|
||||
}) => {
|
||||
// Coerce Box/&Trait instances to &Trait.
|
||||
|
||||
self.search_for_some_kind_of_autorefd_method(
|
||||
AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
|
||||
|m, r| {
|
||||
ty::mk_trait(tcx, trt_did, trt_substs.clone(),
|
||||
RegionTraitStore(r, m), b)
|
||||
})
|
||||
}
|
||||
|
||||
ty_closure(..) => {
|
||||
// This case should probably be handled similarly to
|
||||
// Trait instances.
|
||||
@ -1313,17 +1310,15 @@ impl<'a> LookupContext<'a> {
|
||||
ty::ty_rptr(_, mt) => {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => false,
|
||||
ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
|
||||
mutability_matches(mt.mutbl, m) &&
|
||||
rcvr_matches_object(self_did, candidate)
|
||||
}
|
||||
_ => mutability_matches(mt.mutbl, m) &&
|
||||
rcvr_matches_ty(self.fcx, mt.ty, candidate),
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: self_did, store: RegionTraitStore(_, self_m), ..
|
||||
}) => {
|
||||
mutability_matches(self_m, m) &&
|
||||
rcvr_matches_object(self_did, candidate)
|
||||
}
|
||||
|
||||
_ => false
|
||||
}
|
||||
@ -1335,16 +1330,13 @@ impl<'a> LookupContext<'a> {
|
||||
ty::ty_uniq(typ) => {
|
||||
match ty::get(typ).sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => false,
|
||||
ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
|
||||
rcvr_matches_object(self_did, candidate)
|
||||
}
|
||||
_ => rcvr_matches_ty(self.fcx, typ, candidate),
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: self_did, store: UniqTraitStore, ..
|
||||
}) => {
|
||||
rcvr_matches_object(self_did, candidate)
|
||||
}
|
||||
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -3021,7 +3021,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
else {
|
||||
match ty::get(t_1).sty {
|
||||
// This will be looked up later on
|
||||
ty::ty_trait(..) => (),
|
||||
_ if ty::type_is_trait(t_1) => {},
|
||||
|
||||
_ => {
|
||||
if ty::type_is_nil(t_e) {
|
||||
|
@ -546,15 +546,18 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
// explaining how it goes about doing that.
|
||||
let target_ty = rcx.resolve_node_type(expr.id);
|
||||
match ty::get(target_ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
store: ty::RegionTraitStore(trait_region, _), ..
|
||||
}) => {
|
||||
let source_ty = rcx.resolve_expr_type_adjusted(&**source);
|
||||
constrain_regions_in_type(
|
||||
rcx,
|
||||
trait_region,
|
||||
infer::RelateObjectBound(expr.span),
|
||||
source_ty);
|
||||
ty::ty_rptr(trait_region, ty::mt{ty, ..}) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(..) => {
|
||||
let source_ty = rcx.resolve_expr_type_adjusted(&**source);
|
||||
constrain_regions_in_type(
|
||||
rcx,
|
||||
trait_region,
|
||||
infer::RelateObjectBound(expr.span),
|
||||
source_ty);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
@ -302,6 +302,7 @@ fn search_for_vtable(vcx: &VtableContext,
|
||||
trait_ref: Rc<ty::TraitRef>,
|
||||
is_early: bool)
|
||||
-> Option<vtable_origin> {
|
||||
debug!("nrc - search_for_vtable");
|
||||
let tcx = vcx.tcx();
|
||||
|
||||
let mut found = Vec::new();
|
||||
@ -464,7 +465,6 @@ fn fixup_substs(vcx: &VtableContext,
|
||||
// use a dummy type just to package up the substs that need fixing up
|
||||
let t = ty::mk_trait(tcx,
|
||||
id, substs,
|
||||
ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable),
|
||||
ty::empty_builtin_bounds());
|
||||
fixup_ty(vcx, span, t, is_early).map(|t_f| {
|
||||
match ty::get(t_f).sty {
|
||||
@ -518,43 +518,50 @@ fn insert_vtables(fcx: &FnCtxt, vtable_key: MethodCall, vtables: vtable_res) {
|
||||
}
|
||||
|
||||
pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
fn mutability_allowed(a_mutbl: ast::Mutability,
|
||||
b_mutbl: ast::Mutability) -> bool {
|
||||
a_mutbl == b_mutbl ||
|
||||
(a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
|
||||
}
|
||||
|
||||
debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
|
||||
ex.id, is_early, expr_to_str(ex));
|
||||
let _indent = indenter();
|
||||
|
||||
let cx = fcx.ccx;
|
||||
let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t| {
|
||||
match ty::get(target_ty).sty {
|
||||
// Bounds of type's contents are not checked here, but in kind.rs.
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: target_def_id, substs: ref target_substs, store, ..
|
||||
}) => {
|
||||
fn mutability_allowed(a_mutbl: ast::Mutability,
|
||||
b_mutbl: ast::Mutability) -> bool {
|
||||
a_mutbl == b_mutbl ||
|
||||
(a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
|
||||
}
|
||||
// Look up vtables for the type we're casting to,
|
||||
// passing in the source and target type. The source
|
||||
// must be a pointer type suitable to the object sigil,
|
||||
// e.g.: `&x as &Trait` or `box x as Box<Trait>`
|
||||
let ty = structurally_resolved_type(fcx, ex.span,
|
||||
fcx.expr_ty(src));
|
||||
match (&ty::get(ty).sty, store) {
|
||||
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(_, mutbl))
|
||||
if !mutability_allowed(mt.mutbl, mutbl) => {
|
||||
// Look up vtables for the type we're casting to,
|
||||
// passing in the source and target type. The source
|
||||
// must be a pointer type suitable to the object sigil,
|
||||
// e.g.: `&x as &Trait` or `box x as Box<Trait>`
|
||||
// Bounds of type's contents are not checked here, but in kind.rs.
|
||||
let src_ty = structurally_resolved_type(fcx, ex.span,
|
||||
fcx.expr_ty(src));
|
||||
match (&ty::get(target_ty).sty, &ty::get(src_ty).sty) {
|
||||
(&ty::ty_rptr(_, ty::mt{ty, mutbl}), &ty::ty_rptr(_, mt))
|
||||
if !mutability_allowed(mt.mutbl, mutbl) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(..) => {
|
||||
fcx.tcx()
|
||||
.sess
|
||||
.span_err(ex.span, "types differ in mutability");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_uniq(..), ty::UniqTraitStore) |
|
||||
(&ty::ty_rptr(..), ty::RegionTraitStore(..)) => {
|
||||
let typ = match &ty::get(ty).sty {
|
||||
&ty::ty_box(typ) | &ty::ty_uniq(typ) => typ,
|
||||
&ty::ty_rptr(_, mt) => mt.ty,
|
||||
_ => fail!("shouldn't get here"),
|
||||
};
|
||||
(&ty::ty_uniq(ty), &ty::ty_uniq(..) ) |
|
||||
(&ty::ty_rptr(_, ty::mt{ty, ..}), &ty::ty_rptr(..)) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: target_def_id, substs: ref target_substs, ..
|
||||
}) => {
|
||||
debug!("nrc correct path");
|
||||
let typ = match &ty::get(src_ty).sty {
|
||||
&ty::ty_uniq(typ) => typ,
|
||||
&ty::ty_rptr(_, mt) => mt.ty,
|
||||
_ => fail!("shouldn't get here"),
|
||||
};
|
||||
|
||||
let vcx = fcx.vtable_context();
|
||||
|
||||
@ -594,38 +601,49 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
|
||||
// Now, if this is &trait, we need to link the
|
||||
// regions.
|
||||
match (&ty::get(ty).sty, store) {
|
||||
(&ty::ty_rptr(ra, _),
|
||||
ty::RegionTraitStore(rb, _)) => {
|
||||
match (&ty::get(src_ty).sty, &ty::get(target_ty).sty) {
|
||||
(&ty::ty_rptr(ra, _), &ty::ty_rptr(rb, _)) => {
|
||||
debug!("nrc - make subr");
|
||||
infer::mk_subr(fcx.infcx(),
|
||||
false,
|
||||
infer::RelateObjectBound(
|
||||
ex.span),
|
||||
infer::RelateObjectBound(ex.span),
|
||||
rb,
|
||||
ra);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
(_, ty::UniqTraitStore) => {
|
||||
(&ty::ty_uniq(ty), _) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(..) => {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
ex.span,
|
||||
format!("can only cast an boxed pointer \
|
||||
to a boxed object, not a {}",
|
||||
ty::ty_sort_str(fcx.tcx(), ty)).as_slice());
|
||||
ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
(_, ty::RegionTraitStore(..)) => {
|
||||
}
|
||||
(&ty::ty_rptr(_, ty::mt{ty, ..}), _) => {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_trait(..) => {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
ex.span,
|
||||
format!("can only cast an &-pointer \
|
||||
to an &-object, not a {}",
|
||||
ty::ty_sort_str(fcx.tcx(), ty)).as_slice());
|
||||
ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => { /* not a cast to a trait; ignore */ }
|
||||
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
match ex.node {
|
||||
@ -716,9 +734,17 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
ex.repr(fcx.tcx()),
|
||||
is_early);
|
||||
|
||||
let object_ty = ty::mk_trait(cx.tcx, def_id,
|
||||
substs.clone(),
|
||||
store, bounds);
|
||||
let trait_ty = ty::mk_trait(cx.tcx,
|
||||
def_id,
|
||||
substs.clone(),
|
||||
bounds);
|
||||
let object_ty = match store {
|
||||
ty::UniqTraitStore => ty::mk_uniq(cx.tcx, trait_ty),
|
||||
ty::RegionTraitStore(r, m) => {
|
||||
ty::mk_rptr(cx.tcx, r, ty::mt {ty: trait_ty, mutbl: m})
|
||||
}
|
||||
};
|
||||
|
||||
resolve_object_cast(ex, object_ty);
|
||||
}
|
||||
AutoAddEnv(..) => {}
|
||||
|
@ -74,10 +74,16 @@ fn get_base_type(inference_context: &InferCtxt,
|
||||
}
|
||||
|
||||
match get(resolved_type).sty {
|
||||
ty_enum(..) | ty_trait(..) | ty_struct(..) => {
|
||||
ty_enum(..) | ty_struct(..) => {
|
||||
debug!("(getting base type) found base type");
|
||||
Some(resolved_type)
|
||||
}
|
||||
// FIXME(14865) I would prefere to use `_` here, but that causes a
|
||||
// compiler error.
|
||||
ty_uniq(_) | ty_rptr(_, _) | ty_trait(..) if ty::type_is_trait(resolved_type) => {
|
||||
debug!("(getting base type) found base type (trait)");
|
||||
Some(resolved_type)
|
||||
}
|
||||
|
||||
ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
|
||||
ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
|
||||
@ -87,6 +93,7 @@ fn get_base_type(inference_context: &InferCtxt,
|
||||
get(original_type).sty);
|
||||
None
|
||||
}
|
||||
ty_trait(..) => fail!("should have been caught")
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,18 +115,10 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
|
||||
found_nominal = true;
|
||||
}
|
||||
}
|
||||
ty_trait(box ty::TyTrait { def_id, ref store, .. }) => {
|
||||
ty_trait(box ty::TyTrait { def_id, .. }) => {
|
||||
if def_id.krate == ast::LOCAL_CRATE {
|
||||
found_nominal = true;
|
||||
}
|
||||
if *store == ty::UniqTraitStore {
|
||||
match tcx.lang_items.owned_box() {
|
||||
Some(did) if did.krate == ast::LOCAL_CRATE => {
|
||||
found_nominal = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_uniq(..) => {
|
||||
match tcx.lang_items.owned_box() {
|
||||
@ -150,16 +149,22 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
|
||||
original_type: t)
|
||||
-> Option<DefId> {
|
||||
match get_base_type(inference_context, span, original_type) {
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
None => None,
|
||||
Some(base_type) => {
|
||||
match get(base_type).sty {
|
||||
ty_enum(def_id, _) |
|
||||
ty_struct(def_id, _) |
|
||||
ty_trait(box ty::TyTrait { def_id, .. }) => {
|
||||
return Some(def_id);
|
||||
ty_struct(def_id, _) => {
|
||||
Some(def_id)
|
||||
}
|
||||
ty_rptr(_, ty::mt {ty, ..}) | ty_uniq(ty) => match ty::get(ty).sty {
|
||||
ty_trait(box ty::TyTrait { def_id, .. }) => {
|
||||
Some(def_id)
|
||||
}
|
||||
_ => {
|
||||
fail!("get_base_type() returned a type that wasn't an \
|
||||
enum, struct, or trait");
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
fail!("get_base_type() returned a type that wasn't an \
|
||||
enum, struct, or trait");
|
||||
|
@ -100,7 +100,7 @@ impl<'f> Coerce<'f> {
|
||||
// Note: does not attempt to resolve type variables we encounter.
|
||||
// See above for details.
|
||||
match ty::get(b).sty {
|
||||
ty::ty_rptr(_, mt_b) => {
|
||||
ty::ty_rptr(r_b, mt_b) => {
|
||||
match ty::get(mt_b.ty).sty {
|
||||
ty::ty_vec(mt_b, None) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
@ -113,6 +113,28 @@ impl<'f> Coerce<'f> {
|
||||
self.coerce_borrowed_string(a, sty_a, b)
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
match *sty_a {
|
||||
ty::ty_rptr(_, mt_a) => match ty::get(mt_a.ty).sty {
|
||||
ty::ty_trait(..) => {
|
||||
self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
|
||||
}
|
||||
_ => self.coerce_object(a, sty_a, b, def_id, substs,
|
||||
ty::RegionTraitStore(r_b, mt_b.mutbl),
|
||||
bounds)
|
||||
},
|
||||
_ => self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(t) => return Ok(t),
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
|
||||
@ -121,6 +143,31 @@ impl<'f> Coerce<'f> {
|
||||
};
|
||||
}
|
||||
|
||||
ty::ty_uniq(t_b) => {
|
||||
match ty::get(t_b).sty {
|
||||
ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
match *sty_a {
|
||||
ty::ty_uniq(t_a) => match ty::get(t_a).sty {
|
||||
ty::ty_trait(..) => {
|
||||
Err(ty::terr_mismatch)
|
||||
}
|
||||
_ => self.coerce_object(a, sty_a, b, def_id, substs,
|
||||
ty::UniqTraitStore, bounds)
|
||||
},
|
||||
_ => Err(ty::terr_mismatch)
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(t) => return Ok(t),
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_closure(box ty::ClosureTy {
|
||||
store: ty::RegionTraitStore(..),
|
||||
..
|
||||
@ -136,44 +183,6 @@ impl<'f> Coerce<'f> {
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id, ref substs, store: ty::UniqTraitStore, bounds
|
||||
}) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
match *sty_a {
|
||||
ty::ty_uniq(..) => {
|
||||
self.coerce_object(a, sty_a, b, def_id, substs,
|
||||
ty::UniqTraitStore, bounds)
|
||||
}
|
||||
_ => Err(ty::terr_mismatch)
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(t) => return Ok(t),
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id, ref substs, store: ty::RegionTraitStore(region, m), bounds
|
||||
}) => {
|
||||
let result = self.unpack_actual_value(a, |sty_a| {
|
||||
match *sty_a {
|
||||
ty::ty_rptr(..) => {
|
||||
self.coerce_object(a, sty_a, b, def_id, substs,
|
||||
ty::RegionTraitStore(region, m), bounds)
|
||||
}
|
||||
_ => self.coerce_borrowed_object(a, sty_a, b, m)
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(t) => return Ok(t),
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -335,15 +344,20 @@ impl<'f> Coerce<'f> {
|
||||
let r_a = self.get_ref().infcx.next_region_var(coercion);
|
||||
|
||||
let a_borrowed = match *sty_a {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
ty::mk_trait(tcx, def_id, substs.clone(),
|
||||
ty::RegionTraitStore(r_a, b_mutbl), bounds)
|
||||
}
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
let tr = ty::mk_trait(tcx, def_id, substs.clone(), bounds);
|
||||
ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr })
|
||||
}
|
||||
_ => {
|
||||
return self.subtype(a, b);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return self.subtype(a, b);
|
||||
}
|
||||
|
@ -378,17 +378,19 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
// 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> {
|
||||
fn check_ptr_to_unsized<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, &ty::ty_str) => Ok(result),
|
||||
(&ty::ty_str, &ty::ty_str) |
|
||||
(&ty::ty_trait(..), &ty::ty_trait(..)) => Ok(result),
|
||||
(&ty::ty_vec(_, None), _) | (_, &ty::ty_vec(_, None)) |
|
||||
(&ty::ty_str, _) | (_, &ty::ty_str)
|
||||
(&ty::ty_str, _) | (_, &ty::ty_str) |
|
||||
(&ty::ty_trait(..), _) | (_, &ty::ty_trait(..))
|
||||
=> Err(ty::terr_sorts(expected_found(this, a, b))),
|
||||
_ => Ok(result),
|
||||
}
|
||||
@ -478,12 +480,10 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
if a_.def_id == b_.def_id => {
|
||||
debug!("Trying to match traits {:?} and {:?}", a, b);
|
||||
let substs = if_ok!(this.substs(a_.def_id, &a_.substs, &b_.substs));
|
||||
let s = if_ok!(this.trait_stores(ty::terr_trait, a_.store, b_.store));
|
||||
let bounds = if_ok!(this.bounds(a_.bounds, b_.bounds));
|
||||
Ok(ty::mk_trait(tcx,
|
||||
a_.def_id,
|
||||
substs.clone(),
|
||||
s,
|
||||
bounds))
|
||||
}
|
||||
|
||||
@ -499,18 +499,28 @@ 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));
|
||||
check_ptr_to_vec(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
|
||||
check_ptr_to_unsized(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));
|
||||
check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
|
||||
check_ptr_to_unsized(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));
|
||||
check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
|
||||
// FIXME(14985) If we have mutable references to trait objects, we
|
||||
// used to use covariant subtyping. I have preserved this behaviour,
|
||||
// even though it is probably incorrect. So don't go down the usual
|
||||
// path which would require invariance.
|
||||
let mt = match (&ty::get(a_mt.ty).sty, &ty::get(b_mt.ty).sty) {
|
||||
(&ty::ty_trait(..), &ty::ty_trait(..)) if a_mt.mutbl == b_mt.mutbl => {
|
||||
let ty = if_ok!(this.tys(a_mt.ty, b_mt.ty));
|
||||
ty::mt { ty: ty, mutbl: a_mt.mutbl }
|
||||
}
|
||||
_ => if_ok!(this.mts(a_mt, b_mt))
|
||||
};
|
||||
check_ptr_to_unsized(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)) => {
|
||||
|
@ -694,7 +694,6 @@ impl<'a> InferCtxt<'a> {
|
||||
let dummy0 = ty::mk_trait(self.tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.substs.clone(),
|
||||
ty::UniqTraitStore,
|
||||
ty::empty_builtin_bounds());
|
||||
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
|
||||
match ty::get(dummy1).sty {
|
||||
|
@ -390,7 +390,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
|
||||
parameterized(cx, base.as_slice(), substs, &generics)
|
||||
}
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: did, ref substs, store, ref bounds
|
||||
def_id: did, ref substs, ref bounds
|
||||
}) => {
|
||||
let base = ty::item_path_str(cx, did);
|
||||
let trait_def = ty::lookup_trait_def(cx, did);
|
||||
@ -398,8 +398,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
|
||||
substs, &trait_def.generics);
|
||||
let bound_sep = if bounds.is_empty() { "" } else { ":" };
|
||||
let bound_str = bounds.repr(cx);
|
||||
format!("{}{}{}{}",
|
||||
trait_store_to_str(cx, store),
|
||||
format!("{}{}{}",
|
||||
ty,
|
||||
bound_sep,
|
||||
bound_str)
|
||||
|
@ -233,7 +233,7 @@ use std::f64;
|
||||
use std::fmt;
|
||||
use std::io::MemWriter;
|
||||
use std::io;
|
||||
use std::mem::swap;
|
||||
use std::mem::{swap,transmute};
|
||||
use std::num;
|
||||
use std::str::ScalarValue;
|
||||
use std::str;
|
||||
@ -369,10 +369,11 @@ impl<'a> Encoder<'a> {
|
||||
pub fn buffer_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T) -> Vec<u8> {
|
||||
//Serialize the object in a string using a writer
|
||||
let mut m = MemWriter::new();
|
||||
{
|
||||
// FIXME(14302) remove the transmute and unsafe block.
|
||||
unsafe {
|
||||
let mut encoder = Encoder::new(&mut m as &mut io::Writer);
|
||||
// MemWriter never Errs
|
||||
let _ = to_encode_object.encode(&mut encoder);
|
||||
let _ = to_encode_object.encode(transmute(&mut encoder));
|
||||
}
|
||||
m.unwrap()
|
||||
}
|
||||
@ -543,8 +544,11 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
|
||||
// ref #12967, make sure to wrap a key in double quotes,
|
||||
// in the event that its of a type that omits them (eg numbers)
|
||||
let mut buf = MemWriter::new();
|
||||
let mut check_encoder = Encoder::new(&mut buf);
|
||||
try!(f(&mut check_encoder));
|
||||
// FIXME(14302) remove the transmute and unsafe block.
|
||||
unsafe {
|
||||
let mut check_encoder = Encoder::new(&mut buf);
|
||||
try!(f(transmute(&mut check_encoder)));
|
||||
}
|
||||
let buf = buf.unwrap();
|
||||
let out = from_utf8(buf.as_slice()).unwrap();
|
||||
let needs_wrapping = out.char_at(0) != '"' &&
|
||||
@ -778,8 +782,11 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
|
||||
// ref #12967, make sure to wrap a key in double quotes,
|
||||
// in the event that its of a type that omits them (eg numbers)
|
||||
let mut buf = MemWriter::new();
|
||||
let mut check_encoder = PrettyEncoder::new(&mut buf);
|
||||
try!(f(&mut check_encoder));
|
||||
// FIXME(14302) remove the transmute and unsafe block.
|
||||
unsafe {
|
||||
let mut check_encoder = PrettyEncoder::new(&mut buf);
|
||||
try!(f(transmute(&mut check_encoder)));
|
||||
}
|
||||
let buf = buf.unwrap();
|
||||
let out = from_utf8(buf.as_slice()).unwrap();
|
||||
let needs_wrapping = out.char_at(0) != '"' &&
|
||||
|
@ -281,6 +281,7 @@ mod test {
|
||||
use serialize::{json, Encodable};
|
||||
use std::io;
|
||||
use std::io::MemWriter;
|
||||
use std::mem::transmute;
|
||||
use std::str;
|
||||
use std::gc::GC;
|
||||
use codemap::{Span, BytePos, Spanned};
|
||||
@ -295,8 +296,11 @@ mod test {
|
||||
|
||||
fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> String {
|
||||
let mut writer = MemWriter::new();
|
||||
let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
|
||||
let _ = val.encode(&mut encoder);
|
||||
// FIXME(14302) remove the transmute and unsafe block.
|
||||
unsafe {
|
||||
let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
|
||||
let _ = val.encode(transmute(&mut encoder));
|
||||
}
|
||||
str::from_utf8(writer.unwrap().as_slice()).unwrap().to_string()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user