mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 11:44:28 +00:00
auto merge of #5725 : jdm/rust/muttrait, r=nikomatsakis
This commit is contained in:
commit
68dea75296
@ -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);
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
|
@ -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::*;
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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) => {
|
||||
|
@ -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(
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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) => {
|
||||
|
@ -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)) => {
|
||||
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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]),
|
||||
|
||||
@ -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, _) |
|
||||
@ -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 {
|
||||
@ -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); } }
|
||||
@ -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));
|
||||
@ -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),
|
||||
@ -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) => {
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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),
|
||||
@ -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",
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -141,10 +141,11 @@ fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
|
||||
// use a dummy type just to package up the substs that need fixing up
|
||||
let t = ty::mk_trait(tcx,
|
||||
id, substs,
|
||||
ty::RegionTraitStore(ty::re_static));
|
||||
ty::RegionTraitStore(ty::re_static),
|
||||
ast::m_imm);
|
||||
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),
|
||||
ty::ty_trait(_, ref substs_f, _, _) => (/*bad*/copy *substs_f),
|
||||
_ => fail!(~"t_f should be a trait")
|
||||
}
|
||||
}
|
||||
@ -544,7 +545,12 @@ pub fn early_resolve_expr(ex: @ast::expr,
|
||||
debug!("vtable resolution on expr %s", ex.repr(fcx.tcx()));
|
||||
let target_ty = fcx.expr_ty(ex);
|
||||
match ty::get(target_ty).sty {
|
||||
ty::ty_trait(target_def_id, ref target_substs, store) => {
|
||||
ty::ty_trait(target_def_id, ref target_substs, store, target_mutbl) => {
|
||||
fn mutability_allowed(a_mutbl: ast::mutability,
|
||||
b_mutbl: ast::mutability) -> bool {
|
||||
a_mutbl == b_mutbl ||
|
||||
(a_mutbl == ast::m_mutbl && b_mutbl == ast::m_imm)
|
||||
}
|
||||
// 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,
|
||||
@ -552,6 +558,14 @@ pub fn early_resolve_expr(ex: @ast::expr,
|
||||
let ty = structurally_resolved_type(fcx, ex.span,
|
||||
fcx.expr_ty(src));
|
||||
match (&ty::get(ty).sty, store) {
|
||||
(&ty::ty_box(mt), ty::BoxTraitStore) |
|
||||
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
|
||||
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(*))
|
||||
if !mutability_allowed(mt.mutbl, target_mutbl) => {
|
||||
fcx.tcx().sess.span_err(ex.span,
|
||||
fmt!("types differ in mutability"));
|
||||
}
|
||||
|
||||
(&ty::ty_box(mt), ty::BoxTraitStore) |
|
||||
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
|
||||
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(*)) => {
|
||||
|
@ -114,7 +114,7 @@ pub fn type_is_defined_in_local_crate(original_type: t) -> bool {
|
||||
do ty::walk_ty(original_type) |t| {
|
||||
match get(t).sty {
|
||||
ty_enum(def_id, _) |
|
||||
ty_trait(def_id, _, _) |
|
||||
ty_trait(def_id, _, _, _) |
|
||||
ty_struct(def_id, _) => {
|
||||
if def_id.crate == ast::local_crate {
|
||||
found_nominal = true;
|
||||
@ -140,7 +140,7 @@ pub fn get_base_type_def_id(inference_context: @mut InferCtxt,
|
||||
match get(base_type).sty {
|
||||
ty_enum(def_id, _) |
|
||||
ty_struct(def_id, _) |
|
||||
ty_trait(def_id, _, _) => {
|
||||
ty_trait(def_id, _, _, _) => {
|
||||
return Some(def_id);
|
||||
}
|
||||
_ => {
|
||||
|
@ -525,13 +525,13 @@ pub fn super_tys<C:Combine>(
|
||||
}
|
||||
}
|
||||
|
||||
(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 => {
|
||||
(ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl),
|
||||
ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl))
|
||||
if a_id == b_id && a_mutbl == b_mutbl => {
|
||||
let trait_def = ty::lookup_trait_def(tcx, a_id);
|
||||
do self.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
||||
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s))
|
||||
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,10 +737,11 @@ pub impl InferCtxt {
|
||||
let dummy0 = ty::mk_trait(self.tcx,
|
||||
trait_ref.def_id,
|
||||
copy trait_ref.substs,
|
||||
ty::UniqTraitStore);
|
||||
ty::UniqTraitStore,
|
||||
ast::m_imm);
|
||||
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
|
||||
match ty::get(dummy1).sty {
|
||||
ty::ty_trait(ref def_id, ref substs, _) => {
|
||||
ty::ty_trait(ref def_id, ref substs, _, _) => {
|
||||
ty::TraitRef {def_id: *def_id,
|
||||
substs: copy *substs}
|
||||
}
|
||||
|
@ -224,16 +224,20 @@ pub fn region_to_str_space(cx: ctxt, prefix: &str, region: Region) -> ~str {
|
||||
}
|
||||
}
|
||||
|
||||
fn mutability_to_str(m: ast::mutability) -> ~str {
|
||||
match m {
|
||||
ast::m_mutbl => ~"mut ",
|
||||
ast::m_imm => ~"",
|
||||
ast::m_const => ~"const "
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mt_to_str(cx: ctxt, m: &mt) -> ~str {
|
||||
mt_to_str_wrapped(cx, "", m, "")
|
||||
}
|
||||
|
||||
pub fn mt_to_str_wrapped(cx: ctxt, before: &str, m: &mt, after: &str) -> ~str {
|
||||
let mstr = match m.mutbl {
|
||||
ast::m_mutbl => "mut ",
|
||||
ast::m_imm => "",
|
||||
ast::m_const => "const "
|
||||
};
|
||||
let mstr = mutability_to_str(m.mutbl);
|
||||
return fmt!("%s%s%s%s", mstr, before, ty_to_str(cx, m.ty), after);
|
||||
}
|
||||
|
||||
@ -456,11 +460,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, s) => {
|
||||
ty_trait(did, ref substs, s, mutbl) => {
|
||||
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", trait_store_to_str(cx, s), ty)
|
||||
fmt!("%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty)
|
||||
}
|
||||
ty_evec(ref mt, vs) => {
|
||||
vstore_ty_to_str(cx, mt, vs)
|
||||
|
28
src/test/compile-fail/cast-immutable-mutable-trait.rs
Normal file
28
src/test/compile-fail/cast-immutable-mutable-trait.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait T {
|
||||
fn foo(@mut self);
|
||||
}
|
||||
|
||||
struct S {
|
||||
unused: int
|
||||
}
|
||||
|
||||
impl T for S {
|
||||
fn foo(@mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = @S { unused: 0 };
|
||||
let _s2 = s as @mut T; //~ error: types differ in mutability
|
||||
let _s3 = &s as &mut T; //~ error: types differ in mutability
|
||||
}
|
34
src/test/run-pass/cast-mutable-trait.rs
Normal file
34
src/test/run-pass/cast-mutable-trait.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait T {
|
||||
fn foo(@mut self);
|
||||
}
|
||||
|
||||
struct S {
|
||||
unused: int
|
||||
}
|
||||
|
||||
impl T for S {
|
||||
fn foo(@mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(t: @mut T) {
|
||||
t.foo();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = @mut S { unused: 0 };
|
||||
let s2 = s as @mut T;
|
||||
s2.foo();
|
||||
bar(s2);
|
||||
bar(s as @mut T);
|
||||
}
|
Loading…
Reference in New Issue
Block a user