Skip to content

Commit

Permalink
Allow casting to mutable trait objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdm committed Apr 16, 2013
1 parent 07e087b commit 9730370
Show file tree
Hide file tree
Showing 21 changed files with 162 additions and 65 deletions.
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

5 comments on commit 9730370

@bors
Copy link
Contributor

@bors bors commented on 9730370 Apr 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at jdm@9730370

@bors
Copy link
Contributor

@bors bors commented on 9730370 Apr 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jdm/rust/muttrait = 9730370 into auto

@bors
Copy link
Contributor

@bors bors commented on 9730370 Apr 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jdm/rust/muttrait = 9730370 merged ok, testing candidate = 68dea75

@bors
Copy link
Contributor

@bors bors commented on 9730370 Apr 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 9730370 Apr 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 68dea75

Please sign in to comment.