Skip to content

Commit 9730370

Browse files
committed
Allow casting to mutable trait objects.
1 parent 07e087b commit 9730370

21 files changed

+162
-65
lines changed

src/librustc/metadata/tydecode.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
313313
let def = parse_def(st, NominalType, conv);
314314
let substs = parse_substs(st, conv);
315315
let store = parse_trait_store(st);
316+
let mt = parse_mutability(st);
316317
assert!(next(st) == ']');
317-
return ty::mk_trait(st.tcx, def, substs, store);
318+
return ty::mk_trait(st.tcx, def, substs, store, mt);
318319
}
319320
'p' => {
320321
let did = parse_def(st, TypeParameter, conv);
@@ -396,13 +397,16 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
396397
}
397398
}
398399

399-
fn parse_mt(st: @mut PState, conv: conv_did) -> ty::mt {
400-
let mut m;
400+
fn parse_mutability(st: @mut PState) -> ast::mutability {
401401
match peek(st) {
402-
'm' => { next(st); m = ast::m_mutbl; }
403-
'?' => { next(st); m = ast::m_const; }
404-
_ => { m = ast::m_imm; }
402+
'm' => { next(st); ast::m_mutbl }
403+
'?' => { next(st); ast::m_const }
404+
_ => { ast::m_imm }
405405
}
406+
}
407+
408+
fn parse_mt(st: @mut PState, conv: conv_did) -> ty::mt {
409+
let m = parse_mutability(st);
406410
ty::mt { ty: parse_ty(st, conv), mutbl: m }
407411
}
408412

src/librustc/metadata/tyencode.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use core::io;
2222
use core::uint;
2323
use core::vec;
2424
use syntax::abi::AbiSet;
25+
use syntax::ast;
2526
use syntax::ast::*;
2627
use syntax::diagnostic::span_handler;
2728
use syntax::print::pprust::*;
@@ -113,12 +114,17 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
113114
}
114115
}
115116
}
116-
fn enc_mt(w: @io::Writer, cx: @ctxt, mt: ty::mt) {
117-
match mt.mutbl {
117+
118+
fn enc_mutability(w: @io::Writer, mt: ast::mutability) {
119+
match mt {
118120
m_imm => (),
119121
m_mutbl => w.write_char('m'),
120122
m_const => w.write_char('?')
121123
}
124+
}
125+
126+
fn enc_mt(w: @io::Writer, cx: @ctxt, mt: ty::mt) {
127+
enc_mutability(w, mt.mutbl);
122128
enc_ty(w, cx, mt.ty);
123129
}
124130

@@ -269,12 +275,13 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, +st: ty::sty) {
269275
enc_substs(w, cx, (*substs));
270276
w.write_char(']');
271277
}
272-
ty::ty_trait(def, ref substs, store) => {
278+
ty::ty_trait(def, ref substs, store, mt) => {
273279
w.write_str(&"x[");
274280
w.write_str((cx.ds)(def));
275281
w.write_char('|');
276282
enc_substs(w, cx, (*substs));
277283
enc_trait_store(w, cx, store);
284+
enc_mutability(w, mt);
278285
w.write_char(']');
279286
}
280287
ty::ty_tup(ts) => {

src/librustc/middle/kind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ pub fn check_cast_for_escaping_regions(
589589
pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) {
590590
let target_ty = ty::expr_ty(cx.tcx, target);
591591
match ty::get(target_ty).sty {
592-
ty::ty_trait(_, _, ty::UniqTraitStore) => {
592+
ty::ty_trait(_, _, ty::UniqTraitStore, _) => {
593593
let source_ty = ty::expr_ty(cx.tcx, source);
594594
if !ty::type_is_owned(cx.tcx, source_ty) {
595595
cx.tcx.sess.span_err(

src/librustc/middle/trans/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span)
671671
ty::ty_closure(ref _closurety) => {
672672
cx.sess.span_bug(span, ~"debuginfo for closure NYI")
673673
},
674-
ty::ty_trait(_did, ref _substs, ref _vstore) => {
674+
ty::ty_trait(_did, ref _substs, ref _vstore, _) => {
675675
cx.sess.span_bug(span, ~"debuginfo for trait NYI")
676676
},
677677
ty::ty_struct(did, ref substs) => {

src/librustc/middle/trans/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
667667
}
668668
ast::expr_cast(val, _) => {
669669
match ty::get(node_id_type(bcx, expr.id)).sty {
670-
ty::ty_trait(_, _, store) => {
670+
ty::ty_trait(_, _, store, _) => {
671671
return meth::trans_trait_cast(bcx, val, expr.id, dest,
672672
store);
673673
}

src/librustc/middle/trans/glue.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,11 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
551551
ty::ty_closure(_) => {
552552
closure::make_closure_glue(bcx, v0, t, drop_ty)
553553
}
554-
ty::ty_trait(_, _, ty::BoxTraitStore) => {
554+
ty::ty_trait(_, _, ty::BoxTraitStore, _) => {
555555
let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u]));
556556
decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
557557
}
558-
ty::ty_trait(_, _, ty::UniqTraitStore) => {
558+
ty::ty_trait(_, _, ty::UniqTraitStore, _) => {
559559
let lluniquevalue = GEPi(bcx, v0, [0, 1]);
560560
let lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2]));
561561
call_tydesc_glue_full(bcx, lluniquevalue, lltydesc,
@@ -617,12 +617,12 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
617617
ty::ty_closure(_) => {
618618
closure::make_closure_glue(bcx, v, t, take_ty)
619619
}
620-
ty::ty_trait(_, _, ty::BoxTraitStore) => {
620+
ty::ty_trait(_, _, ty::BoxTraitStore, _) => {
621621
let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u]));
622622
incr_refcnt_of_boxed(bcx, llbox);
623623
bcx
624624
}
625-
ty::ty_trait(_, _, ty::UniqTraitStore) => {
625+
ty::ty_trait(_, _, ty::UniqTraitStore, _) => {
626626
let llval = GEPi(bcx, v, [0, 1]);
627627
let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2]));
628628
call_tydesc_glue_full(bcx, llval, lltydesc,

src/librustc/middle/trans/monomorphize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
303303
ty::ty_closure(ref fty) => {
304304
Some(normalized_closure_ty(tcx, fty.sigil))
305305
}
306-
ty::ty_trait(_, _, ref store) => {
306+
ty::ty_trait(_, _, ref store, _) => {
307307
let sigil = match *store {
308308
ty::UniqTraitStore => ast::OwnedSigil,
309309
ty::BoxTraitStore => ast::ManagedSigil,

src/librustc/middle/trans/reflect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ pub impl Reflector {
323323
}
324324

325325
// Miscallaneous extra types
326-
ty::ty_trait(_, _, _) => self.leaf(~"trait"),
326+
ty::ty_trait(_, _, _, _) => self.leaf(~"trait"),
327327
ty::ty_infer(_) => self.leaf(~"infer"),
328328
ty::ty_err => self.leaf(~"err"),
329329
ty::ty_param(ref p) => {

src/librustc/middle/trans/type_of.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
133133

134134
ty::ty_bare_fn(*) => T_ptr(T_i8()),
135135
ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())], false),
136-
ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
136+
ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store),
137137

138138
ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size),
139139
ty::ty_evec(mt, ty::vstore_fixed(size)) => {
@@ -249,7 +249,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
249249

250250
ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
251251
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
252-
ty::ty_trait(_, _, store) => T_opaque_trait(cx, store),
252+
ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store),
253253
ty::ty_type => T_ptr(cx.tydesc_type),
254254
ty::ty_tup(*) => {
255255
let repr = adt::represent_type(cx, t);

src/librustc/middle/trans/type_use.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ pub fn type_needs_inner(cx: Context,
216216
ty::ty_bare_fn(*) |
217217
ty::ty_ptr(_) |
218218
ty::ty_rptr(_, _) |
219-
ty::ty_trait(_, _, _) => false,
219+
ty::ty_trait(_, _, _, _) => false,
220220

221221
ty::ty_enum(did, ref substs) => {
222222
if list::find(enums_seen, |id| *id == did).is_none() {

src/librustc/middle/ty.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ pub enum sty {
532532
ty_rptr(Region, mt),
533533
ty_bare_fn(BareFnTy),
534534
ty_closure(ClosureTy),
535-
ty_trait(def_id, substs, TraitStore),
535+
ty_trait(def_id, substs, TraitStore, ast::mutability),
536536
ty_struct(def_id, substs),
537537
ty_tup(~[t]),
538538

@@ -946,7 +946,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
946946
&ty_infer(_) => flags |= needs_infer as uint,
947947
&ty_self(_) => flags |= has_self as uint,
948948
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
949-
&ty_trait(_, ref substs, _) => {
949+
&ty_trait(_, ref substs, _, _) => {
950950
flags |= sflags(substs);
951951
}
952952
&ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) |
@@ -1115,10 +1115,11 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
11151115
pub fn mk_trait(cx: ctxt,
11161116
did: ast::def_id,
11171117
+substs: substs,
1118-
store: TraitStore)
1118+
store: TraitStore,
1119+
mutability: ast::mutability)
11191120
-> t {
11201121
// take a copy of substs so that we own the vectors inside
1121-
mk_t(cx, ty_trait(did, substs, store))
1122+
mk_t(cx, ty_trait(did, substs, store, mutability))
11221123
}
11231124

11241125
pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, +substs: substs) -> t {
@@ -1214,7 +1215,7 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) {
12141215
maybe_walk_ty(tm.ty, f);
12151216
}
12161217
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
1217-
ty_trait(_, ref substs, _) => {
1218+
ty_trait(_, ref substs, _, _) => {
12181219
for (*substs).tps.each |subty| { maybe_walk_ty(*subty, f); }
12191220
}
12201221
ty_tup(ref ts) => { for ts.each |tt| { maybe_walk_ty(*tt, f); } }
@@ -1277,8 +1278,8 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
12771278
ty_enum(tid, ref substs) => {
12781279
ty_enum(tid, fold_substs(substs, fldop))
12791280
}
1280-
ty_trait(did, ref substs, st) => {
1281-
ty_trait(did, fold_substs(substs, fldop), st)
1281+
ty_trait(did, ref substs, st, mutbl) => {
1282+
ty_trait(did, fold_substs(substs, fldop), st, mutbl)
12821283
}
12831284
ty_tup(ref ts) => {
12841285
let new_ts = ts.map(|tt| fldop(*tt));
@@ -1367,8 +1368,8 @@ pub fn fold_regions_and_ty(
13671368
ty_struct(def_id, ref substs) => {
13681369
ty::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt))
13691370
}
1370-
ty_trait(def_id, ref substs, st) => {
1371-
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st)
1371+
ty_trait(def_id, ref substs, st, mutbl) => {
1372+
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl)
13721373
}
13731374
ty_bare_fn(ref f) => {
13741375
ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
@@ -1911,16 +1912,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
19111912
TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
19121913
}
19131914
1914-
ty_trait(_, _, UniqTraitStore) => {
1915+
ty_trait(_, _, UniqTraitStore, _) => {
19151916
TC_OWNED_CLOSURE
19161917
}
19171918
1918-
ty_trait(_, _, BoxTraitStore) => {
1919-
TC_MANAGED
1919+
ty_trait(_, _, BoxTraitStore, mutbl) => {
1920+
match mutbl {
1921+
ast::m_mutbl => TC_MANAGED + TC_MUTABLE,
1922+
_ => TC_MANAGED
1923+
}
19201924
}
19211925
1922-
ty_trait(_, _, RegionTraitStore(r)) => {
1923-
borrowed_contents(r, m_imm)
1926+
ty_trait(_, _, RegionTraitStore(r), mutbl) => {
1927+
borrowed_contents(r, mutbl)
19241928
}
19251929
19261930
ty_rptr(r, mt) => {
@@ -2241,7 +2245,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
22412245
false // unsafe ptrs can always be NULL
22422246
}
22432247
2244-
ty_trait(_, _, _) => {
2248+
ty_trait(_, _, _, _) => {
22452249
false
22462250
}
22472251
@@ -2385,7 +2389,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
23852389
ty_box(_) | ty_uniq(_) | ty_closure(_) |
23862390
ty_estr(vstore_uniq) | ty_estr(vstore_box) |
23872391
ty_evec(_, vstore_uniq) | ty_evec(_, vstore_box) |
2388-
ty_trait(_, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
2392+
ty_trait(_, _, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
23892393
// Structural types
23902394
ty_enum(did, ref substs) => {
23912395
let variants = enum_variants(cx, did);
@@ -2673,8 +2677,8 @@ impl to_bytes::IterBytes for sty {
26732677
ty_uniq(ref mt) =>
26742678
to_bytes::iter_bytes_2(&19u8, mt, lsb0, f),
26752679
2676-
ty_trait(ref did, ref substs, ref v) =>
2677-
to_bytes::iter_bytes_4(&20u8, did, substs, v, lsb0, f),
2680+
ty_trait(ref did, ref substs, ref v, ref mutbl) =>
2681+
to_bytes::iter_bytes_5(&20u8, did, substs, v, mutbl, lsb0, f),
26782682
26792683
ty_opaque_closure_ptr(ref ck) =>
26802684
to_bytes::iter_bytes_2(&21u8, ck, lsb0, f),
@@ -3366,7 +3370,7 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
33663370
ty_rptr(_, _) => ~"&-ptr",
33673371
ty_bare_fn(_) => ~"extern fn",
33683372
ty_closure(_) => ~"fn",
3369-
ty_trait(id, _, _) => fmt!("trait %s", item_path_str(cx, id)),
3373+
ty_trait(id, _, _, _) => fmt!("trait %s", item_path_str(cx, id)),
33703374
ty_struct(id, _) => fmt!("struct %s", item_path_str(cx, id)),
33713375
ty_tup(_) => ~"tuple",
33723376
ty_infer(TyVar(_)) => ~"inferred type",
@@ -3679,7 +3683,7 @@ pub fn impl_trait_refs(cx: ctxt, id: ast::def_id) -> ~[@TraitRef] {
36793683

36803684
pub fn ty_to_def_id(ty: t) -> Option<ast::def_id> {
36813685
match get(ty).sty {
3682-
ty_trait(id, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
3686+
ty_trait(id, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
36833687
_ => None
36843688
}
36853689
}
@@ -4413,7 +4417,7 @@ pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
44134417
assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name));
44144418
let trait_ref = *tcx.intrinsic_traits.get(&ty_visitor_name);
44154419
(trait_ref,
4416-
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore))
4420+
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm))
44174421
}
44184422

44194423
// Local Variables:

src/librustc/middle/typeck/astconv.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,9 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
277277
}
278278
return ty::mk_evec(tcx, mt, vst);
279279
}
280-
ast::ty_path(path, id) if a_seq_ty.mutbl == ast::m_imm => {
280+
ast::ty_path(path, id) => {
281281
match tcx.def_map.find(&id) {
282-
Some(&ast::def_prim_ty(ast::ty_str)) => {
282+
Some(&ast::def_prim_ty(ast::ty_str)) if a_seq_ty.mutbl == ast::m_imm => {
283283
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
284284
return ty::mk_estr(tcx, vst);
285285
}
@@ -305,7 +305,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
305305
return ty::mk_trait(tcx,
306306
result.def_id,
307307
copy result.substs,
308-
trait_store);
308+
trait_store,
309+
a_seq_ty.mutbl);
309310
}
310311
_ => {}
311312
}

src/librustc/middle/typeck/check/method.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pub impl<'self> LookupContext<'self> {
291291
ty_param(p) => {
292292
self.push_inherent_candidates_from_param(self_ty, p);
293293
}
294-
ty_trait(did, ref substs, store) => {
294+
ty_trait(did, ref substs, store, _) => {
295295
self.push_inherent_candidates_from_trait(
296296
self_ty, did, substs, store);
297297
self.push_inherent_impl_candidates_for_type(did);

src/librustc/middle/typeck/check/regionck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
288288
// explaining how it goes about doing that.
289289
let target_ty = rcx.resolve_node_type(expr.id);
290290
match ty::get(target_ty).sty {
291-
ty::ty_trait(_, _, ty::RegionTraitStore(trait_region)) => {
291+
ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _) => {
292292
let source_ty = rcx.fcx.expr_ty(source);
293293
constrain_regions_in_type(rcx, trait_region,
294294
expr.span, source_ty);

0 commit comments

Comments
 (0)