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:
bors 2014-06-18 00:16:37 +00:00
commit 5c81a186e9
30 changed files with 451 additions and 364 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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

View File

@ -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,
..

View File

@ -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, _),

View File

@ -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
}

View File

@ -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));

View File

@ -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 {

View File

@ -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),
}
}

View File

@ -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

View File

@ -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,

View File

@ -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));

View File

@ -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);

View File

@ -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"),

View File

@ -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")

View File

@ -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, _) => {

View File

@ -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
})
}

View File

@ -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});
}
}
}
_ => {}
}

View File

@ -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);
}
_ => {

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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);
}
_ => {}
}
}
_ => ()
}

View File

@ -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(..) => {}

View File

@ -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");

View File

@ -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);
}

View File

@ -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)) => {

View File

@ -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 {

View File

@ -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)

View File

@ -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) != '"' &&

View File

@ -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()
}