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 {
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) == '[');
let def = parse_def(st, NominalType, conv);
let substs = parse_substs(st, conv);
let vstore = parse_vstore(st);
let store = parse_trait_store(st);
fail_unless!(next(st) == ']');
return ty::mk_trait(st.tcx, def, substs, vstore);
return ty::mk_trait(st.tcx, def, substs, store);
}
'p' => {
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) {
match st {
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));
w.write_char(']');
}
ty::ty_trait(def, ref substs, vstore) => {
ty::ty_trait(def, ref substs, store) => {
w.write_str(&"x[");
w.write_str((cx.ds)(def));
w.write_char('|');
enc_substs(w, cx, (*substs));
enc_vstore(w, cx, vstore);
enc_trait_store(w, cx, store);
w.write_char(']');
}
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) {
let target_ty = ty::expr_ty(cx.tcx, target);
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);
if !ty::type_is_owned(cx.tcx, source_ty) {
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 {
let _icx = bcx.insn_ctxt("invoke_");
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) {
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");
Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
return normal_bcx;
} 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);
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)));
}
pub fn T_opaque_trait(cx: @CrateContext, vstore: ty::vstore) -> TypeRef {
match vstore {
ty::vstore_box => {
pub fn T_opaque_trait(cx: @CrateContext, store: ty::TraitStore) -> TypeRef {
match store {
ty::BoxTraitStore | ty::BareTraitStore => {
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_unique_ptr(T_unique(cx, T_i8())),
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, _) => {
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,
vstore);
store);
}
_ => {
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(_) => {
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]));
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 lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2]));
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(_) => {
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]));
incr_refcnt_of_boxed(bcx, llbox);
bcx
}
ty::ty_trait(_, _, ty::vstore_uniq) => {
ty::ty_trait(_, _, ty::UniqTraitStore) => {
let llval = GEPi(bcx, v, [0, 1]);
let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2]));
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")
}
}
typeck::method_trait(_, off, vstore) => {
typeck::method_trait(_, off, store) => {
trans_trait_callee(bcx,
callee_id,
off,
self,
vstore,
store,
mentry.explicit_self)
}
typeck::method_self(*) | typeck::method_super(*) => {
@ -570,7 +570,7 @@ pub fn trans_trait_callee(bcx: block,
callee_id: ast::node_id,
n_method: uint,
self_expr: @ast::expr,
vstore: ty::vstore,
store: ty::TraitStore,
explicit_self: ast::self_ty_)
-> Callee {
//!
@ -599,7 +599,7 @@ pub fn trans_trait_callee(bcx: block,
callee_ty,
n_method,
llpair,
vstore,
store,
explicit_self)
}
@ -607,7 +607,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
callee_ty: ty::t,
n_method: uint,
llpair: ValueRef,
vstore: ty::vstore,
store: ty::TraitStore,
explicit_self: ast::self_ty_)
-> Callee {
//!
@ -641,16 +641,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
}
ast::sty_by_ref => {
// We need to pass a pointer to a pointer to the payload.
match vstore {
ty::vstore_box | ty::vstore_uniq => {
match store {
ty::BoxTraitStore |
ty::BareTraitStore |
ty::UniqTraitStore => {
llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
}
ty::vstore_slice(_) => {
ty::RegionTraitStore(_) => {
llself = llbox;
}
ty::vstore_fixed(*) => {
bcx.tcx().sess.bug(~"vstore_fixed trait");
}
}
self_mode = ast::by_ref;
@ -662,16 +661,15 @@ pub fn trans_trait_callee_from_llval(bcx: block,
ast::sty_region(_) => {
// As before, we need to pass a pointer to a pointer to the
// payload.
match vstore {
ty::vstore_box | ty::vstore_uniq => {
match store {
ty::BoxTraitStore |
ty::BareTraitStore |
ty::UniqTraitStore => {
llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
}
ty::vstore_slice(_) => {
ty::RegionTraitStore(_) => {
llself = llbox;
}
ty::vstore_fixed(*) => {
bcx.tcx().sess.bug(~"vstore_fixed trait");
}
}
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);
// Pass a pointer to the box.
match vstore {
ty::vstore_box => llself = llbox,
match store {
ty::BoxTraitStore | ty::BareTraitStore => llself = llbox,
_ => 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(_) => {
// Pass the unique pointer.
match vstore {
ty::vstore_uniq => llself = llbox,
match store {
ty::UniqTraitStore => llself = llbox,
_ => 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.
let trt_id = driver::session::expect(
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");
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,
id: ast::node_id,
dest: expr::Dest,
vstore: ty::vstore)
store: ty::TraitStore)
-> block {
let mut bcx = bcx;
let _icx = bcx.insn_ctxt("impl::trans_cast");
@ -849,8 +849,8 @@ pub fn trans_trait_cast(bcx: block,
let ccx = bcx.ccx();
let v_ty = expr_ty(bcx, val);
match vstore {
ty::vstore_slice(*) | ty::vstore_box => {
match store {
ty::RegionTraitStore(_) | ty::BoxTraitStore | ty::BareTraitStore => {
let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]);
// Just store the pointer into the pair.
llboxdest = PointerCast(bcx,
@ -858,7 +858,7 @@ pub fn trans_trait_cast(bcx: block,
T_ptr(type_of(bcx.ccx(), v_ty)));
bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
}
ty::vstore_uniq => {
ty::UniqTraitStore => {
// Translate the uniquely-owned value into the second element of
// the triple. (The first element is the vtable.)
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]);
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.

View file

@ -286,14 +286,11 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
ty::ty_closure(ref fty) => {
Some(normalized_closure_ty(tcx, fty.sigil))
}
ty::ty_trait(_, _, ref vstore) => {
let sigil = match *vstore {
ty::vstore_uniq => ast::OwnedSigil,
ty::vstore_box => ast::ManagedSigil,
ty::vstore_slice(_) => ast::BorrowedSigil,
ty::vstore_fixed(*) => {
tcx.sess.bug(fmt!("ty_trait with vstore_fixed"));
}
ty::ty_trait(_, _, ref store) => {
let sigil = match *store {
ty::UniqTraitStore => ast::OwnedSigil,
ty::BoxTraitStore | ty::BareTraitStore => ast::ManagedSigil,
ty::RegionTraitStore(_) => ast::BorrowedSigil,
};
// 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 scratch = scratch_datum(bcx, bool_ty, false);
// XXX: Should not be vstore_box!
// XXX: Should not be BoxTraitStore!
let bcx = callee::trans_call_inner(
self.bcx, None, mth_ty, bool_ty,
|bcx| meth::trans_trait_callee_from_llval(bcx,
mth_ty,
mth_idx,
v,
ty::vstore_box,
ty::BoxTraitStore,
ast::sty_region(
ast::m_imm)),
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_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_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_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_tup(*) => {
let repr = adt::represent_type(cx, t);

View file

@ -24,7 +24,7 @@ use middle::typeck;
use middle;
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::{ty_to_str, tys_to_str};
use util::ppaux::{trait_store_to_str, ty_to_str, tys_to_str};
use util::common::{indenter};
use core::cast;
@ -84,6 +84,7 @@ pub struct mt {
#[auto_encode]
#[auto_decode]
#[deriving_eq]
pub enum vstore {
vstore_fixed(uint),
vstore_uniq,
@ -91,6 +92,16 @@ pub enum vstore {
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 {
ident: ident,
id: def_id,
@ -506,7 +517,7 @@ pub enum sty {
ty_rptr(Region, mt),
ty_bare_fn(BareFnTy),
ty_closure(ClosureTy),
ty_trait(def_id, substs, vstore),
ty_trait(def_id, substs, TraitStore),
ty_struct(def_id, substs),
ty_tup(~[t]),
@ -565,6 +576,7 @@ pub enum type_err {
terr_regions_insufficiently_polymorphic(bound_region, Region),
terr_regions_overly_polymorphic(bound_region, Region),
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_sorts(expected_found<t>),
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)
-> t {
pub fn mk_trait(cx: ctxt,
did: ast::def_id,
+substs: substs,
store: TraitStore)
-> t {
// 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 {
@ -1213,8 +1228,8 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
ty_enum(tid, ref substs) => {
ty_enum(tid, fold_substs(substs, fldop))
}
ty_trait(did, ref substs, vst) => {
ty_trait(did, fold_substs(substs, fldop), vst)
ty_trait(did, ref substs, st) => {
ty_trait(did, fold_substs(substs, fldop), st)
}
ty_tup(ts) => {
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::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt))
}
ty_trait(def_id, ref substs, vst) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
ty_trait(def_id, ref substs, st) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st)
}
ty_bare_fn(ref f) => {
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))
}
ty_trait(_, _, vstore_uniq) => {
ty_trait(_, _, UniqTraitStore) => {
TC_OWNED_CLOSURE
}
ty_trait(_, _, vstore_box) => {
ty_trait(_, _, BoxTraitStore) |
ty_trait(_, _, BareTraitStore) => {
TC_MANAGED
}
ty_trait(_, _, vstore_slice(r)) => {
ty_trait(_, _, RegionTraitStore(r)) => {
borrowed_contents(r, m_imm)
}
@ -2013,7 +2029,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
}
ty_type => TC_NONE,
ty_trait(_, _, vstore_fixed(_)) => TC_NONE,
ty_err => {
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 {
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
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).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) => {
fmt!("in field `%s`, %s", *cx.sess.str_of(fname),
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?
*/
pub fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t {
pub fn impl_traits(cx: ctxt, id: ast::def_id, store: TraitStore) -> ~[t] {
fn storeify(cx: ctxt, ty: t, store: TraitStore) -> t {
match ty::get(ty).sty {
ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
ty::ty_trait(did, ref substs, _) => {
mk_trait(cx, did, (/*bad*/copy *substs), vstore)
ty::ty_trait(did, ref substs, trait_store) => {
if store == trait_store ||
(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")
}
@ -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| {
~[vstoreify(cx,
node_id_to_type(cx, trait_ref.ref_id),
vstore)]
~[storeify(cx,
node_id_to_type(cx, trait_ref.ref_id),
store)]
}
}
_ => ~[]
}
} else {
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
},
ty_trait(did, ref substs, BareTraitStore) =>
mk_trait(cx, did, copy *substs, BoxTraitStore),
_ =>
t
};
@ -4318,38 +4359,6 @@ impl cmp::Eq for mt {
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 {
pure fn eq(&self, other: &Region) -> bool {
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);
match ty::get(result.ty).sty {
ty::ty_trait(trait_def_id, ref substs, _) => {
match vst {
ty::vstore_box | ty::vstore_slice(*) |
ty::vstore_uniq => {}
_ => {
let trait_store = match vst {
ty::vstore_box => ty::BoxTraitStore,
ty::vstore_uniq => ty::UniqTraitStore,
ty::vstore_slice(r) => {
ty::RegionTraitStore(r)
}
ty::vstore_fixed(*) => {
tcx.sess.span_err(
path.span,
~"@trait, ~trait or &trait \
are the only supported \
forms of casting-to-\
trait");
ty::BoxTraitStore
}
}
return ty::mk_trait(tcx, trait_def_id,
/*bad*/copy *substs, vst);
};
return ty::mk_trait(tcx,
trait_def_id,
/*bad*/copy *substs,
trait_store);
}
_ => {}

View file

@ -288,9 +288,9 @@ pub impl LookupContext/&self {
ty_param(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_ty, did, substs, vstore);
self_ty, did, substs, store);
self.push_inherent_impl_candidates_for_type(did);
}
ty_self => {
@ -490,7 +490,7 @@ pub impl LookupContext/&self {
self_ty: ty::t,
did: def_id,
substs: &ty::substs,
vstore: ty::vstore) {
store: ty::TraitStore) {
debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)",
self.did_to_str(did),
substs_to_str(self.tcx(), substs));
@ -539,7 +539,7 @@ pub impl LookupContext/&self {
explicit_self: method.self_ty,
num_method_tps: method.tps.len(),
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.
let target_ty = rcx.resolve_node_type(expr.id);
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);
constrain_regions_in_type(rcx, trait_region,
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> {
let tcx = vcx.tcx();
// 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| {
match ty::get(*t_f).sty {
ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f),
@ -167,9 +169,9 @@ pub fn lookup_vtable(vcx: &VtableContext,
let _i = indenter();
let tcx = vcx.tcx();
let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
ty::ty_trait(did, ref substs, vstore) =>
(did, (/*bad*/copy *substs), vstore),
let (trait_id, trait_substs, trait_store) = match ty::get(trait_ty).sty {
ty::ty_trait(did, ref substs, store) =>
(did, (/*bad*/copy *substs), store),
_ => tcx.sess.impossible_case(location_info.span,
"lookup_vtable: \
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
// unify it with trait_ty in order to get all
// the ty vars sorted out.
for vec::each(ty::impl_traits(tcx, im.did,
trait_vstore)) |of_ty| {
for vec::each(ty::impl_traits(tcx,
im.did,
trait_store)) |of_ty| {
match ty::get(*of_ty).sty {
ty::ty_trait(id, _, _) => {
// Not the trait we're looking for
@ -381,7 +384,7 @@ pub fn lookup_vtable(vcx: &VtableContext,
/*bad*/copy substs_f.tps,
trait_tps,
im.did,
trait_vstore);
trait_store);
let subres = lookup_vtables(
vcx, location_info, im_bs, &substs_f,
is_early);
@ -455,11 +458,11 @@ pub fn connect_trait_tps(vcx: &VtableContext,
impl_tys: ~[ty::t],
trait_tys: ~[ty::t],
impl_did: ast::def_id,
vstore: ty::vstore) {
store: ty::TraitStore) {
let tcx = vcx.tcx();
// 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);
debug!("(connect trait tps) trait type is %?, impl did is %?",
ty::get(trait_ty).sty, impl_did);
@ -557,17 +560,19 @@ pub fn early_resolve_expr(ex: @ast::expr,
ast::expr_cast(src, _) => {
let target_ty = fcx.expr_ty(ex);
match ty::get(target_ty).sty {
ty::ty_trait(_, _, vstore) => {
ty::ty_trait(_, _, store) => {
// 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`, `&x as &Trait` or `~x as ~Trait`
let ty = structurally_resolved_type(fcx, ex.span,
fcx.expr_ty(src));
match (&ty::get(ty).sty, vstore) {
(&ty::ty_box(mt), ty::vstore_box) |
(&ty::ty_uniq(mt), ty::vstore_uniq) |
(&ty::ty_rptr(_, mt), ty::vstore_slice(*)) => {
match (&ty::get(ty).sty, store) {
(&ty::ty_box(mt), ty::BoxTraitStore) |
// XXX: Bare trait store is deprecated.
(&ty::ty_box(mt), ty::BareTraitStore) |
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(*)) => {
let location_info =
&location_info_for_expr(ex);
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
// regions.
match (&ty::get(ty).sty, vstore) {
match (&ty::get(ty).sty, store) {
(&ty::ty_rptr(ra, _),
ty::vstore_slice(rb)) => {
ty::RegionTraitStore(rb)) => {
infer::mk_subr(fcx.infcx(),
false,
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(
ex.span,
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::vstore_uniq(*)) => {
(_, ty::UniqTraitStore) => {
fcx.ccx.tcx.sess.span_err(
ex.span,
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::vstore_slice(*)) => {
(_, ty::RegionTraitStore(_)) => {
fcx.ccx.tcx.sess.span_err(
ex.span,
fmt!("can only cast an &-pointer \
to an &-object, not a %s",
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 */ }

View file

@ -81,8 +81,10 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
match intrinsic_item.node {
ast::item_trait(*) => {
let ty = ty::mk_trait(ccx.tcx, def_id, substs,
ty::vstore_box);
let ty = ty::mk_trait(ccx.tcx,
def_id,
substs,
ty::BareTraitStore);
ccx.tcx.intrinsic_defs.insert
(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, _, _) => {
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 {
bounds: bounds,
region_param: rp,

View file

@ -102,10 +102,16 @@ pub trait Combine {
fn purities(&self, a: purity, b: purity) -> cres<purity>;
fn abis(&self, a: ast::Abi, b: ast::Abi) -> cres<ast::Abi>;
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 vstores(&self, vk: ty::terr_vstore_kind,
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 {
@ -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>(
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(b_id, ref b_substs, b_vstore))
(ty::ty_trait(a_id, ref a_substs, a_store),
ty::ty_trait(b_id, ref b_substs, b_store))
if a_id == b_id => {
do self.substs(a_id, a_substs, b_substs).chain |substs| {
do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| {
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, vs))
do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
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)
}
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> {
super_modes(self, a, b)
}

View file

@ -227,6 +227,14 @@ impl Combine for Lub {
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> {
super_modes(self, a, b)
}

View file

@ -239,6 +239,14 @@ impl Combine for Sub {
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> {
super_modes(self, a, b)
}

View file

@ -90,7 +90,7 @@ pub enum method_origin {
method_param(method_param),
// 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_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 {
match vs {
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());
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 base = ast_map::path_to_str(path, cx.sess.intr());
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) => {
vstore_ty_to_str(cx, fmt!("%s", mt_to_str(cx, mt)), vs)