librustc: Separate out trait storage from evec/estr storage

This commit is contained in:
Patrick Walton 2013-03-08 21:16:09 -08:00
parent 3cee6763d1
commit 24a0de4e7f
23 changed files with 293 additions and 162 deletions

View file

@ -157,6 +157,16 @@ fn parse_vstore(st: @mut PState) -> ty::vstore {
} }
} }
fn parse_trait_store(st: @mut PState) -> ty::TraitStore {
match next(st) {
'~' => ty::UniqTraitStore,
'@' => ty::BoxTraitStore,
'&' => ty::RegionTraitStore(parse_region(st)),
'.' => ty::BareTraitStore,
c => st.tcx.sess.bug(fmt!("parse_trait_store(): bad input '%c'", c))
}
}
fn parse_substs(st: @mut PState, conv: conv_did) -> ty::substs { fn parse_substs(st: @mut PState, conv: conv_did) -> ty::substs {
let self_r = parse_opt(st, || parse_region(st) ); let self_r = parse_opt(st, || parse_region(st) );
@ -269,9 +279,9 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
fail_unless!(next(st) == '['); fail_unless!(next(st) == '[');
let def = parse_def(st, NominalType, conv); let def = parse_def(st, NominalType, conv);
let substs = parse_substs(st, conv); let substs = parse_substs(st, conv);
let vstore = parse_vstore(st); let store = parse_trait_store(st);
fail_unless!(next(st) == ']'); fail_unless!(next(st) == ']');
return ty::mk_trait(st.tcx, def, substs, vstore); return ty::mk_trait(st.tcx, def, substs, store);
} }
'p' => { 'p' => {
let did = parse_def(st, TypeParameter, conv); let did = parse_def(st, TypeParameter, conv);

View file

@ -214,6 +214,18 @@ pub fn enc_vstore(w: io::Writer, cx: @ctxt, v: ty::vstore) {
} }
} }
pub fn enc_trait_store(w: io::Writer, cx: @ctxt, s: ty::TraitStore) {
match s {
ty::UniqTraitStore => w.write_char('~'),
ty::BoxTraitStore => w.write_char('@'),
ty::BareTraitStore => w.write_char('.'),
ty::RegionTraitStore(re) => {
w.write_char('&');
enc_region(w, cx, re);
}
}
}
fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
match st { match st {
ty::ty_nil => w.write_char('n'), ty::ty_nil => w.write_char('n'),
@ -252,12 +264,12 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
enc_substs(w, cx, (*substs)); enc_substs(w, cx, (*substs));
w.write_char(']'); w.write_char(']');
} }
ty::ty_trait(def, ref substs, vstore) => { ty::ty_trait(def, ref substs, store) => {
w.write_str(&"x["); w.write_str(&"x[");
w.write_str((cx.ds)(def)); w.write_str((cx.ds)(def));
w.write_char('|'); w.write_char('|');
enc_substs(w, cx, (*substs)); enc_substs(w, cx, (*substs));
enc_vstore(w, cx, vstore); enc_trait_store(w, cx, store);
w.write_char(']'); w.write_char(']');
} }
ty::ty_tup(ts) => { ty::ty_tup(ts) => {

View file

@ -462,7 +462,7 @@ pub fn check_cast_for_escaping_regions(
pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) { pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) {
let target_ty = ty::expr_ty(cx.tcx, target); let target_ty = ty::expr_ty(cx.tcx, target);
match ty::get(target_ty).sty { match ty::get(target_ty).sty {
ty::ty_trait(_, _, ty::vstore_uniq) => { ty::ty_trait(_, _, ty::UniqTraitStore) => {
let source_ty = ty::expr_ty(cx.tcx, source); let source_ty = ty::expr_ty(cx.tcx, source);
if !ty::type_is_owned(cx.tcx, source_ty) { if !ty::type_is_owned(cx.tcx, source_ty) {
cx.tcx.sess.span_err( cx.tcx.sess.span_err(

View file

@ -802,13 +802,36 @@ pub fn trans_external_path(ccx: @CrateContext, did: ast::def_id, t: ty::t)
pub fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block { pub fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block {
let _icx = bcx.insn_ctxt("invoke_"); let _icx = bcx.insn_ctxt("invoke_");
if bcx.unreachable { return bcx; } if bcx.unreachable { return bcx; }
match bcx.node_info {
None => error!("invoke at ???"),
Some(node_info) => {
error!("invoke at %s",
bcx.sess().codemap.span_to_str(node_info.span));
}
}
if need_invoke(bcx) { if need_invoke(bcx) {
debug!("invoking"); unsafe {
debug!("invoking %x at %x",
::core::cast::transmute(llfn),
::core::cast::transmute(bcx.llbb));
for llargs.each |&llarg| {
debug!("arg: %x", ::core::cast::transmute(llarg));
}
}
let normal_bcx = sub_block(bcx, ~"normal return"); let normal_bcx = sub_block(bcx, ~"normal return");
Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx)); Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
return normal_bcx; return normal_bcx;
} else { } else {
debug!("calling"); unsafe {
debug!("calling %x at %x",
::core::cast::transmute(llfn),
::core::cast::transmute(bcx.llbb));
for llargs.each |&llarg| {
debug!("arg: %x", ::core::cast::transmute(llarg));
}
}
Call(bcx, llfn, llargs); Call(bcx, llfn, llargs);
return bcx; return bcx;
} }

View file

@ -1033,17 +1033,19 @@ pub fn T_captured_tydescs(cx: @CrateContext, n: uint) -> TypeRef {
return T_struct(vec::from_elem::<TypeRef>(n, T_ptr(cx.tydesc_type))); return T_struct(vec::from_elem::<TypeRef>(n, T_ptr(cx.tydesc_type)));
} }
pub fn T_opaque_trait(cx: @CrateContext, vstore: ty::vstore) -> TypeRef { pub fn T_opaque_trait(cx: @CrateContext, store: ty::TraitStore) -> TypeRef {
match vstore { match store {
ty::vstore_box => { ty::BoxTraitStore | ty::BareTraitStore => {
T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)]) T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)])
} }
ty::vstore_uniq => { ty::UniqTraitStore => {
T_struct(~[T_ptr(cx.tydesc_type), T_struct(~[T_ptr(cx.tydesc_type),
T_unique_ptr(T_unique(cx, T_i8())), T_unique_ptr(T_unique(cx, T_i8())),
T_ptr(cx.tydesc_type)]) T_ptr(cx.tydesc_type)])
} }
_ => T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())]) ty::RegionTraitStore(_) => {
T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())])
}
} }
} }

View file

@ -678,9 +678,9 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
} }
ast::expr_cast(val, _) => { ast::expr_cast(val, _) => {
match ty::get(node_id_type(bcx, expr.id)).sty { match ty::get(node_id_type(bcx, expr.id)).sty {
ty::ty_trait(_, _, vstore) => { ty::ty_trait(_, _, store) => {
return meth::trans_trait_cast(bcx, val, expr.id, dest, return meth::trans_trait_cast(bcx, val, expr.id, dest,
vstore); store);
} }
_ => { _ => {
bcx.tcx().sess.span_bug(expr.span, bcx.tcx().sess.span_bug(expr.span,

View file

@ -551,11 +551,12 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
ty::ty_closure(_) => { ty::ty_closure(_) => {
closure::make_closure_glue(bcx, v0, t, drop_ty) closure::make_closure_glue(bcx, v0, t, drop_ty)
} }
ty::ty_trait(_, _, ty::vstore_box) => { ty::ty_trait(_, _, ty::BoxTraitStore) |
ty::ty_trait(_, _, ty::BareTraitStore) => {
let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u])); let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u]));
decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx)) decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
} }
ty::ty_trait(_, _, ty::vstore_uniq) => { ty::ty_trait(_, _, ty::UniqTraitStore) => {
let lluniquevalue = GEPi(bcx, v0, [0, 1]); let lluniquevalue = GEPi(bcx, v0, [0, 1]);
let lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2])); let lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2]));
call_tydesc_glue_full(bcx, lluniquevalue, lltydesc, call_tydesc_glue_full(bcx, lluniquevalue, lltydesc,
@ -617,12 +618,13 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
ty::ty_closure(_) => { ty::ty_closure(_) => {
closure::make_closure_glue(bcx, v, t, take_ty) closure::make_closure_glue(bcx, v, t, take_ty)
} }
ty::ty_trait(_, _, ty::vstore_box) => { ty::ty_trait(_, _, ty::BoxTraitStore) |
ty::ty_trait(_, _, ty::BareTraitStore) => {
let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u])); let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u]));
incr_refcnt_of_boxed(bcx, llbox); incr_refcnt_of_boxed(bcx, llbox);
bcx bcx
} }
ty::ty_trait(_, _, ty::vstore_uniq) => { ty::ty_trait(_, _, ty::UniqTraitStore) => {
let llval = GEPi(bcx, v, [0, 1]); let llval = GEPi(bcx, v, [0, 1]);
let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2])); let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2]));
call_tydesc_glue_full(bcx, llval, lltydesc, call_tydesc_glue_full(bcx, llval, lltydesc,

View file

@ -249,12 +249,12 @@ pub fn trans_method_callee(bcx: block,
None => fail!(~"trans_method_callee: missing param_substs") None => fail!(~"trans_method_callee: missing param_substs")
} }
} }
typeck::method_trait(_, off, vstore) => { typeck::method_trait(_, off, store) => {
trans_trait_callee(bcx, trans_trait_callee(bcx,
callee_id, callee_id,
off, off,
self, self,
vstore, store,
mentry.explicit_self) mentry.explicit_self)
} }
typeck::method_self(*) | typeck::method_super(*) => { typeck::method_self(*) | typeck::method_super(*) => {
@ -570,7 +570,7 @@ pub fn trans_trait_callee(bcx: block,
callee_id: ast::node_id, callee_id: ast::node_id,
n_method: uint, n_method: uint,
self_expr: @ast::expr, self_expr: @ast::expr,
vstore: ty::vstore, store: ty::TraitStore,
explicit_self: ast::self_ty_) explicit_self: ast::self_ty_)
-> Callee { -> Callee {
//! //!
@ -599,7 +599,7 @@ pub fn trans_trait_callee(bcx: block,
callee_ty, callee_ty,
n_method, n_method,
llpair, llpair,
vstore, store,
explicit_self) explicit_self)
} }
@ -607,7 +607,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
callee_ty: ty::t, callee_ty: ty::t,
n_method: uint, n_method: uint,
llpair: ValueRef, llpair: ValueRef,
vstore: ty::vstore, store: ty::TraitStore,
explicit_self: ast::self_ty_) explicit_self: ast::self_ty_)
-> Callee { -> Callee {
//! //!
@ -641,16 +641,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
} }
ast::sty_by_ref => { ast::sty_by_ref => {
// We need to pass a pointer to a pointer to the payload. // We need to pass a pointer to a pointer to the payload.
match vstore { match store {
ty::vstore_box | ty::vstore_uniq => { ty::BoxTraitStore |
ty::BareTraitStore |
ty::UniqTraitStore => {
llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
} }
ty::vstore_slice(_) => { ty::RegionTraitStore(_) => {
llself = llbox; llself = llbox;
} }
ty::vstore_fixed(*) => {
bcx.tcx().sess.bug(~"vstore_fixed trait");
}
} }
self_mode = ast::by_ref; self_mode = ast::by_ref;
@ -662,16 +661,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
ast::sty_region(_) => { ast::sty_region(_) => {
// As before, we need to pass a pointer to a pointer to the // As before, we need to pass a pointer to a pointer to the
// payload. // payload.
match vstore { match store {
ty::vstore_box | ty::vstore_uniq => { ty::BoxTraitStore |
ty::BareTraitStore |
ty::UniqTraitStore => {
llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
} }
ty::vstore_slice(_) => { ty::RegionTraitStore(_) => {
llself = llbox; llself = llbox;
} }
ty::vstore_fixed(*) => {
bcx.tcx().sess.bug(~"vstore_fixed trait");
}
} }
let llscratch = alloca(bcx, val_ty(llself)); let llscratch = alloca(bcx, val_ty(llself));
@ -687,8 +685,8 @@ pub fn trans_trait_callee_from_llval(bcx: block,
bcx = glue::take_ty(bcx, llbox, callee_ty); bcx = glue::take_ty(bcx, llbox, callee_ty);
// Pass a pointer to the box. // Pass a pointer to the box.
match vstore { match store {
ty::vstore_box => llself = llbox, ty::BoxTraitStore | ty::BareTraitStore => llself = llbox,
_ => bcx.tcx().sess.bug(~"@self receiver with non-@Trait") _ => bcx.tcx().sess.bug(~"@self receiver with non-@Trait")
} }
@ -700,8 +698,8 @@ pub fn trans_trait_callee_from_llval(bcx: block,
} }
ast::sty_uniq(_) => { ast::sty_uniq(_) => {
// Pass the unique pointer. // Pass the unique pointer.
match vstore { match store {
ty::vstore_uniq => llself = llbox, ty::UniqTraitStore => llself = llbox,
_ => bcx.tcx().sess.bug(~"~self receiver with non-~Trait") _ => bcx.tcx().sess.bug(~"~self receiver with non-~Trait")
} }
@ -796,7 +794,9 @@ pub fn make_impl_vtable(ccx: @CrateContext,
// XXX: This should support multiple traits. // XXX: This should support multiple traits.
let trt_id = driver::session::expect( let trt_id = driver::session::expect(
tcx.sess, tcx.sess,
ty::ty_to_def_id(ty::impl_traits(tcx, impl_id, ty::vstore_box)[0]), ty::ty_to_def_id(ty::impl_traits(tcx,
impl_id,
ty::BoxTraitStore)[0]),
|| ~"make_impl_vtable: non-trait-type implemented"); || ~"make_impl_vtable: non-trait-type implemented");
let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u; let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
@ -834,7 +834,7 @@ pub fn trans_trait_cast(bcx: block,
val: @ast::expr, val: @ast::expr,
id: ast::node_id, id: ast::node_id,
dest: expr::Dest, dest: expr::Dest,
vstore: ty::vstore) store: ty::TraitStore)
-> block { -> block {
let mut bcx = bcx; let mut bcx = bcx;
let _icx = bcx.insn_ctxt("impl::trans_cast"); let _icx = bcx.insn_ctxt("impl::trans_cast");
@ -849,8 +849,8 @@ pub fn trans_trait_cast(bcx: block,
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let v_ty = expr_ty(bcx, val); let v_ty = expr_ty(bcx, val);
match vstore { match store {
ty::vstore_slice(*) | ty::vstore_box => { ty::RegionTraitStore(_) | ty::BoxTraitStore | ty::BareTraitStore => {
let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]); let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]);
// Just store the pointer into the pair. // Just store the pointer into the pair.
llboxdest = PointerCast(bcx, llboxdest = PointerCast(bcx,
@ -858,7 +858,7 @@ pub fn trans_trait_cast(bcx: block,
T_ptr(type_of(bcx.ccx(), v_ty))); T_ptr(type_of(bcx.ccx(), v_ty)));
bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
} }
ty::vstore_uniq => { ty::UniqTraitStore => {
// Translate the uniquely-owned value into the second element of // Translate the uniquely-owned value into the second element of
// the triple. (The first element is the vtable.) // the triple. (The first element is the vtable.)
let mut llvaldest = GEPi(bcx, lldest, [0, 1]); let mut llvaldest = GEPi(bcx, lldest, [0, 1]);
@ -874,10 +874,6 @@ pub fn trans_trait_cast(bcx: block,
let lltydescdest = GEPi(bcx, lldest, [0, 2]); let lltydescdest = GEPi(bcx, lldest, [0, 2]);
Store(bcx, tydesc.tydesc, lltydescdest); Store(bcx, tydesc.tydesc, lltydescdest);
} }
_ => {
bcx.tcx().sess.span_bug(val.span, ~"unexpected vstore in \
trans_trait_cast");
}
} }
// Store the vtable into the pair or triple. // Store the vtable into the pair or triple.

View file

@ -286,14 +286,11 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
ty::ty_closure(ref fty) => { ty::ty_closure(ref fty) => {
Some(normalized_closure_ty(tcx, fty.sigil)) Some(normalized_closure_ty(tcx, fty.sigil))
} }
ty::ty_trait(_, _, ref vstore) => { ty::ty_trait(_, _, ref store) => {
let sigil = match *vstore { let sigil = match *store {
ty::vstore_uniq => ast::OwnedSigil, ty::UniqTraitStore => ast::OwnedSigil,
ty::vstore_box => ast::ManagedSigil, ty::BoxTraitStore | ty::BareTraitStore => ast::ManagedSigil,
ty::vstore_slice(_) => ast::BorrowedSigil, ty::RegionTraitStore(_) => ast::BorrowedSigil,
ty::vstore_fixed(*) => {
tcx.sess.bug(fmt!("ty_trait with vstore_fixed"));
}
}; };
// Traits have the same runtime representation as closures. // Traits have the same runtime representation as closures.

View file

@ -96,14 +96,14 @@ pub impl Reflector {
} }
let bool_ty = ty::mk_bool(tcx); let bool_ty = ty::mk_bool(tcx);
let scratch = scratch_datum(bcx, bool_ty, false); let scratch = scratch_datum(bcx, bool_ty, false);
// XXX: Should not be vstore_box! // XXX: Should not be BoxTraitStore!
let bcx = callee::trans_call_inner( let bcx = callee::trans_call_inner(
self.bcx, None, mth_ty, bool_ty, self.bcx, None, mth_ty, bool_ty,
|bcx| meth::trans_trait_callee_from_llval(bcx, |bcx| meth::trans_trait_callee_from_llval(bcx,
mth_ty, mth_ty,
mth_idx, mth_idx,
v, v,
ty::vstore_box, ty::BoxTraitStore,
ast::sty_region( ast::sty_region(
ast::m_imm)), ast::m_imm)),
ArgVals(args), SaveIn(scratch.val), DontAutorefArg); ArgVals(args), SaveIn(scratch.val), DontAutorefArg);

View file

@ -130,7 +130,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_bare_fn(*) => T_ptr(T_i8()), ty::ty_bare_fn(*) => T_ptr(T_i8()),
ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]), ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore), ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size), ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size),
ty::ty_evec(mt, ty::vstore_fixed(size)) => { ty::ty_evec(mt, ty::vstore_fixed(size)) => {
@ -234,7 +234,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)), ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)), ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore), ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
ty::ty_type => T_ptr(cx.tydesc_type), ty::ty_type => T_ptr(cx.tydesc_type),
ty::ty_tup(*) => { ty::ty_tup(*) => {
let repr = adt::represent_type(cx, t); let repr = adt::represent_type(cx, t);

View file

@ -24,7 +24,7 @@ use middle::typeck;
use middle; use middle;
use util::ppaux::{note_and_explain_region, bound_region_to_str}; use util::ppaux::{note_and_explain_region, bound_region_to_str};
use util::ppaux::{region_to_str, explain_region, vstore_to_str}; use util::ppaux::{region_to_str, explain_region, vstore_to_str};
use util::ppaux::{ty_to_str, tys_to_str}; use util::ppaux::{trait_store_to_str, ty_to_str, tys_to_str};
use util::common::{indenter}; use util::common::{indenter};
use core::cast; use core::cast;
@ -84,6 +84,7 @@ pub struct mt {
#[auto_encode] #[auto_encode]
#[auto_decode] #[auto_decode]
#[deriving_eq]
pub enum vstore { pub enum vstore {
vstore_fixed(uint), vstore_fixed(uint),
vstore_uniq, vstore_uniq,
@ -91,6 +92,16 @@ pub enum vstore {
vstore_slice(Region) vstore_slice(Region)
} }
#[auto_encode]
#[auto_decode]
#[deriving_eq]
pub enum TraitStore {
BareTraitStore, // a plain trait without a sigil
BoxTraitStore, // @Trait
UniqTraitStore, // ~Trait
RegionTraitStore(Region), // &Trait
}
pub struct field_ty { pub struct field_ty {
ident: ident, ident: ident,
id: def_id, id: def_id,
@ -506,7 +517,7 @@ pub enum sty {
ty_rptr(Region, mt), ty_rptr(Region, mt),
ty_bare_fn(BareFnTy), ty_bare_fn(BareFnTy),
ty_closure(ClosureTy), ty_closure(ClosureTy),
ty_trait(def_id, substs, vstore), ty_trait(def_id, substs, TraitStore),
ty_struct(def_id, substs), ty_struct(def_id, substs),
ty_tup(~[t]), ty_tup(~[t]),
@ -565,6 +576,7 @@ pub enum type_err {
terr_regions_insufficiently_polymorphic(bound_region, Region), terr_regions_insufficiently_polymorphic(bound_region, Region),
terr_regions_overly_polymorphic(bound_region, Region), terr_regions_overly_polymorphic(bound_region, Region),
terr_vstores_differ(terr_vstore_kind, expected_found<vstore>), terr_vstores_differ(terr_vstore_kind, expected_found<vstore>),
terr_trait_stores_differ(terr_vstore_kind, expected_found<TraitStore>),
terr_in_field(@type_err, ast::ident), terr_in_field(@type_err, ast::ident),
terr_sorts(expected_found<t>), terr_sorts(expected_found<t>),
terr_self_substs, terr_self_substs,
@ -1048,10 +1060,13 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
} }
pub fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore) pub fn mk_trait(cx: ctxt,
-> t { did: ast::def_id,
+substs: substs,
store: TraitStore)
-> t {
// take a copy of substs so that we own the vectors inside // take a copy of substs so that we own the vectors inside
mk_t(cx, ty_trait(did, substs, vstore)) mk_t(cx, ty_trait(did, substs, store))
} }
pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, +substs: substs) -> t { pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, +substs: substs) -> t {
@ -1213,8 +1228,8 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
ty_enum(tid, ref substs) => { ty_enum(tid, ref substs) => {
ty_enum(tid, fold_substs(substs, fldop)) ty_enum(tid, fold_substs(substs, fldop))
} }
ty_trait(did, ref substs, vst) => { ty_trait(did, ref substs, st) => {
ty_trait(did, fold_substs(substs, fldop), vst) ty_trait(did, fold_substs(substs, fldop), st)
} }
ty_tup(ts) => { ty_tup(ts) => {
let new_ts = vec::map(ts, |tt| fldop(*tt)); let new_ts = vec::map(ts, |tt| fldop(*tt));
@ -1304,8 +1319,8 @@ pub fn fold_regions_and_ty(
ty_struct(def_id, ref substs) => { ty_struct(def_id, ref substs) => {
ty::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt)) ty::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt))
} }
ty_trait(def_id, ref substs, vst) => { ty_trait(def_id, ref substs, st) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst) ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st)
} }
ty_bare_fn(ref f) => { ty_bare_fn(ref f) => {
ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt), ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
@ -1893,15 +1908,16 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
TC_MANAGED + nonowned(tc_mt(cx, mt, cache)) TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
} }
ty_trait(_, _, vstore_uniq) => { ty_trait(_, _, UniqTraitStore) => {
TC_OWNED_CLOSURE TC_OWNED_CLOSURE
} }
ty_trait(_, _, vstore_box) => { ty_trait(_, _, BoxTraitStore) |
ty_trait(_, _, BareTraitStore) => {
TC_MANAGED TC_MANAGED
} }
ty_trait(_, _, vstore_slice(r)) => { ty_trait(_, _, RegionTraitStore(r)) => {
borrowed_contents(r, m_imm) borrowed_contents(r, m_imm)
} }
@ -2013,7 +2029,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
} }
ty_type => TC_NONE, ty_type => TC_NONE,
ty_trait(_, _, vstore_fixed(_)) => TC_NONE,
ty_err => { ty_err => {
cx.sess.bug(~"Asked to compute contents of fictitious type"); cx.sess.bug(~"Asked to compute contents of fictitious type");
@ -2557,6 +2572,17 @@ impl to_bytes::IterBytes for vstore {
} }
} }
impl to_bytes::IterBytes for TraitStore {
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
match *self {
BareTraitStore => 0u8.iter_bytes(lsb0, f),
UniqTraitStore => 1u8.iter_bytes(lsb0, f),
BoxTraitStore => 2u8.iter_bytes(lsb0, f),
RegionTraitStore(ref r) => to_bytes::iter_bytes_2(&3u8, r, lsb0, f),
}
}
}
impl to_bytes::IterBytes for substs { impl to_bytes::IterBytes for substs {
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
to_bytes::iter_bytes_3(&self.self_r, to_bytes::iter_bytes_3(&self.self_r,
@ -3419,6 +3445,11 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
vstore_to_str(cx, (*values).expected), vstore_to_str(cx, (*values).expected),
vstore_to_str(cx, (*values).found)) vstore_to_str(cx, (*values).found))
} }
terr_trait_stores_differ(_, ref values) => {
fmt!("trait storage differs: expected %s but found %s",
trait_store_to_str(cx, (*values).expected),
trait_store_to_str(cx, (*values).found))
}
terr_in_field(err, fname) => { terr_in_field(err, fname) => {
fmt!("in field `%s`, %s", *cx.sess.str_of(fname), fmt!("in field `%s`, %s", *cx.sess.str_of(fname),
type_err_to_str(cx, err)) type_err_to_str(cx, err))
@ -3565,12 +3596,19 @@ pub fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
/* /*
Could this return a list of (def_id, substs) pairs? Could this return a list of (def_id, substs) pairs?
*/ */
pub fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] { pub fn impl_traits(cx: ctxt, id: ast::def_id, store: TraitStore) -> ~[t] {
fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t { fn storeify(cx: ctxt, ty: t, store: TraitStore) -> t {
match ty::get(ty).sty { match ty::get(ty).sty {
ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty, ty::ty_trait(did, ref substs, trait_store) => {
ty::ty_trait(did, ref substs, _) => { if store == trait_store ||
mk_trait(cx, did, (/*bad*/copy *substs), vstore) (store == BareTraitStore &&
trait_store == BoxTraitStore) ||
(store == BoxTraitStore &&
trait_store == BareTraitStore) {
ty
} else {
mk_trait(cx, did, (/*bad*/copy *substs), store)
}
} }
_ => cx.sess.bug(~"impl_traits: not a trait") _ => cx.sess.bug(~"impl_traits: not a trait")
} }
@ -3585,16 +3623,16 @@ pub fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
_)) => { _)) => {
do option::map_default(&opt_trait, ~[]) |trait_ref| { do option::map_default(&opt_trait, ~[]) |trait_ref| {
~[vstoreify(cx, ~[storeify(cx,
node_id_to_type(cx, trait_ref.ref_id), node_id_to_type(cx, trait_ref.ref_id),
vstore)] store)]
} }
} }
_ => ~[] _ => ~[]
} }
} else { } else {
vec::map(csearch::get_impl_traits(cx, id), vec::map(csearch::get_impl_traits(cx, id),
|x| vstoreify(cx, *x, vstore)) |x| storeify(cx, *x, store))
} }
} }
@ -4163,6 +4201,9 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
t t
}, },
ty_trait(did, ref substs, BareTraitStore) =>
mk_trait(cx, did, copy *substs, BoxTraitStore),
_ => _ =>
t t
}; };
@ -4318,38 +4359,6 @@ impl cmp::Eq for mt {
pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) } pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) }
} }
impl cmp::Eq for vstore {
pure fn eq(&self, other: &vstore) -> bool {
match (*self) {
vstore_fixed(e0a) => {
match (*other) {
vstore_fixed(e0b) => e0a == e0b,
_ => false
}
}
vstore_uniq => {
match (*other) {
vstore_uniq => true,
_ => false
}
}
vstore_box => {
match (*other) {
vstore_box => true,
_ => false
}
}
vstore_slice(e0a) => {
match (*other) {
vstore_slice(e0b) => e0a == e0b,
_ => false
}
}
}
}
pure fn ne(&self, other: &vstore) -> bool { !(*self).eq(other) }
}
impl cmp::Eq for Region { impl cmp::Eq for Region {
pure fn eq(&self, other: &Region) -> bool { pure fn eq(&self, other: &Region) -> bool {
match (*self) { match (*self) {

View file

@ -249,20 +249,26 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
type_def_id, path); type_def_id, path);
match ty::get(result.ty).sty { match ty::get(result.ty).sty {
ty::ty_trait(trait_def_id, ref substs, _) => { ty::ty_trait(trait_def_id, ref substs, _) => {
match vst { let trait_store = match vst {
ty::vstore_box | ty::vstore_slice(*) | ty::vstore_box => ty::BoxTraitStore,
ty::vstore_uniq => {} ty::vstore_uniq => ty::UniqTraitStore,
_ => { ty::vstore_slice(r) => {
ty::RegionTraitStore(r)
}
ty::vstore_fixed(*) => {
tcx.sess.span_err( tcx.sess.span_err(
path.span, path.span,
~"@trait, ~trait or &trait \ ~"@trait, ~trait or &trait \
are the only supported \ are the only supported \
forms of casting-to-\ forms of casting-to-\
trait"); trait");
ty::BoxTraitStore
} }
} };
return ty::mk_trait(tcx, trait_def_id, return ty::mk_trait(tcx,
/*bad*/copy *substs, vst); trait_def_id,
/*bad*/copy *substs,
trait_store);
} }
_ => {} _ => {}

View file

@ -288,9 +288,9 @@ pub impl LookupContext/&self {
ty_param(p) => { ty_param(p) => {
self.push_inherent_candidates_from_param(self_ty, p); self.push_inherent_candidates_from_param(self_ty, p);
} }
ty_trait(did, ref substs, vstore) => { ty_trait(did, ref substs, store) => {
self.push_inherent_candidates_from_trait( self.push_inherent_candidates_from_trait(
self_ty, did, substs, vstore); self_ty, did, substs, store);
self.push_inherent_impl_candidates_for_type(did); self.push_inherent_impl_candidates_for_type(did);
} }
ty_self => { ty_self => {
@ -490,7 +490,7 @@ pub impl LookupContext/&self {
self_ty: ty::t, self_ty: ty::t,
did: def_id, did: def_id,
substs: &ty::substs, substs: &ty::substs,
vstore: ty::vstore) { store: ty::TraitStore) {
debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)", debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)",
self.did_to_str(did), self.did_to_str(did),
substs_to_str(self.tcx(), substs)); substs_to_str(self.tcx(), substs));
@ -539,7 +539,7 @@ pub impl LookupContext/&self {
explicit_self: method.self_ty, explicit_self: method.self_ty,
num_method_tps: method.tps.len(), num_method_tps: method.tps.len(),
self_mode: get_mode_from_self_type(method.self_ty), self_mode: get_mode_from_self_type(method.self_ty),
origin: method_trait(did, index, vstore) origin: method_trait(did, index, store)
}); });
} }

View file

@ -263,7 +263,7 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
// explaining how it goes about doing that. // explaining how it goes about doing that.
let target_ty = rcx.resolve_node_type(expr.id); let target_ty = rcx.resolve_node_type(expr.id);
match ty::get(target_ty).sty { match ty::get(target_ty).sty {
ty::ty_trait(_, _, vstore_slice(trait_region)) => { ty::ty_trait(_, _, ty::RegionTraitStore(trait_region)) => {
let source_ty = rcx.fcx.expr_ty(source); let source_ty = rcx.fcx.expr_ty(source);
constrain_regions_in_type(rcx, trait_region, constrain_regions_in_type(rcx, trait_region,
expr.span, source_ty); expr.span, source_ty);

View file

@ -140,7 +140,9 @@ pub fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
is_early: bool) -> Option<ty::substs> { is_early: bool) -> Option<ty::substs> {
let tcx = vcx.tcx(); let tcx = vcx.tcx();
// use a dummy type just to package up the substs that need fixing up // use a dummy type just to package up the substs that need fixing up
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static)); let t = ty::mk_trait(tcx,
id, substs,
ty::RegionTraitStore(ty::re_static));
do fixup_ty(vcx, location_info, t, is_early).map |t_f| { do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
match ty::get(*t_f).sty { match ty::get(*t_f).sty {
ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f), ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f),
@ -167,9 +169,9 @@ pub fn lookup_vtable(vcx: &VtableContext,
let _i = indenter(); let _i = indenter();
let tcx = vcx.tcx(); let tcx = vcx.tcx();
let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty { let (trait_id, trait_substs, trait_store) = match ty::get(trait_ty).sty {
ty::ty_trait(did, ref substs, vstore) => ty::ty_trait(did, ref substs, store) =>
(did, (/*bad*/copy *substs), vstore), (did, (/*bad*/copy *substs), store),
_ => tcx.sess.impossible_case(location_info.span, _ => tcx.sess.impossible_case(location_info.span,
"lookup_vtable: \ "lookup_vtable: \
don't know how to handle a non-trait") don't know how to handle a non-trait")
@ -261,8 +263,9 @@ pub fn lookup_vtable(vcx: &VtableContext,
// it's the same trait as trait_ty, we need to // it's the same trait as trait_ty, we need to
// unify it with trait_ty in order to get all // unify it with trait_ty in order to get all
// the ty vars sorted out. // the ty vars sorted out.
for vec::each(ty::impl_traits(tcx, im.did, for vec::each(ty::impl_traits(tcx,
trait_vstore)) |of_ty| { im.did,
trait_store)) |of_ty| {
match ty::get(*of_ty).sty { match ty::get(*of_ty).sty {
ty::ty_trait(id, _, _) => { ty::ty_trait(id, _, _) => {
// Not the trait we're looking for // Not the trait we're looking for
@ -381,7 +384,7 @@ pub fn lookup_vtable(vcx: &VtableContext,
/*bad*/copy substs_f.tps, /*bad*/copy substs_f.tps,
trait_tps, trait_tps,
im.did, im.did,
trait_vstore); trait_store);
let subres = lookup_vtables( let subres = lookup_vtables(
vcx, location_info, im_bs, &substs_f, vcx, location_info, im_bs, &substs_f,
is_early); is_early);
@ -455,11 +458,11 @@ pub fn connect_trait_tps(vcx: &VtableContext,
impl_tys: ~[ty::t], impl_tys: ~[ty::t],
trait_tys: ~[ty::t], trait_tys: ~[ty::t],
impl_did: ast::def_id, impl_did: ast::def_id,
vstore: ty::vstore) { store: ty::TraitStore) {
let tcx = vcx.tcx(); let tcx = vcx.tcx();
// XXX: This should work for multiple traits. // XXX: This should work for multiple traits.
let ity = ty::impl_traits(tcx, impl_did, vstore)[0]; let ity = ty::impl_traits(tcx, impl_did, store)[0];
let trait_ty = ty::subst_tps(tcx, impl_tys, None, ity); let trait_ty = ty::subst_tps(tcx, impl_tys, None, ity);
debug!("(connect trait tps) trait type is %?, impl did is %?", debug!("(connect trait tps) trait type is %?, impl did is %?",
ty::get(trait_ty).sty, impl_did); ty::get(trait_ty).sty, impl_did);
@ -557,17 +560,19 @@ pub fn early_resolve_expr(ex: @ast::expr,
ast::expr_cast(src, _) => { ast::expr_cast(src, _) => {
let target_ty = fcx.expr_ty(ex); let target_ty = fcx.expr_ty(ex);
match ty::get(target_ty).sty { match ty::get(target_ty).sty {
ty::ty_trait(_, _, vstore) => { ty::ty_trait(_, _, store) => {
// Look up vtables for the type we're casting to, // Look up vtables for the type we're casting to,
// passing in the source and target type. The source // passing in the source and target type. The source
// must be a pointer type suitable to the object sigil, // must be a pointer type suitable to the object sigil,
// e.g.: `@x as @Trait`, `&x as &Trait` or `~x as ~Trait` // e.g.: `@x as @Trait`, `&x as &Trait` or `~x as ~Trait`
let ty = structurally_resolved_type(fcx, ex.span, let ty = structurally_resolved_type(fcx, ex.span,
fcx.expr_ty(src)); fcx.expr_ty(src));
match (&ty::get(ty).sty, vstore) { match (&ty::get(ty).sty, store) {
(&ty::ty_box(mt), ty::vstore_box) | (&ty::ty_box(mt), ty::BoxTraitStore) |
(&ty::ty_uniq(mt), ty::vstore_uniq) | // XXX: Bare trait store is deprecated.
(&ty::ty_rptr(_, mt), ty::vstore_slice(*)) => { (&ty::ty_box(mt), ty::BareTraitStore) |
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(*)) => {
let location_info = let location_info =
&location_info_for_expr(ex); &location_info_for_expr(ex);
let vcx = VtableContext { let vcx = VtableContext {
@ -604,9 +609,9 @@ pub fn early_resolve_expr(ex: @ast::expr,
// Now, if this is &trait, we need to link the // Now, if this is &trait, we need to link the
// regions. // regions.
match (&ty::get(ty).sty, vstore) { match (&ty::get(ty).sty, store) {
(&ty::ty_rptr(ra, _), (&ty::ty_rptr(ra, _),
ty::vstore_slice(rb)) => { ty::RegionTraitStore(rb)) => {
infer::mk_subr(fcx.infcx(), infer::mk_subr(fcx.infcx(),
false, false,
ex.span, ex.span,
@ -617,7 +622,8 @@ pub fn early_resolve_expr(ex: @ast::expr,
} }
} }
(_, ty::vstore_box(*)) => { // XXX: Remove bare below.
(_, ty::BoxTraitStore) | (_, ty::BareTraitStore) => {
fcx.ccx.tcx.sess.span_err( fcx.ccx.tcx.sess.span_err(
ex.span, ex.span,
fmt!("can only cast an @-pointer \ fmt!("can only cast an @-pointer \
@ -625,7 +631,7 @@ pub fn early_resolve_expr(ex: @ast::expr,
ty::ty_sort_str(fcx.tcx(), ty))); ty::ty_sort_str(fcx.tcx(), ty)));
} }
(_, ty::vstore_uniq(*)) => { (_, ty::UniqTraitStore) => {
fcx.ccx.tcx.sess.span_err( fcx.ccx.tcx.sess.span_err(
ex.span, ex.span,
fmt!("can only cast an ~-pointer \ fmt!("can only cast an ~-pointer \
@ -633,19 +639,13 @@ pub fn early_resolve_expr(ex: @ast::expr,
ty::ty_sort_str(fcx.tcx(), ty))); ty::ty_sort_str(fcx.tcx(), ty)));
} }
(_, ty::vstore_slice(*)) => { (_, ty::RegionTraitStore(_)) => {
fcx.ccx.tcx.sess.span_err( fcx.ccx.tcx.sess.span_err(
ex.span, ex.span,
fmt!("can only cast an &-pointer \ fmt!("can only cast an &-pointer \
to an &-object, not a %s", to an &-object, not a %s",
ty::ty_sort_str(fcx.tcx(), ty))); ty::ty_sort_str(fcx.tcx(), ty)));
} }
(_, ty::vstore_fixed(*)) => {
fcx.tcx().sess.span_bug(
ex.span,
fmt!("trait with fixed vstore"));
}
} }
} }
_ => { /* not a cast to a trait; ignore */ } _ => { /* not a cast to a trait; ignore */ }

View file

@ -81,8 +81,10 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
match intrinsic_item.node { match intrinsic_item.node {
ast::item_trait(*) => { ast::item_trait(*) => {
let ty = ty::mk_trait(ccx.tcx, def_id, substs, let ty = ty::mk_trait(ccx.tcx,
ty::vstore_box); def_id,
substs,
ty::BareTraitStore);
ccx.tcx.intrinsic_defs.insert ccx.tcx.intrinsic_defs.insert
(intrinsic_item.ident, (def_id, ty)); (intrinsic_item.ident, (def_id, ty));
} }
@ -893,7 +895,10 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
} }
ast::item_trait(ref generics, _, _) => { ast::item_trait(ref generics, _, _) => {
let (bounds, substs) = mk_substs(ccx, generics, rp); let (bounds, substs) = mk_substs(ccx, generics, rp);
let t = ty::mk_trait(tcx, local_def(it.id), substs, ty::vstore_box); let t = ty::mk_trait(tcx,
local_def(it.id),
substs,
ty::BareTraitStore);
let tpt = ty_param_bounds_and_ty { let tpt = ty_param_bounds_and_ty {
bounds: bounds, bounds: bounds,
region_param: rp, region_param: rp,

View file

@ -102,10 +102,16 @@ pub trait Combine {
fn purities(&self, a: purity, b: purity) -> cres<purity>; fn purities(&self, a: purity, b: purity) -> cres<purity>;
fn abis(&self, a: ast::Abi, b: ast::Abi) -> cres<ast::Abi>; fn abis(&self, a: ast::Abi, b: ast::Abi) -> cres<ast::Abi>;
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<Onceness>; fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<Onceness>;
fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>; fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<ty::Region>;
fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>; fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
fn vstores(&self, vk: ty::terr_vstore_kind, fn vstores(&self, vk: ty::terr_vstore_kind,
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>; a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>;
fn trait_stores(&self,
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore>;
} }
pub struct CombineFields { pub struct CombineFields {
@ -349,6 +355,36 @@ pub fn super_vstores<C:Combine>(
} }
} }
pub fn super_trait_stores<C:Combine>(self: &C,
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
match (a, b) {
(ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
do self.contraregions(a_r, b_r).chain |r| {
Ok(ty::RegionTraitStore(r))
}
}
// XXX: This should go away soon.
(ty::BareTraitStore, ty::BoxTraitStore) |
(ty::BoxTraitStore, ty::BareTraitStore) => {
Ok(ty::BoxTraitStore)
}
_ if a == b => {
Ok(a)
}
_ => {
Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
}
}
}
pub fn super_closure_tys<C:Combine>( pub fn super_closure_tys<C:Combine>(
self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy> self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
{ {
@ -491,12 +527,12 @@ pub fn super_tys<C:Combine>(
} }
} }
(ty::ty_trait(a_id, ref a_substs, a_vstore), (ty::ty_trait(a_id, ref a_substs, a_store),
ty::ty_trait(b_id, ref b_substs, b_vstore)) ty::ty_trait(b_id, ref b_substs, b_store))
if a_id == b_id => { if a_id == b_id => {
do self.substs(a_id, a_substs, b_substs).chain |substs| { do self.substs(a_id, a_substs, b_substs).chain |substs| {
do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| { do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, vs)) Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s))
} }
} }
} }

View file

@ -145,6 +145,14 @@ impl Combine for Glb {
super_vstores(self, vk, a, b) super_vstores(self, vk, a, b)
} }
fn trait_stores(&self,
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> { fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b) super_modes(self, a, b)
} }

View file

@ -227,6 +227,14 @@ impl Combine for Lub {
super_vstores(self, vk, a, b) super_vstores(self, vk, a, b)
} }
fn trait_stores(&self,
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> { fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b) super_modes(self, a, b)
} }

View file

@ -239,6 +239,14 @@ impl Combine for Sub {
super_vstores(self, vk, a, b) super_vstores(self, vk, a, b)
} }
fn trait_stores(&self,
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> { fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b) super_modes(self, a, b)
} }

View file

@ -90,7 +90,7 @@ pub enum method_origin {
method_param(method_param), method_param(method_param),
// method invoked on a trait instance // method invoked on a trait instance
method_trait(ast::def_id, uint, ty::vstore), method_trait(ast::def_id, uint, ty::TraitStore),
// method invoked on "self" inside a default method // method invoked on "self" inside a default method
method_self(ast::def_id, uint) method_self(ast::def_id, uint)

View file

@ -237,6 +237,15 @@ pub fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str {
} }
} }
pub fn trait_store_to_str(cx: ctxt, s: ty::TraitStore) -> ~str {
match s {
ty::BareTraitStore => ~"",
ty::UniqTraitStore => ~"~",
ty::BoxTraitStore => ~"@",
ty::RegionTraitStore(r) => region_to_str_adorned(cx, "&", r, "")
}
}
pub fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str { pub fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
match vs { match vs {
ty::vstore_fixed(_) => { ty::vstore_fixed(_) => {
@ -441,11 +450,11 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
let base = ast_map::path_to_str(path, cx.sess.intr()); let base = ast_map::path_to_str(path, cx.sess.intr());
parameterized(cx, base, substs.self_r, substs.tps) parameterized(cx, base, substs.self_r, substs.tps)
} }
ty_trait(did, ref substs, vs) => { ty_trait(did, ref substs, s) => {
let path = ty::item_path(cx, did); let path = ty::item_path(cx, did);
let base = ast_map::path_to_str(path, cx.sess.intr()); let base = ast_map::path_to_str(path, cx.sess.intr());
let ty = parameterized(cx, base, substs.self_r, substs.tps); let ty = parameterized(cx, base, substs.self_r, substs.tps);
fmt!("%s%s", vstore_to_str(cx, vs), ty) fmt!("%s%s", trait_store_to_str(cx, s), ty)
} }
ty_evec(mt, vs) => { ty_evec(mt, vs) => {
vstore_ty_to_str(cx, fmt!("%s", mt_to_str(cx, mt)), vs) vstore_ty_to_str(cx, fmt!("%s", mt_to_str(cx, mt)), vs)