diff options
Diffstat (limited to 'src')
23 files changed, 293 insertions, 162 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 04dd9156660..e9cbd2685df 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -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); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index d07d8917c65..ff24a889163 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -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) => { diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 48d136ce65f..99781a80c62 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -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( diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 2ab4454a89a..a340e6472b8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -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; } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 2e5dee49c34..70fc29fd25b 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -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())]) + } } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index c163183bfc8..e986d0bdae3 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index b3905680f72..8302f46120e 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -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, diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index b8c5ff4258c..5a46c24b939 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -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. diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index f970d8f26b3..320fc3ed77a 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -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. diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 60af486b3cf..a4a7d958e69 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -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); diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 6855ec5d572..0c3e93885f9 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -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); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 108d4e94017..8d6c6291fdd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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) { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 6c27decc283..9dda55b3a38 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -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); } _ => {} diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index d6060c1ae31..5d2469db285 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -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) }); } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 1dd88e6408b..4ff8431d88a 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -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); diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 7c9ca4ba85a..de301ead1f8 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -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 */ } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 6c8bfdb041d..29d1f81cdd6 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -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, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 1f5e9707e2d..cfe45aaf3a8 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -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)) } } } diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index bba35f02b0c..ff13f7ee576 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -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) } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 3a12fb31a1a..933ad44a79e 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -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) } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index b4d8905a936..580aefe5b1a 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -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) } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 297e33aa8e3..ed1a3d33f4c 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -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) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7add8dd2dbe..05dc967e379 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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) |
