Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow casting to mutable trait objects. #5725

Merged
merged 1 commit into from
Apr 18, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
let def = parse_def(st, NominalType, conv);
let substs = parse_substs(st, conv);
let store = parse_trait_store(st);
let mt = parse_mutability(st);
assert!(next(st) == ']');
return ty::mk_trait(st.tcx, def, substs, store);
return ty::mk_trait(st.tcx, def, substs, store, mt);
}
'p' => {
let did = parse_def(st, TypeParameter, conv);
Expand Down Expand Up @@ -396,13 +397,16 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
}
}

fn parse_mt(st: @mut PState, conv: conv_did) -> ty::mt {
let mut m;
fn parse_mutability(st: @mut PState) -> ast::mutability {
match peek(st) {
'm' => { next(st); m = ast::m_mutbl; }
'?' => { next(st); m = ast::m_const; }
_ => { m = ast::m_imm; }
'm' => { next(st); ast::m_mutbl }
'?' => { next(st); ast::m_const }
_ => { ast::m_imm }
}
}

fn parse_mt(st: @mut PState, conv: conv_did) -> ty::mt {
let m = parse_mutability(st);
ty::mt { ty: parse_ty(st, conv), mutbl: m }
}

Expand Down
13 changes: 10 additions & 3 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use core::io;
use core::uint;
use core::vec;
use syntax::abi::AbiSet;
use syntax::ast;
use syntax::ast::*;
use syntax::diagnostic::span_handler;
use syntax::print::pprust::*;
Expand Down Expand Up @@ -113,12 +114,17 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
}
}
}
fn enc_mt(w: @io::Writer, cx: @ctxt, mt: ty::mt) {
match mt.mutbl {

fn enc_mutability(w: @io::Writer, mt: ast::mutability) {
match mt {
m_imm => (),
m_mutbl => w.write_char('m'),
m_const => w.write_char('?')
}
}

fn enc_mt(w: @io::Writer, cx: @ctxt, mt: ty::mt) {
enc_mutability(w, mt.mutbl);
enc_ty(w, cx, mt.ty);
}

Expand Down Expand Up @@ -269,12 +275,13 @@ 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, store) => {
ty::ty_trait(def, ref substs, store, mt) => {
w.write_str(&"x[");
w.write_str((cx.ds)(def));
w.write_char('|');
enc_substs(w, cx, (*substs));
enc_trait_store(w, cx, store);
enc_mutability(w, mt);
w.write_char(']');
}
ty::ty_tup(ts) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,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::UniqTraitStore) => {
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(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span)
ty::ty_closure(ref _closurety) => {
cx.sess.span_bug(span, ~"debuginfo for closure NYI")
},
ty::ty_trait(_did, ref _substs, ref _vstore) => {
ty::ty_trait(_did, ref _substs, ref _vstore, _) => {
cx.sess.span_bug(span, ~"debuginfo for trait NYI")
},
ty::ty_struct(did, ref substs) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ 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(_, _, store) => {
ty::ty_trait(_, _, store, _) => {
return meth::trans_trait_cast(bcx, val, expr.id, dest,
store);
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,11 @@ 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::BoxTraitStore) => {
ty::ty_trait(_, _, ty::BoxTraitStore, _) => {
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::UniqTraitStore) => {
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,
Expand Down Expand Up @@ -617,12 +617,12 @@ 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::BoxTraitStore) => {
ty::ty_trait(_, _, ty::BoxTraitStore, _) => {
let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u]));
incr_refcnt_of_boxed(bcx, llbox);
bcx
}
ty::ty_trait(_, _, ty::UniqTraitStore) => {
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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
ty::ty_closure(ref fty) => {
Some(normalized_closure_ty(tcx, fty.sigil))
}
ty::ty_trait(_, _, ref store) => {
ty::ty_trait(_, _, ref store, _) => {
let sigil = match *store {
ty::UniqTraitStore => ast::OwnedSigil,
ty::BoxTraitStore => ast::ManagedSigil,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ pub impl Reflector {
}

// Miscallaneous extra types
ty::ty_trait(_, _, _) => self.leaf(~"trait"),
ty::ty_trait(_, _, _, _) => self.leaf(~"trait"),
ty::ty_infer(_) => self.leaf(~"infer"),
ty::ty_err => self.leaf(~"err"),
ty::ty_param(ref p) => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,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())], false),
ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
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)) => {
Expand Down Expand Up @@ -249,7 +249,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(_, _, store) => T_opaque_trait(cx, store),
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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/type_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub fn type_needs_inner(cx: Context,
ty::ty_bare_fn(*) |
ty::ty_ptr(_) |
ty::ty_rptr(_, _) |
ty::ty_trait(_, _, _) => false,
ty::ty_trait(_, _, _, _) => false,

ty::ty_enum(did, ref substs) => {
if list::find(enums_seen, |id| *id == did).is_none() {
Expand Down
46 changes: 25 additions & 21 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ pub enum sty {
ty_rptr(Region, mt),
ty_bare_fn(BareFnTy),
ty_closure(ClosureTy),
ty_trait(def_id, substs, TraitStore),
ty_trait(def_id, substs, TraitStore, ast::mutability),
ty_struct(def_id, substs),
ty_tup(~[t]),

Expand Down Expand Up @@ -946,7 +946,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
&ty_infer(_) => flags |= needs_infer as uint,
&ty_self(_) => flags |= has_self as uint,
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
&ty_trait(_, ref substs, _) => {
&ty_trait(_, ref substs, _, _) => {
flags |= sflags(substs);
}
&ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) |
Expand Down Expand Up @@ -1115,10 +1115,11 @@ 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,
store: TraitStore)
store: TraitStore,
mutability: ast::mutability)
-> t {
// take a copy of substs so that we own the vectors inside
mk_t(cx, ty_trait(did, substs, store))
mk_t(cx, ty_trait(did, substs, store, mutability))
}

pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, +substs: substs) -> t {
Expand Down Expand Up @@ -1214,7 +1215,7 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) {
maybe_walk_ty(tm.ty, f);
}
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
ty_trait(_, ref substs, _) => {
ty_trait(_, ref substs, _, _) => {
for (*substs).tps.each |subty| { maybe_walk_ty(*subty, f); }
}
ty_tup(ref ts) => { for ts.each |tt| { maybe_walk_ty(*tt, f); } }
Expand Down Expand Up @@ -1277,8 +1278,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, st) => {
ty_trait(did, fold_substs(substs, fldop), st)
ty_trait(did, ref substs, st, mutbl) => {
ty_trait(did, fold_substs(substs, fldop), st, mutbl)
}
ty_tup(ref ts) => {
let new_ts = ts.map(|tt| fldop(*tt));
Expand Down Expand Up @@ -1367,8 +1368,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, st) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st)
ty_trait(def_id, ref substs, st, mutbl) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl)
}
ty_bare_fn(ref f) => {
ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
Expand Down Expand Up @@ -1911,16 +1912,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
}

ty_trait(_, _, UniqTraitStore) => {
ty_trait(_, _, UniqTraitStore, _) => {
TC_OWNED_CLOSURE
}

ty_trait(_, _, BoxTraitStore) => {
TC_MANAGED
ty_trait(_, _, BoxTraitStore, mutbl) => {
match mutbl {
ast::m_mutbl => TC_MANAGED + TC_MUTABLE,
_ => TC_MANAGED
}
}

ty_trait(_, _, RegionTraitStore(r)) => {
borrowed_contents(r, m_imm)
ty_trait(_, _, RegionTraitStore(r), mutbl) => {
borrowed_contents(r, mutbl)
}

ty_rptr(r, mt) => {
Expand Down Expand Up @@ -2241,7 +2245,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
false // unsafe ptrs can always be NULL
}

ty_trait(_, _, _) => {
ty_trait(_, _, _, _) => {
false
}

Expand Down Expand Up @@ -2385,7 +2389,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
ty_box(_) | ty_uniq(_) | ty_closure(_) |
ty_estr(vstore_uniq) | ty_estr(vstore_box) |
ty_evec(_, vstore_uniq) | ty_evec(_, vstore_box) |
ty_trait(_, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
ty_trait(_, _, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
// Structural types
ty_enum(did, ref substs) => {
let variants = enum_variants(cx, did);
Expand Down Expand Up @@ -2673,8 +2677,8 @@ impl to_bytes::IterBytes for sty {
ty_uniq(ref mt) =>
to_bytes::iter_bytes_2(&19u8, mt, lsb0, f),

ty_trait(ref did, ref substs, ref v) =>
to_bytes::iter_bytes_4(&20u8, did, substs, v, lsb0, f),
ty_trait(ref did, ref substs, ref v, ref mutbl) =>
to_bytes::iter_bytes_5(&20u8, did, substs, v, mutbl, lsb0, f),

ty_opaque_closure_ptr(ref ck) =>
to_bytes::iter_bytes_2(&21u8, ck, lsb0, f),
Expand Down Expand Up @@ -3366,7 +3370,7 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
ty_rptr(_, _) => ~"&-ptr",
ty_bare_fn(_) => ~"extern fn",
ty_closure(_) => ~"fn",
ty_trait(id, _, _) => fmt!("trait %s", item_path_str(cx, id)),
ty_trait(id, _, _, _) => fmt!("trait %s", item_path_str(cx, id)),
ty_struct(id, _) => fmt!("struct %s", item_path_str(cx, id)),
ty_tup(_) => ~"tuple",
ty_infer(TyVar(_)) => ~"inferred type",
Expand Down Expand Up @@ -3679,7 +3683,7 @@ pub fn impl_trait_refs(cx: ctxt, id: ast::def_id) -> ~[@TraitRef] {

pub fn ty_to_def_id(ty: t) -> Option<ast::def_id> {
match get(ty).sty {
ty_trait(id, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
ty_trait(id, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
_ => None
}
}
Expand Down Expand Up @@ -4413,7 +4417,7 @@ pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name));
let trait_ref = *tcx.intrinsic_traits.get(&ty_visitor_name);
(trait_ref,
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore))
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm))
}

// Local Variables:
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
}
return ty::mk_evec(tcx, mt, vst);
}
ast::ty_path(path, id) if a_seq_ty.mutbl == ast::m_imm => {
ast::ty_path(path, id) => {
match tcx.def_map.find(&id) {
Some(&ast::def_prim_ty(ast::ty_str)) => {
Some(&ast::def_prim_ty(ast::ty_str)) if a_seq_ty.mutbl == ast::m_imm => {
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
return ty::mk_estr(tcx, vst);
}
Expand All @@ -305,7 +305,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
return ty::mk_trait(tcx,
result.def_id,
copy result.substs,
trait_store);
trait_store,
a_seq_ty.mutbl);
}
_ => {}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ pub impl<'self> LookupContext<'self> {
ty_param(p) => {
self.push_inherent_candidates_from_param(self_ty, p);
}
ty_trait(did, ref substs, store) => {
ty_trait(did, ref substs, store, _) => {
self.push_inherent_candidates_from_trait(
self_ty, did, substs, store);
self.push_inherent_impl_candidates_for_type(did);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ 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(_, _, ty::RegionTraitStore(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);
Expand Down
Loading