diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 2d5a4b4edb78c..945ee645414b7 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -44,11 +44,10 @@ pub static tydesc_field_size: uint = 0u; pub static tydesc_field_align: uint = 1u; pub static tydesc_field_take_glue: uint = 2u; pub static tydesc_field_drop_glue: uint = 3u; -pub static tydesc_field_free_glue: uint = 4u; -pub static tydesc_field_visit_glue: uint = 5u; -pub static tydesc_field_borrow_offset: uint = 6u; -pub static tydesc_field_name_offset: uint = 7u; -pub static n_tydesc_fields: uint = 8u; +pub static tydesc_field_visit_glue: uint = 4u; +pub static tydesc_field_borrow_offset: uint = 5u; +pub static tydesc_field_name_offset: uint = 6u; +pub static n_tydesc_fields: uint = 7u; // The two halves of a closure: code and environment. pub static fn_field_code: uint = 0u; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 5f57aef2b16e4..261cb15a7aac5 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -354,11 +354,11 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'V' => { let mt = parse_mt(st, |x,y| conv(x,y)); let v = parse_vstore(st, |x,y| conv(x,y)); - return ty::mk_evec(st.tcx, mt, v); + return ty::mk_vec(st.tcx, mt, v); } 'v' => { let v = parse_vstore(st, |x,y| conv(x,y)); - return ty::mk_estr(st.tcx, v); + return ty::mk_str(st.tcx, v); } 'T' => { assert_eq!(next(st), '['); @@ -410,7 +410,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { let inner = parse_ty(st, |x,y| conv(x,y)); inner } - 'B' => ty::mk_opaque_box(st.tcx), 'a' => { assert_eq!(next(st), '['); let did = parse_def(st, NominalType, |x,y| conv(x,y)); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 8929859b2d605..8a8fdd7265216 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -299,12 +299,12 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) { enc_region(w, cx, r); enc_mt(w, cx, mt); } - ty::ty_evec(mt, v) => { + ty::ty_vec(mt, v) => { mywrite!(w, "V"); enc_mt(w, cx, mt); enc_vstore(w, cx, v); } - ty::ty_estr(v) => { + ty::ty_str(v) => { mywrite!(w, "v"); enc_vstore(w, cx, v); } @@ -331,7 +331,6 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) { mywrite!(w, "C&"); enc_sigil(w, p); } - ty::ty_opaque_box => mywrite!(w, "B"), ty::ty_struct(def, ref substs) => { mywrite!(w, "a[{}|", (cx.ds)(def)); enc_substs(w, cx, substs); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 9541afe719b06..675d31ebea8d5 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -578,9 +578,6 @@ fn encode_method_map_entry(ecx: &e::EncodeContext, ebml_w.emit_struct_field("origin", 1u, |ebml_w| { mme.origin.encode(ebml_w); }); - ebml_w.emit_struct_field("self_mode", 3, |ebml_w| { - mme.self_mode.encode(ebml_w); - }); }) } @@ -602,11 +599,7 @@ impl<'a> read_method_map_entry_helper for reader::Decoder<'a> { let method_origin: method_origin = Decodable::decode(this); method_origin.tr(xcx) - }), - self_mode: this.read_struct_field("self_mode", 3, |this| { - let self_mode: ty::SelfMode = Decodable::decode(this); - self_mode - }), + }) } }) } diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index e35bafd6ebfa4..b1337fca0c85d 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -808,7 +808,7 @@ impl<'a> GatherLoanCtxt<'a> { */ match ty::get(slice_ty).sty { - ty::ty_evec(slice_mt, ty::vstore_slice(slice_r)) => { + ty::ty_vec(slice_mt, ty::vstore_slice(slice_r)) => { (slice_mt.mutbl, slice_r) } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 47a90311c3166..79cb1c779a02e 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -195,7 +195,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, pats: ~[@Pat]) { } } } - ty::ty_unboxed_vec(..) | ty::ty_evec(..) => { + ty::ty_unboxed_vec(..) | ty::ty_vec(..) => { match *ctor { vec(n) => Some(format!("vectors of length {}", n).to_managed()), _ => None @@ -274,10 +274,10 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful { } not_useful } - ty::ty_evec(_, ty::vstore_fixed(n)) => { + ty::ty_vec(_, ty::vstore_fixed(n)) => { is_useful_specialized(cx, m, v, vec(n), n, left_ty) } - ty::ty_unboxed_vec(..) | ty::ty_evec(..) => { + ty::ty_unboxed_vec(..) | ty::ty_vec(..) => { let max_len = m.rev_iter().fold(0, |max_len, r| { match r[0].node { PatVec(ref before, _, ref after) => { @@ -437,7 +437,7 @@ fn missing_ctor(cx: &MatchCheckCtxt, else if true_found { Some(val(const_bool(false))) } else { Some(val(const_bool(true))) } } - ty::ty_evec(_, ty::vstore_fixed(n)) => { + ty::ty_vec(_, ty::vstore_fixed(n)) => { let mut missing = true; let mut wrong = false; for r in m.iter() { @@ -460,7 +460,7 @@ fn missing_ctor(cx: &MatchCheckCtxt, _ => None } } - ty::ty_unboxed_vec(..) | ty::ty_evec(..) => { + ty::ty_unboxed_vec(..) | ty::ty_vec(..) => { // Find the lengths and slices of all vector patterns. let mut vec_pat_lens = m.iter().filter_map(|r| { @@ -525,7 +525,7 @@ fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint { } } ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(), - ty::ty_unboxed_vec(..) | ty::ty_evec(..) => { + ty::ty_unboxed_vec(..) | ty::ty_vec(..) => { match *ctor { vec(n) => n, _ => 0u diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index f46e570bb9d02..e291d2595a0b2 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -71,7 +71,7 @@ impl EffectCheckVisitor { debug!("effect: checking index with base type {}", ppaux::ty_to_str(self.tcx, base_type)); match ty::get(base_type).sty { - ty::ty_estr(..) => { + ty::ty_str(..) => { self.tcx.sess.span_err(e.span, "modification of string types is not allowed"); } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 91eeb7f2aaf6f..55cb9f87bcd0d 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -819,13 +819,13 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) { let mut n_uniq = 0; ty::fold_ty(cx.tcx, ty, |t| { match ty::get(t).sty { - ty::ty_box(_) | ty::ty_estr(ty::vstore_box) | - ty::ty_evec(_, ty::vstore_box) | + ty::ty_box(_) | ty::ty_str(ty::vstore_box) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { n_box += 1; } - ty::ty_uniq(_) | ty::ty_estr(ty::vstore_uniq) | - ty::ty_evec(_, ty::vstore_uniq) | + ty::ty_uniq(_) | ty::ty_str(ty::vstore_uniq) | + ty::ty_vec(_, ty::vstore_uniq) | ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => { n_uniq += 1; } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 14eb564314718..a00b01d54ce79 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -157,14 +157,14 @@ pub fn opt_deref_kind(t: ty::t) -> Option { match ty::get(t).sty { ty::ty_uniq(_) | ty::ty_trait(_, _, ty::UniqTraitStore, _, _) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) | + ty::ty_vec(_, ty::vstore_uniq) | + ty::ty_str(ty::vstore_uniq) | ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => { Some(deref_ptr(uniq_ptr)) } ty::ty_rptr(r, mt) | - ty::ty_evec(mt, ty::vstore_slice(r)) => { + ty::ty_vec(mt, ty::vstore_slice(r)) => { Some(deref_ptr(region_ptr(mt.mutbl, r))) } @@ -172,16 +172,16 @@ pub fn opt_deref_kind(t: ty::t) -> Option { Some(deref_ptr(region_ptr(m, r))) } - ty::ty_estr(ty::vstore_slice(r)) | + ty::ty_str(ty::vstore_slice(r)) | ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, region: r, ..}) => { Some(deref_ptr(region_ptr(ast::MutImmutable, r))) } ty::ty_box(_) | - ty::ty_evec(_, ty::vstore_box) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_trait(_, _, ty::BoxTraitStore, _, _) | - ty::ty_estr(ty::vstore_box) => { + ty::ty_str(ty::vstore_box) => { Some(deref_ptr(gc_ptr)) } @@ -194,8 +194,8 @@ pub fn opt_deref_kind(t: ty::t) -> Option { Some(deref_interior(InteriorField(PositionalField(0)))) } - ty::ty_evec(_, ty::vstore_fixed(_)) | - ty::ty_estr(ty::vstore_fixed(_)) => { + ty::ty_vec(_, ty::vstore_fixed(_)) | + ty::ty_str(ty::vstore_fixed(_)) => { Some(deref_interior(InteriorElement(element_kind(t)))) } @@ -1247,8 +1247,8 @@ impl Repr for InteriorKind { fn element_kind(t: ty::t) -> ElementKind { match ty::get(t).sty { - ty::ty_evec(..) => VecElement, - ty::ty_estr(..) => StrElement, + ty::ty_vec(..) => VecElement, + ty::ty_str(..) => StrElement, _ => OtherElement } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index c6f375bbc1b7e..29c82ef83f8de 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1078,7 +1078,7 @@ fn extract_vec_elems<'a>( let slice_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset); let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u); let slice_len = Sub(bcx, len, slice_len_offset); - let slice_ty = ty::mk_evec(bcx.tcx(), + let slice_ty = ty::mk_vec(bcx.tcx(), ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable}, ty::vstore_slice(ty::ReStatic) ); @@ -1312,7 +1312,7 @@ fn compare_values<'a>( } match ty::get(rhs_t).sty { - ty::ty_estr(ty::vstore_uniq) => { + ty::ty_str(ty::vstore_uniq) => { let scratch_lhs = alloca(cx, val_ty(lhs), "__lhs"); Store(cx, lhs, scratch_lhs); let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs"); @@ -1326,7 +1326,7 @@ fn compare_values<'a>( val: bool_to_i1(result.bcx, result.val) } } - ty::ty_estr(_) => { + ty::ty_str(_) => { let did = langcall(cx, None, format!("comparison of `{}`", cx.ty_to_str(rhs_t)), StrEqFnLangItem); @@ -1392,37 +1392,41 @@ fn insert_lllocals<'a>( let llval = match binding_info.trmode { // By value bindings: use the stack slot that we // copied/moved the value into - TrByValue(lldest) => { - if add_cleans { - add_clean(bcx, lldest, binding_info.ty); - } + TrByValue(lldest) => lldest, + // By ref binding: use the ptr into the matched value + TrByRef => binding_info.llmatch + }; - lldest - } + let datum = Datum { + val: llval, + ty: binding_info.ty, + mode: ByRef(ZeroMem) + }; - // By ref binding: use the ptr into the matched value - TrByRef => { - binding_info.llmatch + if add_cleans { + match binding_info.trmode { + TrByValue(_) => datum.add_clean(bcx), + _ => {} } - }; + } { debug!("binding {:?} to {}", binding_info.id, bcx.val_to_str(llval)); let mut llmap = bcx.fcx.lllocals.borrow_mut(); - llmap.get().insert(binding_info.id, llval); + llmap.get().insert(binding_info.id, datum); } if bcx.sess().opts.extra_debuginfo { debuginfo::create_match_binding_metadata(bcx, ident, binding_info.id, - binding_info.ty, - binding_info.span); + binding_info.span, + datum); } } - return bcx; + bcx } fn compile_guard<'r, @@ -2032,8 +2036,7 @@ pub fn store_local<'a>( Some(path) => { return mk_binding_alloca( bcx, pat.id, path, BindLocal, - |bcx, _, llval| expr::trans_into(bcx, init_expr, - expr::SaveIn(llval))); + |bcx, datum| expr::trans_into(bcx, init_expr, expr::SaveIn(datum.val))); } None => {} @@ -2067,13 +2070,13 @@ pub fn store_local<'a>( pat_bindings(tcx.def_map, pat, |_, p_id, _, path| { bcx = mk_binding_alloca( bcx, p_id, path, BindLocal, - |bcx, var_ty, llval| { zero_mem(bcx, llval, var_ty); bcx }); + |bcx, datum| { datum.cancel_clean(bcx); bcx }); }); bcx } } -pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, llval: ValueRef) +pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, arg: Datum) -> &'a Block<'a> { /*! * Generates code for argument patterns like `fn foo(: T)`. @@ -2093,13 +2096,12 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, llval: ValueRef) // Note that we cannot do it before for fear of a fn like // fn getaddr(~ref x: ~uint) -> *uint {....} // (From test `run-pass/func-arg-ref-pattern.rs`) - let arg_ty = node_id_type(bcx, pat.id); - add_clean(bcx, llval, arg_ty); + arg.add_clean(bcx); // Debug information (the llvm.dbg.declare intrinsic to be precise) always expects to get an // alloca, which only is the case on the general path, so lets disable the optimized path when // debug info is enabled. - let arg_is_alloca = unsafe { llvm::LLVMIsAAllocaInst(llval) != ptr::null() }; + let arg_is_alloca = unsafe { llvm::LLVMIsAAllocaInst(arg.val) != ptr::null() }; let fast_path = (arg_is_alloca || !bcx.ccx().sess.opts.extra_debuginfo) && simple_identifier(pat).is_some(); @@ -2109,37 +2111,42 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, llval: ValueRef) // `llval` wholesale as the pointer for `x`, avoiding the // general logic which may copy out of `llval`. let mut llargs = bcx.fcx.llargs.borrow_mut(); - llargs.get().insert(pat.id, llval); + llargs.get().insert(pat.id, arg); } else { // General path. Copy out the values that are used in the // pattern. - bcx = bind_irrefutable_pat(bcx, pat, llval, BindArgument); + let llptr = arg.to_ref_llval(bcx); + bcx = bind_irrefutable_pat(bcx, pat, llptr, BindArgument); } return bcx; } fn mk_binding_alloca<'a>( - mut bcx: &'a Block<'a>, + bcx: &'a Block<'a>, p_id: ast::NodeId, path: &ast::Path, binding_mode: IrrefutablePatternBindingMode, - populate: |&'a Block<'a>, - ty::t, - ValueRef| - -> &'a Block<'a>) + populate: |&'a Block<'a>, Datum| -> &'a Block<'a>) -> &'a Block<'a> { let var_ty = node_id_type(bcx, p_id); let ident = ast_util::path_to_ident(path); let llval = alloc_ty(bcx, var_ty, bcx.ident(ident)); - bcx = populate(bcx, var_ty, llval); - let mut llmap = match binding_mode { - BindLocal => bcx.fcx.lllocals.borrow_mut(), - BindArgument => bcx.fcx.llargs.borrow_mut(), + let datum = Datum { + val: llval, + ty: var_ty, + mode: ByRef(ZeroMem) }; - llmap.get().insert(p_id, llval); - add_clean(bcx, llval, var_ty); - return bcx; + { + let mut llmap = match binding_mode { + BindLocal => bcx.fcx.lllocals.borrow_mut(), + BindArgument => bcx.fcx.llargs.borrow_mut() + }; + llmap.get().insert(p_id, datum); + } + let bcx = populate(bcx, datum); + datum.add_clean(bcx); + bcx } fn bind_irrefutable_pat<'a>( @@ -2179,7 +2186,7 @@ fn bind_irrefutable_pat<'a>( let _indenter = indenter(); - let _icx = push_ctxt("alt::bind_irrefutable_pat"); + let _icx = push_ctxt("match::bind_irrefutable_pat"); let mut bcx = bcx; let tcx = bcx.tcx(); let ccx = bcx.ccx(); @@ -2191,21 +2198,23 @@ fn bind_irrefutable_pat<'a>( // map. bcx = mk_binding_alloca( bcx, pat.id, path, binding_mode, - |bcx, variable_ty, llvariable_val| { + |bcx, var_datum| { match pat_binding_mode { ast::BindByValue(_) => { // By value binding: move the value that `val` // points at into the binding's stack slot. - let datum = Datum {val: val, - ty: variable_ty, - mode: ByRef(ZeroMem)}; - datum.store_to(bcx, INIT, llvariable_val) + let datum = Datum { + val: val, + ty: var_datum.ty, + mode: ByRef(ZeroMem) + }; + datum.store_to(bcx, INIT, var_datum.val) } ast::BindByRef(_) => { // By ref binding: the value of the variable // is the pointer `val` itself. - Store(bcx, val, llvariable_val); + Store(bcx, val, var_datum.val); bcx } } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index ffcbd59c9e03a..11f217f3cb4b1 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -20,7 +20,6 @@ use middle::trans::callee; use middle::trans::common::*; use middle::trans::expr::*; use middle::trans::type_of::*; -use middle::ty; use middle::trans::type_::Type; @@ -56,7 +55,6 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm) unpack_result!(bcx, { callee::trans_arg_expr(bcx, expr_ty(bcx, input), - ty::ByCopy, input, &mut cleanups, callee::DontAutorefArg) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index dbe7a03ad0cd0..6fa3764fb379b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -53,12 +53,12 @@ use middle::trans::expr; use middle::trans::foreign; use middle::trans::glue; use middle::trans::inline; -use middle::trans::llrepr::LlvmRepr; use middle::trans::machine; use middle::trans::machine::{llalign_of_min, llsize_of}; use middle::trans::meth; use middle::trans::monomorphize; use middle::trans::tvec; +use middle::trans::type_::Type; use middle::trans::type_of; use middle::trans::type_of::*; use middle::trans::value::Value; @@ -66,7 +66,6 @@ use middle::ty; use util::common::indenter; use util::ppaux::{Repr, ty_to_str}; use util::sha2::Sha256; -use middle::trans::type_::Type; use extra::arena::TypedArena; use extra::time; @@ -218,7 +217,7 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, } } - let f = decl_rust_fn(ccx, inputs, output, name); + let f = decl_rust_fn(ccx, None, inputs, output, name); csearch::get_item_attrs(ccx.tcx.cstore, did, |meta_items| { set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).to_owned_vec(), f) }); @@ -228,8 +227,12 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, f } -fn decl_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, name: &str) -> ValueRef { - let llfty = type_of_rust_fn(ccx, inputs, output); +fn decl_rust_fn(ccx: &CrateContext, + self_ty: Option, + inputs: &[ty::t], + output: ty::t, + name: &str) -> ValueRef { + let llfty = type_of_rust_fn(ccx, self_ty, inputs, output); let llfn = decl_cdecl_fn(ccx.llmod, name, llfty); match ty::get(output).sty { @@ -241,7 +244,7 @@ fn decl_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, name: &str) } // `~` pointer return values never alias because ownership is transferred ty::ty_uniq(..) | - ty::ty_evec(_, ty::vstore_uniq) => { + ty::ty_vec(_, ty::vstore_uniq) => { unsafe { llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint); } @@ -257,13 +260,13 @@ fn decl_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, name: &str) match ty::get(arg_ty).sty { // `~` pointer parameters never alias because ownership is transferred ty::ty_uniq(..) | - ty::ty_evec(_, ty::vstore_uniq) | + ty::ty_vec(_, ty::vstore_uniq) | ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => { unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); } } - _ => () + _ => {} } } @@ -281,9 +284,10 @@ fn decl_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, name: &str) llfn } -pub fn decl_internal_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t, - name: &str) -> ValueRef { - let llfn = decl_rust_fn(ccx, inputs, output, name); +pub fn decl_internal_rust_fn(ccx: &CrateContext, + self_ty: Option, inputs: &[ty::t], + output: ty::t, name: &str) -> ValueRef { + let llfn = decl_rust_fn(ccx, self_ty, inputs, output, name); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); llfn } @@ -758,8 +762,8 @@ pub fn iter_structural_ty<'r, } }) } - ty::ty_estr(ty::vstore_fixed(_)) | - ty::ty_evec(_, ty::vstore_fixed(_)) => { + ty::ty_str(ty::vstore_fixed(_)) | + ty::ty_vec(_, ty::vstore_fixed(_)) => { let (base, len) = tvec::get_base_and_byte_len(cx, av, t); cx = tvec::iter_vec_raw(cx, base, t, len, f); } @@ -913,7 +917,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val Some(..) | None => { let c = foreign::llvm_calling_convention(ccx, fn_ty.abis); let cconv = c.unwrap_or(lib::llvm::CCallConv); - let llty = type_of_fn_from_ty(ccx, t); + let llty = type_of_fn_from_ty(ccx, None, t); let mut externs = ccx.externs.borrow_mut(); get_extern_fn(externs.get(), ccx.llmod, name, cconv, llty) } @@ -1013,7 +1017,7 @@ pub fn need_invoke(bcx: &Block) -> bool { let cleanups = inf.cleanups.borrow(); for cleanup in cleanups.get().iter() { match *cleanup { - clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { + Clean(_, cleanup_type) | CleanTemp(_, _, cleanup_type) => { if cleanup_type == normal_exit_and_unwind { return true; } @@ -1365,7 +1369,7 @@ pub fn trans_block_cleanups_<'a>( let mut bcx = bcx; for cu in cleanups.rev_iter() { match *cu { - clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) => { + Clean(cfn, cleanup_type) | CleanTemp(_, cfn, cleanup_type) => { // Some types don't need to be cleaned up during // landing pads because they can be freed en mass later if cleanup_type == normal_exit_and_unwind || !is_lpad { @@ -1639,7 +1643,7 @@ pub fn zero_mem(cx: &Block, llptr: ValueRef, t: ty::t) { // allocation for large data structures, and the generated code will be // awful. (A telltale sign of this is large quantities of // `mov [byte ptr foo],0` in the generated code.) -pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { +fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { let _icx = push_ctxt("memzero"); let ccx = b.ccx; @@ -1865,69 +1869,116 @@ pub fn new_fn_ctxt(ccx: @CrateContext, // spaces that have been created for them (by code in the llallocas field of // the function's fn_ctxt). create_llargs_for_fn_args populates the llargs // field of the fn_ctxt with -pub fn create_llargs_for_fn_args(cx: &FunctionContext, - self_arg: self_arg, - args: &[ast::Arg]) - -> ~[ValueRef] { +fn create_llargs_for_fn_args(cx: &FunctionContext, + self_arg: Option, + arg_tys: &[ty::t]) + -> ~[datum::Datum] { let _icx = push_ctxt("create_llargs_for_fn_args"); match self_arg { - impl_self(tt, self_mode) => { - cx.llself.set(Some(ValSelfData { - v: cx.llenv.get(), - t: tt, - is_copy: self_mode == ty::ByCopy - })); - } - no_self => () + Some(t) => { + cx.llself.set(Some(datum::Datum { + val: cx.llenv.get(), + ty: t, + mode: if arg_is_indirect(cx.ccx, t) { + datum::ByRef(datum::ZeroMem) + } else { + datum::ByValue + } + })); + } + None => {} } - // Return an array containing the ValueRefs that we get from - // llvm::LLVMGetParam for each argument. - vec::from_fn(args.len(), |i| { - unsafe { llvm::LLVMGetParam(cx.llfn, cx.arg_pos(i) as c_uint) } - }) + // Return an array wrapping the ValueRefs that we get from + // llvm::LLVMGetParam for each argument into datums. + arg_tys.iter().enumerate().map(|(i, &arg_ty)| { + let llarg = unsafe { llvm::LLVMGetParam(cx.llfn, cx.arg_pos(i) as c_uint) }; + datum::Datum { + val: llarg, + ty: arg_ty, + mode: if arg_is_indirect(cx.ccx, arg_ty) { + datum::ByRef(datum::ZeroMem) + } else { + datum::ByValue + } + } + }).collect() } -pub fn copy_args_to_allocas<'a>( - fcx: &FunctionContext<'a>, +fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>, bcx: &'a Block<'a>, args: &[ast::Arg], - raw_llargs: &[ValueRef], - arg_tys: &[ty::t]) + method: Option<&ast::Method>, + raw_llargs: &[datum::Datum]) -> &'a Block<'a> { - debug!("copy_args_to_allocas: raw_llargs={} arg_tys={}", - raw_llargs.llrepr(fcx.ccx), - arg_tys.repr(fcx.ccx.tcx)); + debug!("copy_args_to_allocas: args=[{}]", + raw_llargs.map(|d| d.to_str(fcx.ccx)).connect(", ")); let _icx = push_ctxt("copy_args_to_allocas"); let mut bcx = bcx; match fcx.llself.get() { Some(slf) => { - let self_val = if slf.is_copy - && datum::appropriate_mode(bcx.ccx(), slf.t).is_by_value() { - let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t)); - let alloc = alloc_ty(bcx, slf.t, "__self"); - Store(bcx, tmp, alloc); - alloc + let needs_indirection = if slf.mode.is_by_value() { + // FIXME(eddyb) #11445 Always needs indirection because of cleanup. + if true { + true + } else { + match method { + Some(method) => { + match method.explicit_self.node { + ast::SelfValue(ast::MutMutable) => true, + _ => false + } + } + None => true + } + } + } else { + false + }; + let slf = if needs_indirection { + // HACK(eddyb) this is just slf.to_ref_datum(bcx) with a named alloca. + let alloc = alloc_ty(bcx, slf.ty, "__self"); + Store(bcx, slf.val, alloc); + datum::Datum { + val: alloc, + ty: slf.ty, + mode: datum::ByRef(datum::ZeroMem) + } } else { - PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) + slf }; - fcx.llself.set(Some(ValSelfData {v: self_val, ..slf})); - add_clean(bcx, self_val, slf.t); + fcx.llself.set(Some(slf)); + slf.add_clean(bcx); if fcx.ccx.sess.opts.extra_debuginfo { - debuginfo::create_self_argument_metadata(bcx, slf.t, self_val); + debuginfo::create_self_argument_metadata(bcx, slf.ty, slf.val); } } _ => {} } - for (arg_n, &arg_ty) in arg_tys.iter().enumerate() { - let raw_llarg = raw_llargs[arg_n]; - + for (i, &arg) in raw_llargs.iter().enumerate() { + let needs_indirection = if arg.mode.is_by_value() { + if fcx.ccx.sess.opts.extra_debuginfo { + true + } else { + // FIXME(eddyb) #11445 Always needs indirection because of cleanup. + if true { + true + } else { + match args[i].pat.node { + ast::PatIdent(ast::BindByValue(ast::MutMutable), _, _) => true, + _ => false + } + } + } + } else { + false + }; // For certain mode/type combinations, the raw llarg values are passed // by value. However, within the fn body itself, we want to always // have all locals and arguments be by-ref so that we can cancel the @@ -1935,18 +1986,28 @@ pub fn copy_args_to_allocas<'a>( // the argument would be passed by value, we store it into an alloca. // This alloca should be optimized away by LLVM's mem-to-reg pass in // the event it's not truly needed. - // only by value if immediate: - let llarg = if datum::appropriate_mode(bcx.ccx(), arg_ty).is_by_value() { - let alloc = alloc_ty(bcx, arg_ty, "__arg"); - Store(bcx, raw_llarg, alloc); - alloc + let arg = if needs_indirection { + // HACK(eddyb) this is just arg.to_ref_datum(bcx) with a named alloca. + let alloc = match args[i].pat.node { + ast::PatIdent(_, ref path, _) => { + let name = ast_util::path_to_ident(path).name; + alloc_ty(bcx, arg.ty, token::interner_get(name)) + } + _ => alloc_ty(bcx, arg.ty, "__arg") + }; + Store(bcx, arg.val, alloc); + datum::Datum { + val: alloc, + ty: arg.ty, + mode: datum::ByRef(datum::ZeroMem) + } } else { - raw_llarg + arg }; - bcx = _match::store_arg(bcx, args[arg_n].pat, llarg); + bcx = _match::store_arg(bcx, args[i].pat, arg); if fcx.ccx.sess.opts.extra_debuginfo { - debuginfo::create_argument_metadata(bcx, &args[arg_n]); + debuginfo::create_argument_metadata(bcx, &args[i]); } } @@ -2001,8 +2062,6 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) { Ret(ret_cx, retval); } -pub enum self_arg { impl_self(ty::t, ty::SelfMode), no_self, } - // trans_closure: Builds an LLVM function out of a source function. // If the function closes over its environment a closure will be // returned. @@ -2011,9 +2070,10 @@ pub fn trans_closure(ccx: @CrateContext, decl: &ast::FnDecl, body: &ast::Block, llfndecl: ValueRef, - self_arg: self_arg, + self_arg: Option, param_substs: Option<@param_substs>, id: ast::NodeId, + method: Option<&ast::Method>, _attributes: &[ast::Attribute], output_type: ty::t, maybe_load_env: |&FunctionContext|) { @@ -2042,9 +2102,9 @@ pub fn trans_closure(ccx: @CrateContext, // Set up arguments to the function. let arg_tys = ty::ty_fn_args(node_id_type(bcx, id)); - let raw_llargs = create_llargs_for_fn_args(&fcx, self_arg, decl.inputs); + let raw_llargs = create_llargs_for_fn_args(&fcx, self_arg, arg_tys); - bcx = copy_args_to_allocas(&fcx, bcx, decl.inputs, raw_llargs, arg_tys); + bcx = copy_args_to_allocas(&fcx, bcx, decl.inputs, method, raw_llargs); maybe_load_env(&fcx); @@ -2089,9 +2149,10 @@ pub fn trans_fn(ccx: @CrateContext, decl: &ast::FnDecl, body: &ast::Block, llfndecl: ValueRef, - self_arg: self_arg, + self_arg: Option, param_substs: Option<@param_substs>, id: ast::NodeId, + method: Option<&ast::Method>, attrs: &[ast::Attribute]) { let the_path_str = path_str(ccx.sess, path); @@ -2109,6 +2170,7 @@ pub fn trans_fn(ccx: @CrateContext, self_arg, param_substs, id, + method, attrs, output_type, |_fcx| { }); @@ -2191,14 +2253,13 @@ impl IdAndTy for ast::StructField { fn ty(&self) -> ast::P { self.node.ty } } -pub fn trans_enum_variant_or_tuple_like_struct( +fn trans_enum_variant_or_tuple_like_struct( ccx: @CrateContext, ctor_id: ast::NodeId, args: &[A], disr: ty::Disr, param_substs: Option<@param_substs>, - llfndecl: ValueRef) -{ + llfndecl: ValueRef) { // Translate variant arguments to function arguments. let fn_args = args.map(|varg| { ast::Arg { @@ -2247,12 +2308,12 @@ pub fn trans_enum_variant_or_tuple_like_struct( let arg_tys = ty::ty_fn_args(ctor_ty); - let raw_llargs = create_llargs_for_fn_args(&fcx, no_self, fn_args); + let raw_llargs = create_llargs_for_fn_args(&fcx, None, arg_tys); let bcx = fcx.entry_bcx.get().unwrap(); insert_synthetic_type_entries(bcx, fn_args, arg_tys); - let bcx = copy_args_to_allocas(&fcx, bcx, fn_args, raw_llargs, arg_tys); + let bcx = copy_args_to_allocas(&fcx, bcx, fn_args, None, raw_llargs); let repr = adt::represent_type(ccx, result_ty); adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr); @@ -2266,8 +2327,7 @@ pub fn trans_enum_variant_or_tuple_like_struct( let llargs = fcx.llargs.borrow(); llargs.get().get_copy(&fn_arg.pat.id) }; - let arg_ty = arg_tys[i]; - memcpy_ty(bcx, lldestptr, llarg, arg_ty); + llarg.move_to(bcx, datum::INIT, lldestptr); } finish_fn(&fcx, bcx); } @@ -2334,9 +2394,10 @@ pub fn trans_item(ccx: @CrateContext, item: &ast::Item) { decl, body, llfndecl, - no_self, + None, None, item.id, + None, item.attrs); } else { // Be sure to travel more than just one layer deep to catch nested @@ -2448,12 +2509,13 @@ fn finish_register_fn(ccx: @CrateContext, sp: Span, sym: ~str, node_id: ast::Nod } } -pub fn register_fn(ccx: @CrateContext, - sp: Span, - sym: ~str, - node_id: ast::NodeId, - node_type: ty::t) - -> ValueRef { +fn register_fn(ccx: @CrateContext, + sp: Span, + sym: ~str, + node_id: ast::NodeId, + node_type: ty::t, + self_ty: Option) + -> ValueRef { let f = match ty::get(node_type).sty { ty::ty_bare_fn(ref f) => { assert!(f.abis.is_rust() || f.abis.is_intrinsic()); @@ -2462,7 +2524,7 @@ pub fn register_fn(ccx: @CrateContext, _ => fail!("expected bare rust fn or an intrinsic") }; - let llfn = decl_rust_fn(ccx, f.sig.inputs, f.sig.output, sym); + let llfn = decl_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, sym); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -2722,7 +2784,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef { ast::ItemFn(_, purity, _, _, _) => { let llfn = if purity != ast::ExternFn { - register_fn(ccx, i.span, sym, i.id, ty) + register_fn(ccx, i.span, sym, i.id, ty, None) } else { foreign::register_rust_fn_with_foreign_abi(ccx, i.span, @@ -2826,7 +2888,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef { llfn = match enm.node { ast::ItemEnum(_, _) => { - register_fn(ccx, (*v).span, sym, id, ty) + register_fn(ccx, (*v).span, sym, id, ty, None) } _ => fail!("NodeVariant, shouldn't happen") }; @@ -2851,7 +2913,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef { let sym = exported_name(ccx, (*struct_path).clone(), ty, struct_item.attrs); let llfn = register_fn(ccx, struct_item.span, - sym, ctor_id, ty); + sym, ctor_id, ty, None); set_inline_hint(llfn); llfn } @@ -2881,10 +2943,10 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef { } } -pub fn register_method(ccx: @CrateContext, - id: ast::NodeId, - path: @ast_map::Path, - m: @ast::Method) -> ValueRef { +fn register_method(ccx: @CrateContext, + id: ast::NodeId, + path: @ast_map::Path, + m: &ast::Method) -> ValueRef { let mty = ty::node_id_to_type(ccx.tcx, id); let mut path = (*path).clone(); @@ -2892,7 +2954,11 @@ pub fn register_method(ccx: @CrateContext, let sym = exported_name(ccx, path, mty, m.attrs); - let llfn = register_fn(ccx, m.span, sym, id, mty); + let self_ty = match m.explicit_self.node { + ast::SelfStatic => None, + _ => Some(ty::node_id_to_type(ccx.tcx, m.self_id)) + }; + let llfn = register_fn(ccx, m.span, sym, id, mty, self_ty); set_llvm_fn_attrs(m.attrs, llfn); llfn } @@ -3120,12 +3186,12 @@ pub fn create_module_map(ccx: &CrateContext) -> (ValueRef, uint) { }; for key in keys.iter() { - let llestrval = C_estr_slice(ccx, *key); + let llstrval = C_str_slice(ccx, *key); let module_data = ccx.module_data.borrow(); let val = *module_data.get().find_equiv(key).unwrap(); let v_ptr = p2i(ccx, val); let elt = C_struct([ - llestrval, + llstrval, v_ptr ], false); elts.push(elt); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 795ccb200a0ab..c1451a8fe1e12 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -60,8 +60,7 @@ pub struct FnData { pub struct MethodData { llfn: ValueRef, llself: ValueRef, - temp_cleanup: Option, - self_mode: ty::SelfMode, + temp_cleanup: Option } pub enum CalleeData { @@ -398,7 +397,7 @@ pub fn trans_fn_ref_with_vtables( let ref_ty = common::node_id_type(bcx, ref_id); val = PointerCast( - bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to()); + bcx, val, type_of::type_of_fn_from_ty(ccx, None, ref_ty).ptr_to()); } return FnData {llfn: val}; } @@ -437,7 +436,7 @@ pub fn trans_fn_ref_with_vtables( // This can occur on either a crate-local or crate-external // reference. It also occurs when testing libcore and in some // other weird situations. Annoying. - let llty = type_of::type_of_fn_from_ty(ccx, fn_tpt.ty); + let llty = type_of::type_of_fn_from_ty(ccx, None, fn_tpt.ty); let llptrty = llty.ptr_to(); if val_ty(val) != llptrty { val = BitCast(bcx, val, llptrty); @@ -496,10 +495,7 @@ pub fn trans_method_call<'a>( call_ex.repr(in_cx.tcx()), origin.repr(in_cx.tcx())); - meth::trans_method_callee(cx, - callee_id, - rcvr, - origin) + meth::trans_method_callee(cx, callee_id, rcvr, origin) } None => { cx.tcx().sess.span_bug(call_ex.span, "method call expr wasn't in method map") @@ -704,7 +700,7 @@ pub fn trans_call_inner<'a>( match ty::get(ret_ty).sty { // `~` pointer return values never alias because ownership is transferred ty::ty_uniq(..) | - ty::ty_evec(_, ty::vstore_uniq) => { + ty::ty_vec(_, ty::vstore_uniq) => { attrs.push((0, NoAliasAttribute)); } _ => () @@ -799,7 +795,6 @@ pub fn trans_args<'a>( let arg_val = unpack_result!(bcx, { trans_arg_expr(bcx, arg_ty, - ty::ByCopy, *arg_expr, &mut temp_cleanups, autoref_arg) @@ -832,7 +827,6 @@ pub enum AutorefArg { pub fn trans_arg_expr<'a>( bcx: &'a Block<'a>, formal_arg_ty: ty::t, - self_mode: ty::SelfMode, arg_expr: &ast::Expr, temp_cleanups: &mut ~[ValueRef], autoref_arg: AutorefArg) @@ -840,9 +834,8 @@ pub fn trans_arg_expr<'a>( let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); - debug!("trans_arg_expr(formal_arg_ty=({}), self_mode={:?}, arg_expr={})", + debug!("trans_arg_expr(formal_arg_ty=({}), arg_expr={})", formal_arg_ty.repr(bcx.tcx()), - self_mode, arg_expr.repr(bcx.tcx())); // translate the arg expr to a datum @@ -888,16 +881,8 @@ pub fn trans_arg_expr<'a>( arg_datum }; - val = match self_mode { - ty::ByRef => { - debug!("by ref arg with type {}", bcx.ty_to_str(arg_datum.ty)); - arg_datum.to_ref_llval(bcx) - } - ty::ByCopy => { - debug!("by copy arg with type {}", bcx.ty_to_str(arg_datum.ty)); - arg_datum.to_appropriate_llval(bcx) - } - } + debug!("by copy arg with type {}", bcx.ty_to_str(arg_datum.ty)); + val = arg_datum.to_appropriate_llval(bcx); } } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 5a9d7b0a283d0..25bc968b987dc 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -405,7 +405,7 @@ pub fn trans_expr_fn<'a>( let s = mangle_internal_name_by_path_and_seq(ccx, sub_path.clone(), "expr_fn"); - let llfn = decl_internal_rust_fn(ccx, f.sig.inputs, f.sig.output, s); + let llfn = decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, s); // set an inline hint for all closures set_inline_hint(llfn); @@ -423,9 +423,10 @@ pub fn trans_expr_fn<'a>( decl, body, llfn, - no_self, + None, bcx.fcx.param_substs, user_id, + None, [], ty::ty_fn_ret(fty), |fcx| load_environment(fcx, cdata_ty, cap_vars, sigil)); @@ -474,7 +475,7 @@ pub fn make_opaque_cbox_drop_glue<'a>( bcx.tcx().sess.bug("trying to trans drop glue of @fn") } ast::OwnedSigil => { - glue::free_ty( + glue::make_free_glue( bcx, cboxptr, ty::mk_opaque_closure_ptr(bcx.tcx(), sigil)) } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index dab701a0e1f92..7f6ab2dd9d154 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -94,7 +94,6 @@ pub struct tydesc_info { name: ValueRef, take_glue: Cell>, drop_glue: Cell>, - free_glue: Cell>, visit_glue: Cell>, } @@ -159,13 +158,6 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { pub type ExternMap = HashMap<~str, ValueRef>; -// Types used for llself. -pub struct ValSelfData { - v: ValueRef, - t: ty::t, - is_copy: bool, -} - // Here `self_ty` is the real type of the self parameter to this method. It // will only be set in the case of default methods. pub struct param_substs { @@ -228,7 +220,7 @@ pub struct FunctionContext<'a> { // NB: This is the type of the self *variable*, not the self *type*. The // self type is set only for default methods, while the self variable is // set for all methods. - llself: Cell>, + llself: Cell>, // The a value alloca'd for calls to upcalls.rust_personality. Used when // outputting the resume instruction. personality: Cell>, @@ -239,10 +231,10 @@ pub struct FunctionContext<'a> { caller_expects_out_pointer: bool, // Maps arguments to allocas created for them in llallocas. - llargs: RefCell>, + llargs: RefCell>, // Maps the def_ids for local variables to the allocas created for // them in llallocas. - lllocals: RefCell>, + lllocals: RefCell>, // Same as above, but for closure upvars llupvars: RefCell>, @@ -343,28 +335,14 @@ pub trait CleanupFunction { } /// A cleanup function that calls the "drop glue" (destructor function) on -/// a typed value. -pub struct TypeDroppingCleanupFunction { - val: ValueRef, - t: ty::t, -} - -impl CleanupFunction for TypeDroppingCleanupFunction { - fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> { - glue::drop_ty(block, self.val, self.t) - } -} - -/// A cleanup function that calls the "drop glue" (destructor function) on -/// an immediate typed value. -pub struct ImmediateTypeDroppingCleanupFunction { - val: ValueRef, - t: ty::t, +/// a datum. +struct DatumDroppingCleanupFunction { + datum: datum::Datum } -impl CleanupFunction for ImmediateTypeDroppingCleanupFunction { +impl CleanupFunction for DatumDroppingCleanupFunction { fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> { - glue::drop_ty_immediate(block, self.val, self.t) + self.datum.drop_val(block) } } @@ -391,16 +369,16 @@ impl CleanupFunction for ExchangeHeapFreeingCleanupFunction { } pub enum cleanup { - clean(@CleanupFunction, cleantype), - clean_temp(ValueRef, @CleanupFunction, cleantype), + Clean(@CleanupFunction, cleantype), + CleanTemp(ValueRef, @CleanupFunction, cleantype), } // Can't use deriving(Clone) because of the managed closure. impl Clone for cleanup { fn clone(&self) -> cleanup { match *self { - clean(f, ct) => clean(f, ct), - clean_temp(v, f, ct) => clean_temp(v, f, ct), + Clean(f, ct) => Clean(f, ct), + CleanTemp(v, f, ct) => CleanTemp(v, f, ct), } } } @@ -439,20 +417,21 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype { } } -pub fn add_clean(bcx: &Block, val: ValueRef, t: ty::t) { - if !ty::type_needs_drop(bcx.tcx(), t) { - return - } +pub fn add_clean(bcx: &Block, val: ValueRef, ty: ty::t) { + if !ty::type_needs_drop(bcx.tcx(), ty) { return; } - debug!("add_clean({}, {}, {})", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); + debug!("add_clean({}, {}, {})", bcx.to_str(), bcx.val_to_str(val), ty.repr(bcx.tcx())); - let cleanup_type = cleanup_type(bcx.tcx(), t); + let cleanup_type = cleanup_type(bcx.tcx(), ty); in_scope_cx(bcx, None, |scope_info| { { let mut cleanups = scope_info.cleanups.borrow_mut(); - cleanups.get().push(clean(@TypeDroppingCleanupFunction { - val: val, - t: t, + cleanups.get().push(Clean(@DatumDroppingCleanupFunction { + datum: datum::Datum { + val: val, + ty: ty, + mode: datum::ByRef(datum::ZeroMem) + } } as @CleanupFunction, cleanup_type)); } @@ -460,21 +439,24 @@ pub fn add_clean(bcx: &Block, val: ValueRef, t: ty::t) { }) } -pub fn add_clean_temp_immediate(cx: &Block, val: ValueRef, ty: ty::t) { - if !ty::type_needs_drop(cx.tcx(), ty) { return; } +pub fn add_clean_temp_immediate(bcx: &Block, val: ValueRef, ty: ty::t) { + if !ty::type_needs_drop(bcx.tcx(), ty) { return; } + debug!("add_clean_temp_immediate({}, {}, {})", - cx.to_str(), cx.val_to_str(val), - ty.repr(cx.tcx())); - let cleanup_type = cleanup_type(cx.tcx(), ty); - in_scope_cx(cx, None, |scope_info| { + bcx.to_str(), bcx.val_to_str(val), + ty.repr(bcx.tcx())); + let cleanup_type = cleanup_type(bcx.tcx(), ty); + in_scope_cx(bcx, None, |scope_info| { { let mut cleanups = scope_info.cleanups.borrow_mut(); - cleanups.get().push(clean_temp(val, - @ImmediateTypeDroppingCleanupFunction { + cleanups.get().push(CleanTemp(val, @DatumDroppingCleanupFunction { + datum: datum::Datum { val: val, - t: ty, - } as @CleanupFunction, - cleanup_type)); + ty: ty, + mode: datum::ByValue + } + } as @CleanupFunction, + cleanup_type)); } grow_scope_clean(scope_info); }) @@ -501,12 +483,14 @@ pub fn add_clean_temp_mem_in_scope_(bcx: &Block, scope_id: Option, in_scope_cx(bcx, scope_id, |scope_info| { { let mut cleanups = scope_info.cleanups.borrow_mut(); - cleanups.get().push(clean_temp(val, - @TypeDroppingCleanupFunction { + cleanups.get().push(CleanTemp(val, @DatumDroppingCleanupFunction { + datum: datum::Datum { val: val, - t: t, - } as @CleanupFunction, - cleanup_type)); + ty: t, + mode: datum::ByRef(datum::RevokeClean) + } + } as @CleanupFunction, + cleanup_type)); } grow_scope_clean(scope_info); }) @@ -528,7 +512,7 @@ pub fn add_clean_free(cx: &Block, ptr: ValueRef, heap: heap) { in_scope_cx(cx, None, |scope_info| { { let mut cleanups = scope_info.cleanups.borrow_mut(); - cleanups.get().push(clean_temp(ptr, + cleanups.get().push(CleanTemp(ptr, free_fn, normal_exit_and_unwind)); } @@ -544,22 +528,26 @@ pub fn revoke_clean(cx: &Block, val: ValueRef) { in_scope_cx(cx, None, |scope_info| { let cleanup_pos = { let mut cleanups = scope_info.cleanups.borrow_mut(); + debug!("revoke_clean({}, {}) revoking {:?} from {:?}", + cx.to_str(), cx.val_to_str(val), val, cleanups.get()); cleanups.get().iter().position(|cu| { match *cu { - clean_temp(v, _, _) if v == val => true, + CleanTemp(v, _, _) if v == val => true, _ => false } }) }; - for i in cleanup_pos.iter() { + debug!("revoke_clean({}, {}) revoking {:?}", + cx.to_str(), cx.val_to_str(val), cleanup_pos); + for &i in cleanup_pos.iter() { let new_cleanups = { let cleanups = scope_info.cleanups.borrow(); - vec::append(cleanups.get().slice(0u, *i).to_owned(), - cleanups.get().slice(*i + 1u, cleanups.get() - .len())) + vec::append(cleanups.get().slice(0u, i).to_owned(), + cleanups.get().slice(i + 1u, cleanups.get() + .len())) }; scope_info.cleanups.set(new_cleanups); - shrink_scope_clean(scope_info, *i); + shrink_scope_clean(scope_info, i); } }) } @@ -768,16 +756,16 @@ pub fn in_scope_cx<'a>( Some(inf) => match scope_id { Some(wanted) => match inf.node_info { Some(NodeInfo { id: actual, .. }) if wanted == actual => { - debug!("in_scope_cx: selected cur={} (cx={})", - cur.to_str(), cx.to_str()); + debug!("in_scope_cx: selected cur={} (cx={}) info={:?}", + cur.to_str(), cx.to_str(), inf.node_info); f(inf); return; }, _ => inf.parent, }, None => { - debug!("in_scope_cx: selected cur={} (cx={})", - cur.to_str(), cx.to_str()); + debug!("in_scope_cx: selected cur={} (cx={}) info={:?}", + cur.to_str(), cx.to_str(), inf.node_info); f(inf); return; } @@ -906,7 +894,7 @@ pub fn C_cstr(cx: &CrateContext, s: @str) -> ValueRef { // NB: Do not use `do_spill_noroot` to make this into a constant string, or // you will be kicked off fast isel. See issue #4352 for an example of this. -pub fn C_estr_slice(cx: &CrateContext, s: @str) -> ValueRef { +pub fn C_str_slice(cx: &CrateContext, s: @str) -> ValueRef { unsafe { let len = s.len(); let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p().to_ref()); @@ -1043,10 +1031,9 @@ pub enum MonoDataClass { pub fn mono_data_classify(t: ty::t) -> MonoDataClass { match ty::get(t).sty { ty::ty_float(_) => MonoFloat, - ty::ty_rptr(..) | ty::ty_uniq(..) | - ty::ty_box(..) | ty::ty_opaque_box(..) | - ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) | + ty::ty_rptr(..) | ty::ty_uniq(..) | ty::ty_box(..) | + ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) | + ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) | ty::ty_bare_fn(..) => MonoNonNull, // Is that everything? Would closures or slices qualify? _ => MonoBits diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 8cde68225c940..1f8ac5b5aeb6d 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -71,7 +71,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit) } ast::LitBool(b) => C_bool(b), ast::LitNil => C_nil(), - ast::LitStr(s, _) => C_estr_slice(cx, s), + ast::LitStr(s, _) => C_str_slice(cx, s), ast::LitBinary(data) => C_binary_slice(cx, data), } } @@ -241,7 +241,7 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) { assert_eq!(abi::slice_elt_len, 1); match ty::get(ty).sty { - ty::ty_evec(_, ty::vstore_fixed(len)) => { + ty::ty_vec(_, ty::vstore_fixed(len)) => { llconst = C_struct([llptr, C_uint(cx, len)], false); } _ => {} @@ -419,7 +419,7 @@ fn const_expr_unadjusted(cx: @CrateContext, "index is not an integer-constant expression") }; let (arr, len) = match ty::get(bt).sty { - ty::ty_evec(_, vstore) | ty::ty_estr(vstore) => + ty::ty_vec(_, vstore) | ty::ty_str(vstore) => match vstore { ty::vstore_fixed(u) => (bv, C_uint(cx, u)), @@ -437,7 +437,7 @@ fn const_expr_unadjusted(cx: @CrateContext, let len = llvm::LLVMConstIntGetZExtValue(len) as u64; let len = match ty::get(bt).sty { - ty::ty_estr(..) => {assert!(len > 0); len - 1}, + ty::ty_str(..) => {assert!(len > 0); len - 1}, _ => len }; if iv >= len { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index b34e68d9a57b7..e7eab31ac14e7 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -113,6 +113,7 @@ pub enum CopyAction { DROP_EXISTING } +#[deriving(Clone)] pub struct Datum { /// The llvm value. This is either a pointer to the Rust value or /// the value itself, depending on `mode` below. @@ -130,7 +131,7 @@ pub struct DatumBlock<'a> { datum: Datum, } -#[deriving(Eq, IterBytes)] +#[deriving(Clone, Eq, IterBytes)] pub enum DatumMode { /// `val` is a pointer to the actual value (and thus has type *T). /// The argument indicates how to cancel cleanup of this datum if @@ -153,7 +154,7 @@ impl DatumMode { } /// See `Datum cleanup styles` section at the head of this module. -#[deriving(Eq, IterBytes)] +#[deriving(Clone, Eq, IterBytes)] pub enum DatumCleanup { RevokeClean, ZeroMem @@ -396,8 +397,7 @@ impl Datum { add_clean_temp_mem(bcx, self.val, self.ty); } ByRef(ZeroMem) => { - bcx.tcx().sess.bug( - format!("Cannot add clean to a 'zero-mem' datum")); + add_clean(bcx, self.val, self.ty) } } } @@ -413,7 +413,6 @@ impl Datum { // Lvalues which potentially need to be dropped // must be passed by ref, so that we can zero them // out. - assert!(self.mode.is_by_ref()); zero_mem(bcx, self.val, self.ty); } } @@ -571,7 +570,7 @@ impl Datum { let (content_ty, header) = match ty::get(self.ty).sty { ty::ty_box(typ) => (typ, true), ty::ty_uniq(mt) => (mt.ty, false), - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { + ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => { let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty); let unboxed_vec_ty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); (unboxed_vec_ty, true) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 11804369a583b..fa620cca35eaf 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -133,6 +133,7 @@ use middle::trans::adt; use middle::trans::base; use middle::trans::build; use middle::trans::common::*; +use middle::trans::datum; use middle::trans::machine; use middle::trans::type_of; use middle::trans::type_::Type; @@ -280,12 +281,11 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) { pat_util::pat_bindings(def_map, local.pat, |_, node_id, span, path_ref| { let var_ident = ast_util::path_to_ident(path_ref); - let var_type = node_id_type(bcx, node_id); - let llptr = { + let datum = { let lllocals = bcx.fcx.lllocals.borrow(); match lllocals.get().find_copy(&node_id) { - Some(v) => v, + Some(datum) => datum, None => { bcx.tcx().sess.span_bug(span, format!("No entry in lllocals table for {:?}", @@ -298,9 +298,9 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) { declare_local(bcx, var_ident, - var_type, + datum.ty, scope_metadata, - DirectVariable { alloca: llptr }, + DirectVariable { alloca: datum.val }, LocalVariable, span); }) @@ -382,33 +382,19 @@ pub fn create_captured_var_metadata(bcx: &Block, pub fn create_match_binding_metadata(bcx: &Block, variable_ident: ast::Ident, node_id: ast::NodeId, - variable_type: ty::t, - span: Span) { + span: Span, + datum: datum::Datum) { if fn_should_be_ignored(bcx.fcx) { return; } - let llptr = { - let lllocals = bcx.fcx.lllocals.borrow(); - match lllocals.get().find_copy(&node_id) { - Some(v) => v, - None => { - bcx.tcx() - .sess - .span_bug(span, - format!("No entry in lllocals table for {:?}", - node_id)); - } - } - }; - let scope_metadata = scope_metadata(bcx.fcx, node_id, span); declare_local(bcx, variable_ident, - variable_type, + datum.ty, scope_metadata, - DirectVariable { alloca: llptr }, + DirectVariable { alloca: datum.val }, LocalVariable, span); } @@ -506,7 +492,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; pat_util::pat_bindings(def_map, arg.pat, |_, node_id, span, path_ref| { - let llptr = { + let llarg = { let llargs = bcx.fcx.llargs.borrow(); match llargs.get().find_copy(&node_id) { Some(v) => v, @@ -518,12 +504,11 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { } }; - if unsafe { llvm::LLVMIsAAllocaInst(llptr) } == ptr::null() { + if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null() { cx.sess.span_bug(span, "debuginfo::create_argument_metadata() - \ Referenced variable location is not an alloca!"); } - let argument_type = node_id_type(bcx, node_id); let argument_ident = ast_util::path_to_ident(path_ref); let argument_index = { @@ -535,9 +520,9 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { declare_local(bcx, argument_ident, - argument_type, + llarg.ty, scope_metadata, - DirectVariable { alloca: llptr }, + DirectVariable { alloca: llarg.val }, ArgumentVariable(argument_index), span); }) @@ -2115,7 +2100,7 @@ fn type_metadata(cx: &CrateContext, ty::ty_float(_) => { basic_type_metadata(cx, t) }, - ty::ty_estr(ref vstore) => { + ty::ty_str(ref vstore) => { let i8_t = ty::mk_i8(); match *vstore { ty::vstore_fixed(len) => { @@ -2140,7 +2125,7 @@ fn type_metadata(cx: &CrateContext, ty::ty_box(typ) => { create_pointer_to_box_metadata(cx, t, typ) }, - ty::ty_evec(ref mt, ref vstore) => { + ty::ty_vec(ref mt, ref vstore) => { match *vstore { ty::vstore_fixed(len) => { fixed_vec_metadata(cx, mt.ty, len, usage_site_span) @@ -2185,9 +2170,6 @@ fn type_metadata(cx: &CrateContext, }, ty::ty_tup(ref elements) => { prepare_tuple_metadata(cx, t, *elements, usage_site_span).finalize(cx) - }, - ty::ty_opaque_box => { - create_pointer_to_box_metadata(cx, t, ty::mk_nil()) } _ => cx.sess.bug(format!("debuginfo: unexpected type in type_metadata: {:?}", sty)) }; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 06a85d7028452..1641e4a8bde92 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -287,9 +287,9 @@ pub fn trans_to_datum<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) // this type may have a different region/mutability than the // real one, but it will have the same runtime representation - let slice_ty = ty::mk_evec(tcx, - ty::mt { ty: unit_ty, mutbl: ast::MutImmutable }, - ty::vstore_slice(ty::ReStatic)); + let slice_ty = ty::mk_vec(tcx, + ty::mt { ty: unit_ty, mutbl: ast::MutImmutable }, + ty::vstore_slice(ty::ReStatic)); let scratch = scratch_datum(bcx, slice_ty, "__adjust", false); @@ -1172,7 +1172,7 @@ pub fn trans_local_var(bcx: &Block, def: ast::Def) -> Datum { take_local(bcx, lllocals.get(), nid) } ast::DefSelf(nid, _) => { - let self_info: ValSelfData = match bcx.fcx.llself.get() { + let self_info = match bcx.fcx.llself.get() { Some(self_info) => self_info, None => { bcx.sess().bug(format!( @@ -1181,14 +1181,10 @@ pub fn trans_local_var(bcx: &Block, def: ast::Def) -> Datum { } }; - debug!("def_self() reference, self_info.t={}", - self_info.t.repr(bcx.tcx())); + debug!("def_self() reference, self_info.ty={}", + self_info.ty.repr(bcx.tcx())); - Datum { - val: self_info.v, - ty: self_info.t, - mode: ByRef(ZeroMem) - } + self_info } _ => { bcx.sess().unimpl(format!( @@ -1197,24 +1193,18 @@ pub fn trans_local_var(bcx: &Block, def: ast::Def) -> Datum { }; fn take_local(bcx: &Block, - table: &HashMap, - nid: ast::NodeId) - -> Datum { - let v = match table.find(&nid) { + table: &HashMap, + nid: ast::NodeId) -> Datum { + let datum = match table.find(&nid) { Some(&v) => v, None => { bcx.sess().bug(format!( - "trans_local_var: no llval for local/arg {:?} found", nid)); + "trans_local_var: no datum for local/arg {:?} found", nid)); } }; - let ty = node_id_type(bcx, nid); debug!("take_local(nid={:?}, v={}, ty={})", - nid, bcx.val_to_str(v), bcx.ty_to_str(ty)); - Datum { - val: v, - ty: ty, - mode: ByRef(ZeroMem) - } + nid, bcx.val_to_str(datum.val), bcx.ty_to_str(datum.ty)); + datum } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 487aaa528eda2..304edb2c31243 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -489,16 +489,17 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @CrateContext, id, t.repr(tcx)); - let llfndecl = base::decl_internal_rust_fn(ccx, f.sig.inputs, f.sig.output, ps); + let llfndecl = base::decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, ps); base::set_llvm_fn_attrs(attrs, llfndecl); base::trans_fn(ccx, (*path).clone(), decl, body, llfndecl, - base::no_self, + None, None, id, + None, []); return llfndecl; } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index c93c0db8c3f72..16a761a44db31 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -23,13 +23,13 @@ use middle::trans::base::*; use middle::trans::callee; use middle::trans::closure; use middle::trans::common::*; +use middle::trans::datum::immediate_rvalue; use middle::trans::build::*; use middle::trans::expr; use middle::trans::machine::*; use middle::trans::reflect; use middle::trans::tvec; use middle::trans::type_of::type_of; -use middle::trans::uniq; use middle::ty; use util::ppaux; use util::ppaux::ty_to_short_str; @@ -86,139 +86,74 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) drop_ty(bcx, vp, t) } -pub fn free_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t) - -> &'a Block<'a> { - // NB: v is an *alias* of type t here, not a direct value. - let _icx = push_ctxt("free_ty"); - if ty::type_needs_drop(cx.tcx(), t) { - return call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue); - } - return cx; -} - -pub fn free_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) - -> &'a Block<'a> { - let _icx = push_ctxt("free_ty_immediate"); - match ty::get(t).sty { - ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) | - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_box) | - ty::ty_opaque_closure_ptr(_) => { - let vp = alloca(bcx, type_of(bcx.ccx(), t), ""); - Store(bcx, v, vp); - free_ty(bcx, vp, t) - } - _ => bcx.tcx().sess.bug("free_ty_immediate: non-box ty") - } -} - pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext, static_ti: @tydesc_info) { lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti); - lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti); } -pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { - if (field == abi::tydesc_field_take_glue || - field == abi::tydesc_field_drop_glue || - field == abi::tydesc_field_free_glue) && - ! ty::type_needs_drop(tcx, t) { - return ty::mk_u32(); +fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { + if (field == abi::tydesc_field_take_glue || field == abi::tydesc_field_drop_glue) + && !ty::type_needs_drop(tcx, t) { + return ty::mk_nil(); } if field == abi::tydesc_field_take_glue { match ty::get(t).sty { - ty::ty_unboxed_vec(..) | - ty::ty_uniq(..) | - ty::ty_estr(ty::vstore_uniq) | - ty::ty_evec(_, ty::vstore_uniq) => { return ty::mk_u32(); } - _ => () + ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) | + ty::ty_unboxed_vec(..) | ty::ty_uniq(..) => return ty::mk_nil(), + _ => {} } } - if field == abi::tydesc_field_take_glue && - ty::type_is_boxed(t) { - return ty::mk_imm_box(tcx, ty::mk_u32()); - } - - if field == abi::tydesc_field_free_glue { - match ty::get(t).sty { - ty::ty_bare_fn(..) | - ty::ty_closure(..) | - ty::ty_box(..) | - ty::ty_opaque_box | - ty::ty_uniq(..) | - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) | - ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) | - ty::ty_opaque_closure_ptr(..) => (), - _ => { return ty::mk_u32(); } - } + if field == abi::tydesc_field_take_glue && ty::type_is_boxed(t) { + return ty::mk_imm_box(tcx, ty::mk_nil()); } - if (field == abi::tydesc_field_free_glue || - field == abi::tydesc_field_drop_glue) { + if field == abi::tydesc_field_drop_glue { match ty::get(t).sty { - ty::ty_box(typ) - if ! ty::type_needs_drop(tcx, typ) => - return ty::mk_imm_box(tcx, ty::mk_u32()), + ty::ty_box(typ) + if !ty::type_needs_drop(tcx, typ) => + return ty::mk_imm_box(tcx, ty::mk_nil()), - ty::ty_evec(mt, ty::vstore_box) - if ! ty::type_needs_drop(tcx, mt.ty) => - return ty::mk_imm_box(tcx, ty::mk_u32()), + ty::ty_vec(mt, ty::vstore_box) + if !ty::type_needs_drop(tcx, mt.ty) => + return ty::mk_imm_box(tcx, ty::mk_nil()), - ty::ty_uniq(mt) | - ty::ty_evec(mt, ty::vstore_uniq) - if ! ty::type_needs_drop(tcx, mt.ty) => - return ty::mk_imm_uniq(tcx, ty::mk_u32()), + ty::ty_uniq(mt) | ty::ty_vec(mt, ty::vstore_uniq) + if !ty::type_needs_drop(tcx, mt.ty) => + return ty::mk_imm_uniq(tcx, ty::mk_nil()), - _ => () + _ => {} } } - return t; + t } -pub fn lazily_emit_simplified_tydesc_glue(ccx: @CrateContext, - field: uint, - ti: &tydesc_info) - -> bool { - let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue"); +fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) { + let _icx = push_ctxt("lazily_emit_tydesc_glue"); + let simpl = simplified_glue_type(ccx.tcx, field, ti.ty); if simpl != ti.ty { + let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue"); let simpl_ti = get_tydesc(ccx, simpl); lazily_emit_tydesc_glue(ccx, field, simpl_ti); - { - if field == abi::tydesc_field_take_glue { - ti.take_glue.set(simpl_ti.take_glue.get()); - } else if field == abi::tydesc_field_drop_glue { - ti.drop_glue.set(simpl_ti.drop_glue.get()); - } else if field == abi::tydesc_field_free_glue { - ti.free_glue.set(simpl_ti.free_glue.get()); - } else if field == abi::tydesc_field_visit_glue { - ti.visit_glue.set(simpl_ti.visit_glue.get()); - } - } - return true; - } - return false; -} - -pub fn lazily_emit_tydesc_glue(ccx: @CrateContext, - field: uint, - ti: @tydesc_info) { - let _icx = push_ctxt("lazily_emit_tydesc_glue"); - let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to()); + if field == abi::tydesc_field_take_glue { + ti.take_glue.set(simpl_ti.take_glue.get()); + } else if field == abi::tydesc_field_drop_glue { + ti.drop_glue.set(simpl_ti.drop_glue.get()); + } else if field == abi::tydesc_field_visit_glue { + ti.visit_glue.set(simpl_ti.visit_glue.get()); + } - if lazily_emit_simplified_tydesc_glue(ccx, field, ti) { return; } + let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to()); + if field == abi::tydesc_field_take_glue { match ti.take_glue.get() { Some(_) => (), @@ -245,19 +180,6 @@ pub fn lazily_emit_tydesc_glue(ccx: @CrateContext, ppaux::ty_to_str(ccx.tcx, ti.ty)); } } - } else if field == abi::tydesc_field_free_glue { - match ti.free_glue.get() { - Some(_) => (), - None => { - debug!("+++ lazily_emit_tydesc_glue FREE {}", - ppaux::ty_to_str(ccx.tcx, ti.ty)); - let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "free"); - ti.free_glue.set(Some(glue_fn)); - make_generic_glue(ccx, ti.ty, glue_fn, make_free_glue, "free"); - debug!("--- lazily_emit_tydesc_glue FREE {}", - ppaux::ty_to_str(ccx.tcx, ti.ty)); - } - } } else if field == abi::tydesc_field_visit_glue { match ti.visit_glue.get() { Some(_) => (), @@ -294,8 +216,6 @@ pub fn call_tydesc_glue_full(bcx: &Block, sti.take_glue.get() } else if field == abi::tydesc_field_drop_glue { sti.drop_glue.get() - } else if field == abi::tydesc_field_free_glue { - sti.free_glue.get() } else if field == abi::tydesc_field_visit_glue { sti.visit_glue.get() } else { @@ -334,20 +254,16 @@ pub fn call_tydesc_glue_full(bcx: &Block, } // See [Note-arg-mode] -pub fn call_tydesc_glue<'a>( - cx: &'a Block<'a>, - v: ValueRef, - t: ty::t, - field: uint) - -> &'a Block<'a> { +fn call_tydesc_glue<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t, field: uint) + -> &'a Block<'a> { let _icx = push_ctxt("call_tydesc_glue"); let ti = get_tydesc(cx.ccx(), t); call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti)); - return cx; + cx } -pub fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) - -> &'a Block<'a> { +fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("make_visit_glue"); with_scope(bcx, None, "visitor cleanup", |bcx| { let mut bcx = bcx; @@ -377,25 +293,25 @@ pub fn make_free_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) let bcx = drop_ty(bcx, body, body_ty); trans_free(bcx, v) } - ty::ty_opaque_box => { - let v = Load(bcx, v); - let td = Load(bcx, GEPi(bcx, v, [0u, abi::box_field_tydesc])); - let valptr = GEPi(bcx, v, [0u, abi::box_field_body]); - // Generate code that, dynamically, indexes into the - // tydesc and calls the drop glue that got set dynamically - call_tydesc_glue_full(bcx, valptr, td, abi::tydesc_field_drop_glue, - None); - trans_free(bcx, v) - } ty::ty_uniq(..) => { - uniq::make_free_glue(bcx, v, t) + let box_datum = immediate_rvalue(Load(bcx, v), t); + let not_null = IsNotNull(bcx, box_datum.val); + with_cond(bcx, not_null, |bcx| { + let body_datum = box_datum.box_body(bcx); + let bcx = drop_ty(bcx, body_datum.to_ref_llval(bcx), body_datum.ty); + if ty::type_contents(bcx.tcx(), t).owns_managed() { + trans_free(bcx, box_datum.val) + } else { + trans_exchange_free(bcx, box_datum.val) + } + }) } - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) | - ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { + ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => { make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t)) } ty::ty_closure(_) => { - closure::make_closure_glue(bcx, v, t, free_ty) + closure::make_closure_glue(bcx, v, t, make_free_glue) } ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_free_glue(bcx, ck, v) @@ -469,13 +385,13 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) let _icx = push_ctxt("make_drop_glue"); let ccx = bcx.ccx(); match ty::get(t).sty { - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { - decr_refcnt_maybe_free(bcx, Load(bcx, v0), Some(v0), t) + ty::ty_box(_) | + ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => { + decr_refcnt_maybe_free(bcx, v0, Some(t)) } ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { - free_ty(bcx, v0, t) + ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => { + make_free_glue(bcx, v0, t) } ty::ty_unboxed_vec(_) => { tvec::make_drop_glue_unboxed(bcx, v0, t) @@ -500,9 +416,7 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) } ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]); - let llbox = Load(bcx, llbox_ptr); - decr_refcnt_maybe_free(bcx, llbox, Some(llbox_ptr), - ty::mk_opaque_box(ccx.tcx)) + decr_refcnt_maybe_free(bcx, llbox_ptr, None) } ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => { let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]); @@ -517,7 +431,7 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) call_tydesc_glue_full(bcx, lluniquevalue, lltydesc, - abi::tydesc_field_free_glue, + abi::tydesc_field_drop_glue, None); bcx }) @@ -534,49 +448,50 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) } } -// box_ptr_ptr is optional, it is constructed if not supplied. -pub fn decr_refcnt_maybe_free<'a>( - bcx: &'a Block<'a>, - box_ptr: ValueRef, - box_ptr_ptr: Option, - t: ty::t) - -> &'a Block<'a> { +fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef, + t: Option) -> &'a Block<'a> { let _icx = push_ctxt("decr_refcnt_maybe_free"); let ccx = bcx.ccx(); let decr_bcx = sub_block(bcx, "decr"); let free_bcx = sub_block(decr_bcx, "free"); let next_bcx = sub_block(bcx, "next"); + let box_ptr = Load(bcx, box_ptr_ptr); let llnotnull = IsNotNull(bcx, box_ptr); CondBr(bcx, llnotnull, decr_bcx.llbb, next_bcx.llbb); let rc_ptr = GEPi(decr_bcx, box_ptr, [0u, abi::box_field_refcnt]); let rc = Sub(decr_bcx, Load(decr_bcx, rc_ptr), C_int(ccx, 1)); Store(decr_bcx, rc, rc_ptr); - let llisnull = IsNull(decr_bcx, rc); - CondBr(decr_bcx, llisnull, free_bcx.llbb, next_bcx.llbb); - - let free_bcx = match box_ptr_ptr { - Some(p) => free_ty(free_bcx, p, t), - None => free_ty_immediate(free_bcx, box_ptr, t) + CondBr(decr_bcx, IsNull(decr_bcx, rc), free_bcx.llbb, next_bcx.llbb); + + let free_bcx = match t { + Some(t) => make_free_glue(free_bcx, box_ptr_ptr, t), + None => { + let v = Load(free_bcx, box_ptr_ptr); + let td = Load(free_bcx, GEPi(free_bcx, v, [0u, abi::box_field_tydesc])); + let valptr = GEPi(free_bcx, v, [0u, abi::box_field_body]); + // Generate code that, dynamically, indexes into the + // tydesc and calls the drop glue that got set dynamically + call_tydesc_glue_full(free_bcx, valptr, td, abi::tydesc_field_drop_glue, None); + trans_free(free_bcx, v) + } }; Br(free_bcx, next_bcx.llbb); next_bcx } - -pub fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) - -> &'a Block<'a> { +fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) -> &'a Block<'a> { let _icx = push_ctxt("make_take_glue"); // NB: v is a *pointer* to type t here, not a direct value. match ty::get(t).sty { - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { + ty::ty_box(_) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => { incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx } - ty::ty_evec(_, ty::vstore_slice(_)) - | ty::ty_estr(ty::vstore_slice(_)) => { + ty::ty_vec(_, ty::vstore_slice(_)) + | ty::ty_str(ty::vstore_slice(_)) => { bcx } ty::ty_closure(_) => bcx, @@ -608,7 +523,7 @@ pub fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) } } -pub fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) { +fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) { let _icx = push_ctxt("incr_refcnt_of_boxed"); let ccx = cx.ccx(); let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]); @@ -654,7 +569,7 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { } }); - let ty_name = C_estr_slice(ccx, ppaux::ty_to_str(ccx.tcx, t).to_managed()); + let ty_name = C_str_slice(ccx, ppaux::ty_to_str(ccx.tcx, t).to_managed()); let inf = @tydesc_info { ty: t, @@ -665,18 +580,14 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { name: ty_name, take_glue: Cell::new(None), drop_glue: Cell::new(None), - free_glue: Cell::new(None), visit_glue: Cell::new(None), }; debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx, t)); return inf; } -pub type glue_helper<'a> = - 'a |&'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>; - -pub fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, - name: &str) -> ValueRef { +fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, + name: &str) -> ValueRef { let _icx = push_ctxt("declare_generic_glue"); let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed(); debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx, t)); @@ -685,12 +596,14 @@ pub fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, return llfn; } -pub fn make_generic_glue_inner(ccx: @CrateContext, - t: ty::t, - llfn: ValueRef, - helper: glue_helper) - -> ValueRef { - let _icx = push_ctxt("make_generic_glue_inner"); +pub type glue_helper<'a> = + 'a |&'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>; + +fn make_generic_glue(ccx: @CrateContext, t: ty::t, llfn: ValueRef, + helper: glue_helper, name: &str) -> ValueRef { + let _icx = push_ctxt("make_generic_glue"); + let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx, t)); + let _s = StatRecorder::new(ccx, glue_name); let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None); init_function(&fcx, false, ty::mk_nil(), None, None); @@ -706,25 +619,12 @@ pub fn make_generic_glue_inner(ccx: @CrateContext, // type, so we don't need to explicitly cast the function parameter. let bcx = fcx.entry_bcx.get().unwrap(); - let rawptr0_arg = fcx.arg_pos(0u); - let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; + let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, fcx.arg_pos(0) as c_uint) }; let bcx = helper(bcx, llrawptr0, t); finish_fn(&fcx, bcx); - return llfn; -} - -pub fn make_generic_glue(ccx: @CrateContext, - t: ty::t, - llfn: ValueRef, - helper: glue_helper, - name: &str) - -> ValueRef { - let _icx = push_ctxt("make_generic_glue"); - let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx, t)); - let _s = StatRecorder::new(ccx, glue_name); - make_generic_glue_inner(ccx, t, llfn, helper) + llfn } pub fn emit_tydescs(ccx: &CrateContext) { @@ -770,21 +670,6 @@ pub fn emit_tydescs(ccx: &CrateContext) { } } }; - let free_glue = - match ti.free_glue.get() { - None => { - ccx.stats.n_null_glues.set(ccx.stats.n_null_glues.get() + - 1u); - C_null(glue_fn_ty) - } - Some(v) => { - unsafe { - ccx.stats.n_real_glues.set(ccx.stats.n_real_glues.get() + - 1); - llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) - } - } - }; let visit_glue = match ti.visit_glue.get() { None => { @@ -808,7 +693,6 @@ pub fn emit_tydescs(ccx: &CrateContext) { ti.align, // align take_glue, // take_glue drop_glue, // drop_glue - free_glue, // free_glue visit_glue, // visit_glue ti.borrow_offset, // borrow_offset ti.name]); // name diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index f571d35bb28e8..7d0e5a435441b 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -11,8 +11,7 @@ use lib::llvm::{AvailableExternallyLinkage, SetLinkage}; use metadata::csearch; use middle::astencode; -use middle::trans::base::{push_ctxt, impl_self, no_self}; -use middle::trans::base::{trans_item, get_item_val, trans_fn}; +use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn}; use middle::trans::common::*; use middle::ty; use util::ppaux::ty_to_str; @@ -162,16 +161,13 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::DefId) let path = vec::append_one( ty::item_path(ccx.tcx, impl_did), PathName(mth.ident)); let self_kind = match mth.explicit_self.node { - ast::SelfStatic => no_self, + ast::SelfStatic => None, _ => { let self_ty = ty::node_id_to_type(ccx.tcx, mth.self_id); debug!("calling inline trans_fn with self_ty {}", ty_to_str(ccx.tcx, self_ty)); - match mth.explicit_self.node { - ast::SelfValue(_) => impl_self(self_ty, ty::ByRef), - _ => impl_self(self_ty, ty::ByCopy), - } + Some(self_ty) } }; trans_fn(ccx, @@ -182,6 +178,7 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::DefId) self_kind, None, mth.id, + Some(&*mth), []); } local_def(mth.id) diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index b001802f16507..126aa9e7be580 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -430,7 +430,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, // XXX This is a hack to grab the address of this particular // native function. There should be a general in-language // way to do this - let llfty = type_of_rust_fn(bcx.ccx(), [], ty::mk_nil()); + let llfty = type_of_rust_fn(bcx.ccx(), None, [], ty::mk_nil()); let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index f526fb528c5d8..2ab495226a8c1 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -76,7 +76,7 @@ pub fn trans_impl(ccx: @CrateContext, path, *method, None, - llfn); + |_| llfn); } else { let mut v = TransItemVisitor{ ccx: ccx }; visit::walk_method_helper(&mut v, *method, ()); @@ -91,7 +91,7 @@ pub fn trans_impl(ccx: @CrateContext, /// * `method`: the AST node for the method /// * `param_substs`: if this is a generic method, the current values for /// type parameters and so forth, else none -/// * `llfn`: the LLVM ValueRef for the method +/// * `llfn`: a closure returning the LLVM ValueRef for the method /// * `impl_id`: the node ID of the impl this method is inside /// /// XXX(pcwalton) Can we take `path` by reference? @@ -99,12 +99,10 @@ pub fn trans_method(ccx: @CrateContext, path: Path, method: &ast::Method, param_substs: Option<@param_substs>, - llfn: ValueRef) { + llfn_with_self: |Option| -> ValueRef) -> ValueRef { // figure out how self is being passed - let self_arg = match method.explicit_self.node { - ast::SelfStatic => { - no_self - } + let self_ty = match method.explicit_self.node { + ast::SelfStatic => None, _ => { // determine the (monomorphized) type that `self` maps to for // this method @@ -115,43 +113,25 @@ pub fn trans_method(ccx: @CrateContext, ty::subst_tps(ccx.tcx, *tys, *self_sub, self_ty) } }; - debug!("calling trans_fn with self_ty {}", - self_ty.repr(ccx.tcx)); - match method.explicit_self.node { - ast::SelfValue(_) => impl_self(self_ty, ty::ByRef), - _ => impl_self(self_ty, ty::ByCopy), - } + debug!("calling trans_fn with self_ty {}", self_ty.repr(ccx.tcx)); + Some(self_ty) } }; + let llfn = llfn_with_self(self_ty); + // generate the actual code trans_fn(ccx, path, method.decl, method.body, llfn, - self_arg, + self_ty, param_substs, method.id, + Some(method), []); -} - -pub fn trans_self_arg<'a>( - bcx: &'a Block<'a>, - base: &ast::Expr, - temp_cleanups: &mut ~[ValueRef], - mentry: typeck::method_map_entry) - -> Result<'a> { - let _icx = push_ctxt("impl::trans_self_arg"); - - // self is passed as an opaque box in the environment slot - let self_ty = ty::mk_opaque_box(bcx.tcx()); - trans_arg_expr(bcx, - self_ty, - mentry.self_mode, - base, - temp_cleanups, - DontAutorefArg) + llfn } pub fn trans_method_callee<'a>( @@ -169,16 +149,23 @@ pub fn trans_method_callee<'a>( match mentry.origin { typeck::method_static(did) => { - let callee_fn = callee::trans_fn_ref(bcx, did, callee_id); + let self_ty = monomorphize_type(bcx, mentry.self_ty); let mut temp_cleanups = ~[]; - let Result {bcx, val} = trans_self_arg(bcx, this, &mut temp_cleanups, mentry); + let Result {bcx, val} = trans_arg_expr(bcx, self_ty, this, + &mut temp_cleanups, + DontAutorefArg); + // HACK should not need the pointer cast, eventually trans_fn_ref + // should return a function type with the right type for self. + let callee_fn = callee::trans_fn_ref(bcx, did, callee_id); + let fn_ty = node_id_type(bcx, callee_id); + let llfn_ty = type_of_fn_from_ty(bcx.ccx(), Some(self_ty), fn_ty).ptr_to(); + let llfn_val = PointerCast(bcx, callee_fn.llfn, llfn_ty); Callee { bcx: bcx, data: Method(MethodData { - llfn: callee_fn.llfn, + llfn: llfn_val, llself: val, - temp_cleanup: temp_cleanups.head_opt().map(|v| *v), - self_mode: mentry.self_mode, + temp_cleanup: temp_cleanups.head_opt().map(|v| *v) }) } } @@ -194,8 +181,7 @@ pub fn trans_method_callee<'a>( bcx.tcx(), trait_id); - let vtbl = find_vtable(bcx.tcx(), substs, - p, b); + let vtbl = find_vtable(bcx.tcx(), substs, p, b); trans_monomorphized_callee(bcx, callee_id, this, mentry, trait_id, off, vtbl) } @@ -276,7 +262,7 @@ pub fn trans_static_method_callee(bcx: &Block, typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t))); - let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name); + let mth_id = method_with_name(ccx, impl_did, mname.name); let (callee_substs, callee_origins) = combine_impl_and_methods_tps( bcx, mth_id, callee_id, @@ -290,7 +276,7 @@ pub fn trans_static_method_callee(bcx: &Block, Some(callee_origins)); let callee_ty = node_id_type(bcx, callee_id); - let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to(); + let llty = type_of_fn_from_ty(ccx, None, callee_ty).ptr_to(); FnData {llfn: PointerCast(bcx, lval, llty)} } _ => { @@ -340,9 +326,11 @@ pub fn trans_monomorphized_callee<'a>( let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name); // obtain the `self` value: + let self_ty = monomorphize_type(bcx, mentry.self_ty); let mut temp_cleanups = ~[]; - let Result {bcx, val: llself_val} = - trans_self_arg(bcx, base, &mut temp_cleanups, mentry); + let Result {bcx, val} = trans_arg_expr(bcx, self_ty, base, + &mut temp_cleanups, + DontAutorefArg); // create a concatenated set of substitutions which includes // those from the impl and those from the method: @@ -359,8 +347,9 @@ pub fn trans_monomorphized_callee<'a>( Some(callee_origins)); // create a llvalue that represents the fn ptr + // HACK should not need the pointer cast (add self in trans_fn_ref_with_vtables). let fn_ty = node_id_type(bcx, callee_id); - let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).ptr_to(); + let llfn_ty = type_of_fn_from_ty(ccx, Some(self_ty), fn_ty).ptr_to(); let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty); // combine the self environment with the rest @@ -368,9 +357,8 @@ pub fn trans_monomorphized_callee<'a>( bcx: bcx, data: Method(MethodData { llfn: llfn_val, - llself: llself_val, - temp_cleanup: temp_cleanups.head_opt().map(|v| *v), - self_mode: mentry.self_mode, + llself: val, + temp_cleanup: temp_cleanups.head_opt().map(|v| *v) }) } } @@ -496,7 +484,7 @@ pub fn trans_trait_callee_from_llval<'a>( // Load the function from the vtable and cast it to the expected type. debug!("(translating trait callee) loading method"); - let llcallee_ty = type_of_fn_from_ty(ccx, callee_ty); + let llcallee_ty = type_of_fn_from_ty(ccx, None, callee_ty); let llvtable = Load(bcx, PointerCast(bcx, GEPi(bcx, llpair, @@ -510,12 +498,7 @@ pub fn trans_trait_callee_from_llval<'a>( data: Method(MethodData { llfn: mptr, llself: llself, - temp_cleanup: temp_cleanup, - - // We know that the func declaration is &self, ~self, - // or @self, and such functions are always by-copy - // (right now, at least). - self_mode: ty::ByCopy, + temp_cleanup: temp_cleanup }) }; } diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index f55360213c6f6..e534e087cb835 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -25,7 +25,6 @@ pub mod build; pub mod builder; pub mod base; pub mod _match; -pub mod uniq; pub mod closure; pub mod tvec; pub mod meth; diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 8365b54153251..c7bf618a619c0 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -13,9 +13,8 @@ use back::link::mangle_exported_name; use driver::session; use lib::llvm::ValueRef; use middle::trans::base::{set_llvm_fn_attrs, set_inline_hint}; -use middle::trans::base::{trans_enum_variant,push_ctxt}; +use middle::trans::base::{trans_enum_variant, push_ctxt, get_item_val}; use middle::trans::base::{trans_fn, decl_internal_rust_fn}; -use middle::trans::base::{get_item_val, no_self}; use middle::trans::base; use middle::trans::common::*; use middle::trans::meth; @@ -211,8 +210,8 @@ pub fn monomorphic_fn(ccx: @CrateContext, let s = mangle_exported_name(ccx, pt.clone(), mono_ty); debug!("monomorphize_fn mangled to {}", s); - let mk_lldecl = || { - let lldecl = decl_internal_rust_fn(ccx, f.sig.inputs, f.sig.output, s); + let mk_lldecl = |self_ty| { + let lldecl = decl_internal_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, s); let mut monomorphized = ccx.monomorphized.borrow_mut(); monomorphized.get().insert(hash_id, lldecl); lldecl @@ -223,16 +222,17 @@ pub fn monomorphic_fn(ccx: @CrateContext, node: ast::ItemFn(decl, _, _, _, body), .. }, _) => { - let d = mk_lldecl(); + let d = mk_lldecl(None); set_llvm_fn_attrs(i.attrs, d); trans_fn(ccx, pt, decl, body, d, - no_self, + None, Some(psubsts), fn_id.node, + None, []); d } @@ -240,7 +240,7 @@ pub fn monomorphic_fn(ccx: @CrateContext, ccx.tcx.sess.bug("Can't monomorphize this kind of item") } ast_map::NodeForeignItem(i, _, _, _) => { - let d = mk_lldecl(); + let d = mk_lldecl(None); intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs, ref_id); d @@ -248,7 +248,7 @@ pub fn monomorphic_fn(ccx: @CrateContext, ast_map::NodeVariant(v, enum_item, _) => { let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id)); let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); - let d = mk_lldecl(); + let d = mk_lldecl(None); set_inline_hint(d); match v.node.kind { ast::TupleVariantKind(ref args) => { @@ -266,20 +266,21 @@ pub fn monomorphic_fn(ccx: @CrateContext, d } ast_map::NodeMethod(mth, _, _) => { - // XXX: What should the self type be here? - let d = mk_lldecl(); - set_llvm_fn_attrs(mth.attrs, d); - meth::trans_method(ccx, pt, mth, Some(psubsts), d); - d + meth::trans_method(ccx, pt, mth, Some(psubsts), |self_ty| { + let d = mk_lldecl(self_ty); + set_llvm_fn_attrs(mth.attrs, d); + d + }) } ast_map::NodeTraitMethod(@ast::Provided(mth), _, pt) => { - let d = mk_lldecl(); - set_llvm_fn_attrs(mth.attrs, d); - meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), d); - d + meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), |self_ty| { + let d = mk_lldecl(self_ty); + set_llvm_fn_attrs(mth.attrs, d); + d + }) } ast_map::NodeStructCtor(struct_def, _, _) => { - let d = mk_lldecl(); + let d = mk_lldecl(None); set_inline_hint(d); base::trans_tuple_struct(ccx, struct_def.fields, diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 7810a99b2739e..ef9f48d478531 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -60,7 +60,7 @@ impl<'a> Reflector<'a> { // will kick us off fast isel. (Issue #4352.) let bcx = self.bcx; let str_vstore = ty::vstore_slice(ty::ReStatic); - let str_ty = ty::mk_estr(bcx.tcx(), str_vstore); + let str_ty = ty::mk_str(bcx.tcx(), str_vstore); let scratch = scratch_datum(bcx, str_ty, "", false); let len = C_uint(bcx.ccx(), s.len()); let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), Type::i8p()); @@ -176,11 +176,11 @@ impl<'a> Reflector<'a> { self.visit("vec", values) } - ty::ty_estr(vst) => { + ty::ty_str(vst) => { let (name, extra) = self.vstore_name_and_extra(t, vst); self.visit(~"estr_" + name, extra) } - ty::ty_evec(ref mt, vst) => { + ty::ty_vec(ref mt, vst) => { let (name, extra) = self.vstore_name_and_extra(t, vst); let extra = extra + self.c_mt(mt); if "uniq" == name && ty::type_contents(bcx.tcx(), t).owns_managed() { @@ -295,7 +295,7 @@ impl<'a> Reflector<'a> { sub_path, "get_disr"); - let llfdecl = decl_internal_rust_fn(ccx, [opaqueptrty], ty::mk_u64(), sym); + let llfdecl = decl_internal_rust_fn(ccx, None, [opaqueptrty], ty::mk_u64(), sym); let fcx = new_fn_ctxt(ccx, ~[], llfdecl, @@ -362,7 +362,6 @@ impl<'a> Reflector<'a> { } ty::ty_self(..) => self.leaf("self"), ty::ty_type => self.leaf("type"), - ty::ty_opaque_box => self.leaf("opaque_box"), ty::ty_opaque_closure_ptr(ck) => { let ckval = ast_sigil_constant(ck); let extra = ~[self.c_uint(ckval)]; diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index da7f3068fb95e..e8d4381e9f799 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -40,10 +40,10 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { let unit_ty = ty::sequence_element_type(tcx, t); let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty); match ty::get(t).sty { - ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => { + ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) => { ty::mk_imm_uniq(tcx, unboxed_vec_ty) } - ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { + ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => { ty::mk_imm_box(tcx, unboxed_vec_ty) } _ => tcx.sess.bug("non boxed-vec type \ @@ -239,9 +239,9 @@ pub fn trans_slice_vstore<'a>( let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); // Arrange for the backing array to be cleaned up. - let fixed_ty = ty::mk_evec(bcx.tcx(), - ty::mt {ty: vt.unit_ty, mutbl: ast::MutMutable}, - ty::vstore_fixed(count)); + let fixed_ty = ty::mk_vec(bcx.tcx(), + ty::mt {ty: vt.unit_ty, mutbl: ast::MutMutable}, + ty::vstore_fixed(count)); let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); add_clean(bcx, llfixed_casted, fixed_ty); @@ -323,7 +323,7 @@ pub fn trans_uniq_or_managed_vstore<'a>( let llptrval = C_cstr(bcx.ccx(), s); let llptrval = PointerCast(bcx, llptrval, Type::i8p()); let llsizeval = C_uint(bcx.ccx(), s.len()); - let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq); + let typ = ty::mk_str(bcx.tcx(), ty::vstore_uniq); let lldestval = scratch_datum(bcx, typ, "", false); let alloc_fn = langcall(bcx, Some(span), "", StrDupUniqFnLangItem); @@ -449,7 +449,7 @@ pub fn write_content<'a>( } _ => { bcx.tcx().sess.span_bug(content_expr.span, - "Unexpected evec content"); + "Unexpected vec content"); } } } @@ -485,7 +485,7 @@ pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint { ty::eval_repeat_count(&bcx.tcx(), count_expr) } _ => bcx.tcx().sess.span_bug(content_expr.span, - "Unexpected evec content") + "Unexpected vec content") } } @@ -503,7 +503,7 @@ pub fn get_base_and_byte_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t) let vt = vec_types(bcx, vec_ty); let vstore = match ty::get(vt.vec_ty).sty { - ty::ty_estr(vst) | ty::ty_evec(_, vst) => vst, + ty::ty_str(vst) | ty::ty_vec(_, vst) => vst, _ => ty::vstore_uniq }; @@ -540,7 +540,7 @@ pub fn get_base_and_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t) let vt = vec_types(bcx, vec_ty); let vstore = match ty::get(vt.vec_ty).sty { - ty::ty_estr(vst) | ty::ty_evec(_, vst) => vst, + ty::ty_str(vst) | ty::ty_vec(_, vst) => vst, _ => ty::vstore_uniq }; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index e2338c1ad8110..d4ba4a76f8129 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -219,7 +219,6 @@ impl Type { int_ty, // align glue_fn_ty, // take glue_fn_ty, // drop - glue_fn_ty, // free glue_fn_ty, // visit int_ty, // borrow_offset Type::struct_([Type::i8p(), Type::int(arch)], false)]; // name diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index f6fb509e317fe..f59c2acd0274c 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -44,6 +44,7 @@ pub fn type_of_explicit_args(ccx: &CrateContext, } pub fn type_of_rust_fn(cx: &CrateContext, + self_ty: Option, inputs: &[ty::t], output: ty::t) -> Type { let mut atys: ~[Type] = ~[]; @@ -57,7 +58,11 @@ pub fn type_of_rust_fn(cx: &CrateContext, } // Arg 1: Environment - atys.push(Type::opaque_box(cx).ptr_to()); + let env = match self_ty { + Some(t) => type_of_explicit_arg(cx, t), + None => Type::opaque_box(cx).ptr_to() + }; + atys.push(env); // ... then explicit args. atys.push_all(type_of_explicit_args(cx, inputs)); @@ -71,14 +76,14 @@ pub fn type_of_rust_fn(cx: &CrateContext, } // Given a function type and a count of ty params, construct an llvm type -pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type { +pub fn type_of_fn_from_ty(cx: &CrateContext, self_ty: Option, fty: ty::t) -> Type { return match ty::get(fty).sty { ty::ty_closure(ref f) => { - type_of_rust_fn(cx, f.sig.inputs, f.sig.output) + type_of_rust_fn(cx, None, f.sig.inputs, f.sig.output) } ty::ty_bare_fn(ref f) => { if f.abis.is_rust() || f.abis.is_intrinsic() { - type_of_rust_fn(cx, f.sig.inputs, f.sig.output) + type_of_rust_fn(cx, self_ty, f.sig.inputs, f.sig.output) } else { foreign::lltype_for_foreign_fn(cx, fty) } @@ -117,20 +122,19 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_uint(t) => Type::uint_from_ty(cx, t), ty::ty_float(t) => Type::float_from_ty(t), - ty::ty_estr(ty::vstore_uniq) | - ty::ty_estr(ty::vstore_box) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_evec(_, ty::vstore_box) | + ty::ty_str(ty::vstore_uniq) | + ty::ty_str(ty::vstore_box) | + ty::ty_vec(_, ty::vstore_uniq) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_box(..) | - ty::ty_opaque_box | ty::ty_uniq(..) | ty::ty_ptr(..) | ty::ty_rptr(..) | ty::ty_type | ty::ty_opaque_closure_ptr(..) => Type::i8p(), - ty::ty_estr(ty::vstore_slice(..)) | - ty::ty_evec(_, ty::vstore_slice(..)) => { + ty::ty_str(ty::vstore_slice(..)) | + ty::ty_vec(_, ty::vstore_slice(..)) => { Type::struct_([Type::i8p(), Type::i8p()], false) } @@ -138,8 +142,8 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_closure(..) => Type::struct_([Type::i8p(), Type::i8p()], false), ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store), - ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), - ty::ty_evec(mt, ty::vstore_fixed(size)) => { + ty::ty_str(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), + ty::ty_vec(mt, ty::vstore_fixed(size)) => { Type::array(&sizing_type_of(cx, mt.ty), size as u64) } @@ -214,7 +218,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_int(t) => Type::int_from_ty(cx, t), ty::ty_uint(t) => Type::uint_from_ty(cx, t), ty::ty_float(t) => Type::float_from_ty(t), - ty::ty_estr(ty::vstore_uniq) => { + ty::ty_str(ty::vstore_uniq) => { Type::vec(cx.sess.targ_cfg.arch, &Type::i8()).ptr_to() } ty::ty_enum(did, ref substs) => { @@ -226,12 +230,12 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { let name = llvm_type_name(cx, an_enum, did, substs.tps); adt::incomplete_type_of(cx, repr, name) } - ty::ty_estr(ty::vstore_box) => { + ty::ty_str(ty::vstore_box) => { Type::smart_ptr(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() } - ty::ty_evec(ref mt, ty::vstore_box) => { + ty::ty_vec(ref mt, ty::vstore_box) => { let e_ty = type_of(cx, mt.ty); let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty); Type::smart_ptr(cx, &v_ty).ptr_to() @@ -240,7 +244,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { let ty = type_of(cx, typ); Type::smart_ptr(cx, &ty).ptr_to() } - ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); if ty::type_contents(cx.tcx, mt.ty).owns_managed() { @@ -249,7 +252,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { ty.ptr_to() } } - ty::ty_evec(ref mt, ty::vstore_uniq) => { + ty::ty_vec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); let ty = Type::vec(cx.sess.targ_cfg.arch, &ty); if ty::type_contents(cx.tcx, mt.ty).owns_managed() { @@ -265,30 +268,30 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(), ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(), - ty::ty_evec(ref mt, ty::vstore_slice(_)) => { + ty::ty_vec(ref mt, ty::vstore_slice(_)) => { let p_ty = type_of(cx, mt.ty).ptr_to(); let u_ty = Type::uint_from_ty(cx, ast::TyU); Type::struct_([p_ty, u_ty], false) } - ty::ty_estr(ty::vstore_slice(_)) => { + ty::ty_str(ty::vstore_slice(_)) => { // This means we get a nicer name in the output cx.tn.find_type("str_slice").unwrap() } - ty::ty_estr(ty::vstore_fixed(n)) => { + ty::ty_str(ty::vstore_fixed(n)) => { Type::array(&Type::i8(), (n + 1u) as u64) } - ty::ty_evec(ref mt, ty::vstore_fixed(n)) => { + ty::ty_vec(ref mt, ty::vstore_fixed(n)) => { Type::array(&type_of(cx, mt.ty), n as u64) } ty::ty_bare_fn(_) => { - type_of_fn_from_ty(cx, t).ptr_to() + type_of_fn_from_ty(cx, None, t).ptr_to() } ty::ty_closure(_) => { - let ty = type_of_fn_from_ty(cx, t); + let ty = type_of_fn_from_ty(cx, None, t); Type::func_pair(cx, &ty) } ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store), diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs deleted file mode 100644 index 91ac5f9f3b4d3..0000000000000 --- a/src/librustc/middle/trans/uniq.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -use lib::llvm::ValueRef; -use middle::trans::base::*; -use middle::trans::build::*; -use middle::trans::common::*; -use middle::trans::datum::immediate_rvalue; -use middle::trans::glue; -use middle::ty; - -pub fn make_free_glue<'a>( - bcx: &'a Block<'a>, - vptrptr: ValueRef, - box_ty: ty::t) - -> &'a Block<'a> { - let _icx = push_ctxt("uniq::make_free_glue"); - let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); - - let not_null = IsNotNull(bcx, box_datum.val); - with_cond(bcx, not_null, |bcx| { - let body_datum = box_datum.box_body(bcx); - let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx), - body_datum.ty); - if ty::type_contents(bcx.tcx(), box_ty).owns_managed() { - glue::trans_free(bcx, box_datum.val) - } else { - glue::trans_exchange_free(bcx, box_datum.val) - } - }) -} diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 05b59baa49c9c..46dc1bb68b3a0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -151,14 +151,6 @@ pub enum TraitStore { RegionTraitStore(Region), // &Trait } -// XXX: This should probably go away at some point. Maybe after destructors -// do? -#[deriving(Clone, Eq, Encodable, Decodable)] -pub enum SelfMode { - ByCopy, - ByRef, -} - pub struct field_ty { name: Name, id: DefId, @@ -635,11 +627,11 @@ pub enum sty { ty_int(ast::IntTy), ty_uint(ast::UintTy), ty_float(ast::FloatTy), - ty_estr(vstore), + ty_str(vstore), ty_enum(DefId, substs), ty_box(t), ty_uniq(mt), - ty_evec(mt, vstore), + ty_vec(mt, vstore), ty_ptr(mt), ty_rptr(Region, mt), ty_bare_fn(BareFnTy), @@ -659,8 +651,7 @@ pub enum sty { // "Fake" types, used for trans purposes ty_type, // type_desc* - ty_opaque_box, // used by monomorphizer to represent any @ box - ty_opaque_closure_ptr(Sigil), // ptr to env for ||, @fn, ~fn + ty_opaque_closure_ptr(Sigil), // ptr to env for || and proc ty_unboxed_vec(mt), } @@ -1070,16 +1061,15 @@ pub fn mk_t(cx: ctxt, st: sty) -> t { return f; } match &st { - &ty_estr(vstore_slice(r)) => { + &ty_str(vstore_slice(r)) => { flags |= rflags(r); } - &ty_evec(ref mt, vstore_slice(r)) => { + &ty_vec(ref mt, vstore_slice(r)) => { flags |= rflags(r); flags |= get(mt.ty).flags; } &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) | - &ty_estr(_) | &ty_type | &ty_opaque_closure_ptr(_) | - &ty_opaque_box => (), + &ty_str(_) | &ty_type | &ty_opaque_closure_ptr(_) => {} // You might think that we could just return ty_err for // any type containing ty_err as a component, and get // rid of the has_ty_err flag -- likewise for ty_bot (with @@ -1103,7 +1093,7 @@ pub fn mk_t(cx: ctxt, st: sty) -> t { } } &ty_box(ref tt) => flags |= get(*tt).flags, - &ty_uniq(ref m) | &ty_evec(ref m, _) | &ty_ptr(ref m) | + &ty_uniq(ref m) | &ty_vec(ref m, _) | &ty_ptr(ref m) | &ty_unboxed_vec(ref m) => { flags |= get(m.ty).flags; } @@ -1234,8 +1224,8 @@ pub fn mk_mach_float(tm: ast::FloatTy) -> t { #[inline] pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) } -pub fn mk_estr(cx: ctxt, t: vstore) -> t { - mk_t(cx, ty_estr(t)) +pub fn mk_str(cx: ctxt, t: vstore) -> t { + mk_t(cx, ty_str(t)) } pub fn mk_enum(cx: ctxt, did: ast::DefId, substs: substs) -> t { @@ -1278,8 +1268,8 @@ pub fn mk_nil_ptr(cx: ctxt) -> t { mk_ptr(cx, mt {ty: mk_nil(), mutbl: ast::MutImmutable}) } -pub fn mk_evec(cx: ctxt, tm: mt, t: vstore) -> t { - mk_t(cx, ty_evec(tm, t)) +pub fn mk_vec(cx: ctxt, tm: mt, t: vstore) -> t { + mk_t(cx, ty_vec(tm, t)) } pub fn mk_unboxed_vec(cx: ctxt, tm: mt) -> t { @@ -1354,8 +1344,6 @@ pub fn mk_opaque_closure_ptr(cx: ctxt, sigil: ast::Sigil) -> t { mk_t(cx, ty_opaque_closure_ptr(sigil)) } -pub fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) } - pub fn walk_ty(ty: t, f: |t|) { maybe_walk_ty(ty, |t| { f(t); true }); } @@ -1366,13 +1354,10 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) { } match get(ty).sty { ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | - ty_estr(_) | ty_type | ty_opaque_box | ty_self(_) | - ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => { - } - ty_box(ref ty) => { - maybe_walk_ty(*ty, f); - } - ty_evec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) | + ty_str(_) | ty_type | ty_self(_) | + ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {} + ty_box(ref ty) => maybe_walk_ty(*ty, f), + ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_uniq(ref tm) => { maybe_walk_ty(tm.ty, f); } @@ -1520,8 +1505,8 @@ pub fn type_is_self(ty: t) -> bool { pub fn type_is_structural(ty: t) -> bool { match get(ty).sty { ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) | - ty_evec(_, vstore_fixed(_)) | ty_estr(vstore_fixed(_)) | - ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) + ty_vec(_, vstore_fixed(_)) | ty_str(vstore_fixed(_)) | + ty_vec(_, vstore_slice(_)) | ty_str(vstore_slice(_)) => true, _ => false } @@ -1529,7 +1514,7 @@ pub fn type_is_structural(ty: t) -> bool { pub fn type_is_sequence(ty: t) -> bool { match get(ty).sty { - ty_estr(_) | ty_evec(_, _) => true, + ty_str(_) | ty_vec(_, _) => true, _ => false } } @@ -1543,15 +1528,15 @@ pub fn type_is_simd(cx: ctxt, ty: t) -> bool { pub fn type_is_str(ty: t) -> bool { match get(ty).sty { - ty_estr(_) => true, + ty_str(_) => true, _ => false } } pub fn sequence_element_type(cx: ctxt, ty: t) -> t { match get(ty).sty { - ty_estr(_) => return mk_mach_uint(ast::TyU8), - ty_evec(mt, _) | ty_unboxed_vec(mt) => return mt.ty, + ty_str(_) => return mk_mach_uint(ast::TyU8), + ty_vec(mt, _) | ty_unboxed_vec(mt) => return mt.ty, _ => cx.sess.bug("sequence_element_type called on non-sequence value"), } } @@ -1592,8 +1577,7 @@ pub fn type_is_box(ty: t) -> bool { pub fn type_is_boxed(ty: t) -> bool { match get(ty).sty { - ty_box(_) | ty_opaque_box | - ty_evec(_, vstore_box) | ty_estr(vstore_box) => true, + ty_box(_) | ty_vec(_, vstore_box) | ty_str(vstore_box) => true, _ => false } } @@ -1607,7 +1591,7 @@ pub fn type_is_region_ptr(ty: t) -> bool { pub fn type_is_slice(ty: t) -> bool { match get(ty).sty { - ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) => true, + ty_vec(_, vstore_slice(_)) | ty_str(vstore_slice(_)) => true, _ => return false } } @@ -1628,8 +1612,8 @@ pub fn type_is_unsafe_ptr(ty: t) -> bool { pub fn type_is_vec(ty: t) -> bool { return match get(ty).sty { - ty_evec(_, _) | ty_unboxed_vec(_) => true, - ty_estr(_) => true, + ty_vec(_, _) | ty_unboxed_vec(_) => true, + ty_str(_) => true, _ => false }; } @@ -1637,8 +1621,8 @@ pub fn type_is_vec(ty: t) -> bool { pub fn type_is_unique(ty: t) -> bool { match get(ty).sty { ty_uniq(_) | - ty_evec(_, vstore_uniq) | - ty_estr(vstore_uniq) | + ty_vec(_, vstore_uniq) | + ty_str(vstore_uniq) | ty_opaque_closure_ptr(ast::OwnedSigil) => true, _ => return false } @@ -1699,7 +1683,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, maybe_walk_ty(ty, |ty| { let old_encountered_box = encountered_box; let result = match get(ty).sty { - ty_box(_) | ty_opaque_box => { + ty_box(_) => { encountered_box = true; true } @@ -1719,10 +1703,10 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, !needs_unwind_cleanup } ty_uniq(_) | - ty_estr(vstore_uniq) | - ty_estr(vstore_box) | - ty_evec(_, vstore_uniq) | - ty_evec(_, vstore_box) + ty_str(vstore_uniq) | + ty_str(vstore_box) | + ty_vec(_, vstore_uniq) | + ty_vec(_, vstore_box) => { // Once we're inside a box, the annihilator will find // it and destroy it. @@ -2031,7 +2015,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { TC::None } - ty_estr(vstore_uniq) => { + ty_str(vstore_uniq) => { TC::OwnsOwned } @@ -2060,32 +2044,32 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { tc_mt(cx, mt, cache).owned_pointer() } - ty_evec(mt, vstore_uniq) => { + ty_vec(mt, vstore_uniq) => { tc_mt(cx, mt, cache).owned_pointer() } - ty_evec(mt, vstore_box) => { + ty_vec(mt, vstore_box) => { tc_mt(cx, mt, cache).managed_pointer() } - ty_evec(ref mt, vstore_slice(r)) => { + ty_vec(ref mt, vstore_slice(r)) => { tc_ty(cx, mt.ty, cache).reference( borrowed_contents(r, mt.mutbl)) } - ty_evec(mt, vstore_fixed(_)) => { + ty_vec(mt, vstore_fixed(_)) => { tc_mt(cx, mt, cache) } - ty_estr(vstore_box) => { + ty_str(vstore_box) => { TC::Managed } - ty_estr(vstore_slice(r)) => { + ty_str(vstore_slice(r)) => { borrowed_contents(r, ast::MutImmutable) } - ty_estr(vstore_fixed(_)) => { + ty_str(vstore_fixed(_)) => { TC::None } @@ -2145,8 +2129,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { // times. TC::All } - - ty_opaque_box => TC::Managed, ty_unboxed_vec(mt) => TC::InteriorUnsized | tc_mt(cx, mt, cache), ty_opaque_closure_ptr(sigil) => { match sigil { @@ -2324,7 +2306,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_int(_) | ty_uint(_) | ty_float(_) | - ty_estr(_) | + ty_str(_) | ty_bare_fn(_) | ty_closure(_) | ty_infer(_) | @@ -2332,9 +2314,8 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_param(_) | ty_self(_) | ty_type | - ty_opaque_box | ty_opaque_closure_ptr(_) | - ty_evec(_, _) | + ty_vec(_, _) | ty_unboxed_vec(_) => { false } @@ -2431,7 +2412,7 @@ pub fn type_structurally_contains(cx: ctxt, ty: t, test: |x: &sty| -> bool) } return false; } - ty_evec(ref mt, vstore_fixed(_)) => { + ty_vec(ref mt, vstore_fixed(_)) => { return type_structurally_contains(cx, mt.ty, test); } _ => return false @@ -2442,8 +2423,8 @@ pub fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool { return type_structurally_contains(cx, ty, |sty| { match *sty { ty_uniq(_) | - ty_evec(_, vstore_uniq) | - ty_estr(vstore_uniq) => true, + ty_vec(_, vstore_uniq) | + ty_str(vstore_uniq) => true, _ => false, } }); @@ -2513,9 +2494,9 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { ty_type | ty_ptr(_) | ty_bare_fn(_) => result = true, // Boxed types 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_str(vstore_uniq) | ty_str(vstore_box) | + ty_vec(_, vstore_uniq) | ty_vec(_, vstore_box) | + ty_trait(_, _, _, _, _) | ty_rptr(_,_) => result = false, // Structural types ty_enum(did, ref substs) => { let variants = enum_variants(cx, did); @@ -2532,8 +2513,8 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { ty_tup(ref elts) => { for elt in elts.iter() { if !type_is_pod(cx, *elt) { result = false; } } } - ty_estr(vstore_fixed(_)) => result = true, - ty_evec(ref mt, vstore_fixed(_)) | ty_unboxed_vec(ref mt) => { + ty_str(vstore_fixed(_)) => result = true, + ty_vec(ref mt, vstore_fixed(_)) | ty_unboxed_vec(ref mt) => { result = type_is_pod(cx, mt.ty); } ty_param(_) => result = false, @@ -2547,7 +2528,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { }); } - ty_estr(vstore_slice(..)) | ty_evec(_, vstore_slice(..)) => { + ty_str(vstore_slice(..)) | ty_vec(_, vstore_slice(..)) => { result = false; } @@ -2652,8 +2633,8 @@ pub fn index(t: t) -> Option { pub fn index_sty(sty: &sty) -> Option { match *sty { - ty_evec(mt, _) => Some(mt), - ty_estr(_) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}), + ty_vec(mt, _) => Some(mt), + ty_str(_) => Some(mt {ty: mk_u8(), mutbl: ast::MutImmutable}), _ => None } } @@ -2765,8 +2746,8 @@ pub fn is_fn_ty(fty: t) -> bool { pub fn ty_vstore(ty: t) -> vstore { match get(ty).sty { - ty_evec(_, vstore) => vstore, - ty_estr(vstore) => vstore, + ty_vec(_, vstore) => vstore, + ty_str(vstore) => vstore, ref s => fail!("ty_vstore() called on invalid sty: {:?}", s) } } @@ -2776,8 +2757,8 @@ pub fn ty_region(tcx: ctxt, ty: t) -> Region { match get(ty).sty { ty_rptr(r, _) => r, - ty_evec(_, vstore_slice(r)) => r, - ty_estr(vstore_slice(r)) => r, + ty_vec(_, vstore_slice(r)) => r, + ty_str(vstore_slice(r)) => r, ref s => { tcx.sess.span_bug( span, @@ -2962,12 +2943,12 @@ pub fn adjust_ty(cx: ctxt, r: Region, m: ast::Mutability, ty: ty::t) -> ty::t { match get(ty).sty { - ty_evec(mt, _) => { - ty::mk_evec(cx, mt {ty: mt.ty, mutbl: m}, vstore_slice(r)) + ty_vec(mt, _) => { + ty::mk_vec(cx, mt {ty: mt.ty, mutbl: m}, vstore_slice(r)) } - ty_estr(_) => { - ty::mk_estr(cx, vstore_slice(r)) + ty_str(_) => { + ty::mk_str(cx, vstore_slice(r)) } ref s => { @@ -3344,15 +3325,15 @@ pub fn occurs_check(tcx: ctxt, sp: Span, vid: TyVid, rt: t) { pub fn ty_sort_str(cx: ctxt, t: t) -> ~str { match get(t).sty { ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | - ty_uint(_) | ty_float(_) | ty_estr(_) | - ty_type | ty_opaque_box | ty_opaque_closure_ptr(_) => { + ty_uint(_) | ty_float(_) | ty_str(_) | + ty_type | ty_opaque_closure_ptr(_) => { ::util::ppaux::ty_to_str(cx, t) } ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)), ty_box(_) => ~"@-ptr", ty_uniq(_) => ~"~-ptr", - ty_evec(_, _) => ~"vector", + ty_vec(_, _) => ~"vector", ty_unboxed_vec(_) => ~"unboxed vector", ty_ptr(_) => ~"*-ptr", ty_rptr(_, _) => ~"&-ptr", @@ -4814,7 +4795,7 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 { hash.input([6]); iter(&mut hash, &f); } - ty_estr(v) => { + ty_str(v) => { hash.input([7]); vstore(&mut hash, v); } @@ -4829,7 +4810,7 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 { hash.input([10]); mt(&mut hash, m); } - ty_evec(m, v) => { + ty_vec(m, v) => { hash.input([11]); mt(&mut hash, m); vstore(&mut hash, v); @@ -4890,13 +4871,12 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 { ty_infer(_) => unreachable!(), ty_err => hash.input([23]), ty_type => hash.input([24]), - ty_opaque_box => hash.input([25]), ty_opaque_closure_ptr(s) => { - hash.input([26]); + hash.input([25]); iter(&mut hash, &s); } ty_unboxed_vec(m) => { - hash.input([27]); + hash.input([26]); mt(&mut hash, m); } } diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 06a3152056fb1..bd1f091b9d6aa 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -152,9 +152,8 @@ pub fn super_fold_sty(this: &mut T, ty::ty_unboxed_vec(ref tm) => { ty::ty_unboxed_vec(this.fold_mt(tm)) } - ty::ty_evec(ref tm, vst) => { - ty::ty_evec(this.fold_mt(tm), - this.fold_vstore(vst)) + ty::ty_vec(ref tm, vst) => { + ty::ty_vec(this.fold_mt(tm), this.fold_vstore(vst)) } ty::ty_enum(tid, ref substs) => { ty::ty_enum(tid, this.fold_substs(substs)) @@ -184,14 +183,14 @@ pub fn super_fold_sty(this: &mut T, ty::ty_struct(did, this.fold_substs(substs)) } - ty::ty_estr(vst) => { - ty::ty_estr(this.fold_vstore(vst)) + ty::ty_str(vst) => { + ty::ty_str(this.fold_vstore(vst)) } ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | ty::ty_type | ty::ty_opaque_closure_ptr(_) | - ty::ty_err | ty::ty_opaque_box | ty::ty_infer(_) | + ty::ty_err | ty::ty_infer(_) | ty::ty_param(..) | ty::ty_self(_) => { (*sty).clone() } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 882fb46e77258..74e4c96929250 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -293,8 +293,8 @@ pub fn ast_ty_to_ty( ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl} } - // Handle @, ~, and & being able to mean estrs and evecs. - // If a_seq_ty is a str or a vec, make it an estr/evec. + // Handle @, ~, and & being able to mean strs and vecs. + // If a_seq_ty is a str or a vec, make it an str/vec. // Also handle first-class trait types. fn mk_pointer( @@ -314,7 +314,7 @@ pub fn ast_ty_to_ty( mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl }; } debug!("&[]: vst={:?}", vst); - return ty::mk_evec(tcx, mt, vst); + return ty::mk_vec(tcx, mt, vst); } ast::TyPath(ref path, ref bounds, id) => { // Note that the "bounds must be empty if path is not a trait" @@ -324,7 +324,7 @@ pub fn ast_ty_to_ty( match def_map.get().find(&id) { Some(&ast::DefPrimTy(ast::TyStr)) if a_seq_ty.mutbl == ast::MutImmutable => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); - return ty::mk_estr(tcx, vst); + return ty::mk_str(tcx, vst); } Some(&ast::DefTrait(trait_def_id)) => { let result = ast_path_to_trait_ref( @@ -415,7 +415,7 @@ pub fn ast_ty_to_ty( ast::TyVec(ty) => { tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type"); // return /something/ so they can at least get more errors - ty::mk_evec(tcx, ast_ty_to_mt(this, rscope, ty), ty::vstore_uniq) + ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), ty::vstore_uniq) } ast::TyPtr(ref mt) => { ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt)) @@ -519,7 +519,7 @@ pub fn ast_ty_to_ty( tcx.sess.span_err(ast_ty.span, "bare `str` is not a type"); // return /something/ so they can at least get more errors - ty::mk_estr(tcx, ty::vstore_uniq) + ty::mk_str(tcx, ty::vstore_uniq) } } } @@ -552,11 +552,11 @@ pub fn ast_ty_to_ty( Ok(ref r) => { match *r { const_eval::const_int(i) => - ty::mk_evec(tcx, ast_ty_to_mt(this, rscope, ty), - ty::vstore_fixed(i as uint)), + ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), + ty::vstore_fixed(i as uint)), const_eval::const_uint(i) => - ty::mk_evec(tcx, ast_ty_to_mt(this, rscope, ty), - ty::vstore_fixed(i as uint)), + ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), + ty::vstore_fixed(i as uint)), _ => { tcx.sess.span_fatal( ast_ty.span, "expected constant expr for vector length"); diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 8e0f2585d8011..efd632dc80ac1 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -602,7 +602,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { let (elt_type, region_var) = match *structure_of(fcx, pat.span, expected) { - ty::ty_evec(mt, vstore) => { + ty::ty_vec(mt, vstore) => { let region_var = match vstore { ty::vstore_slice(r) => r, ty::vstore_box | ty::vstore_uniq | ty::vstore_fixed(_) => { @@ -643,7 +643,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { } match slice { Some(slice_pat) => { - let slice_ty = ty::mk_evec(tcx, + let slice_ty = ty::mk_vec(tcx, ty::mt {ty: elt_type.ty, mutbl: elt_type.mutbl}, ty::vstore_slice(region_var) ); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 4a9f7ea36240f..00f8eb6daebb3 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -648,11 +648,11 @@ impl<'a> LookupContext<'a> { autoderefs: autoderefs+1, autoref: Some(ty::AutoPtr(region, self_mt.mutbl))})) } - ty::ty_evec(self_mt, vstore_slice(_)) => { + ty::ty_vec(self_mt, vstore_slice(_)) => { let region = self.infcx().next_region_var( infer::Autoref(self.expr.span)); - (ty::mk_evec(tcx, self_mt, vstore_slice(region)), + (ty::mk_vec(tcx, self_mt, vstore_slice(region)), ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: autoderefs, autoref: Some(ty::AutoBorrowVec(region, self_mt.mutbl))})) @@ -699,16 +699,16 @@ impl<'a> LookupContext<'a> { let tcx = self.tcx(); let sty = ty::get(self_ty).sty.clone(); match sty { - ty_evec(mt, vstore_box) | - ty_evec(mt, vstore_uniq) | - ty_evec(mt, vstore_slice(_)) | // NDM(#3148) - ty_evec(mt, vstore_fixed(_)) => { + ty_vec(mt, vstore_box) | + ty_vec(mt, vstore_uniq) | + ty_vec(mt, vstore_slice(_)) | // NDM(#3148) + ty_vec(mt, vstore_fixed(_)) => { // First try to borrow to a slice let entry = self.search_for_some_kind_of_autorefd_method( AutoBorrowVec, autoderefs, [MutImmutable, MutMutable], - |m,r| ty::mk_evec(tcx, - ty::mt {ty:mt.ty, mutbl:m}, - vstore_slice(r))); + |m,r| ty::mk_vec(tcx, + ty::mt {ty:mt.ty, mutbl:m}, + vstore_slice(r))); if entry.is_some() { return entry; } @@ -716,9 +716,9 @@ impl<'a> LookupContext<'a> { self.search_for_some_kind_of_autorefd_method( AutoBorrowVecRef, autoderefs, [MutImmutable, MutMutable], |m,r| { - let slice_ty = ty::mk_evec(tcx, - ty::mt {ty:mt.ty, mutbl:m}, - vstore_slice(r)); + let slice_ty = ty::mk_vec(tcx, + ty::mt {ty:mt.ty, mutbl:m}, + vstore_slice(r)); // NB: we do not try to autoref to a mutable // pointer. That would be creating a pointer // to a temporary pointer (the borrowed @@ -728,19 +728,19 @@ impl<'a> LookupContext<'a> { }) } - ty_estr(vstore_box) | - ty_estr(vstore_uniq) | - ty_estr(vstore_fixed(_)) => { + ty_str(vstore_box) | + ty_str(vstore_uniq) | + ty_str(vstore_fixed(_)) => { let entry = self.search_for_some_kind_of_autorefd_method( AutoBorrowVec, autoderefs, [MutImmutable], - |_m,r| ty::mk_estr(tcx, vstore_slice(r))); + |_m,r| ty::mk_str(tcx, vstore_slice(r))); if entry.is_some() { return entry; } self.search_for_some_kind_of_autorefd_method( AutoBorrowVecRef, autoderefs, [MutImmutable], |m,r| { - let slice_ty = ty::mk_estr(tcx, vstore_slice(r)); + let slice_ty = ty::mk_str(tcx, vstore_slice(r)); ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m}) }) } @@ -782,7 +782,7 @@ impl<'a> LookupContext<'a> { ty_self(_) | ty_param(..) | ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | ty_enum(..) | ty_ptr(..) | ty_struct(..) | ty_tup(..) | - ty_estr(..) | ty_evec(..) | ty_trait(..) | ty_closure(..) => { + ty_str(..) | ty_vec(..) | ty_trait(..) | ty_closure(..) => { self.search_for_some_kind_of_autorefd_method( AutoPtr, autoderefs, [MutImmutable, MutMutable], |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m})) @@ -791,7 +791,7 @@ impl<'a> LookupContext<'a> { ty_err => None, ty_opaque_closure_ptr(_) | ty_unboxed_vec(_) | - ty_opaque_box | ty_type | ty_infer(TyVar(_)) => { + ty_type | ty_infer(TyVar(_)) => { self.bug(format!("Unexpected type: {}", self.ty_to_str(self_ty))); } @@ -1020,8 +1020,6 @@ impl<'a> LookupContext<'a> { }); debug!("after replacing bound regions, fty={}", self.ty_to_str(fty)); - let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self); - // before we only checked whether self_ty could be a subtype // of rcvr_ty; now we actually make it so (this may cause // variables to unify etc). Since we checked beforehand, and @@ -1041,7 +1039,6 @@ impl<'a> LookupContext<'a> { self.fcx.write_substs(self.callee_id, all_substs); method_map_entry { self_ty: transformed_self_ty, - self_mode: self_mode, explicit_self: candidate.method_ty.explicit_self, origin: candidate.origin, } @@ -1375,13 +1372,6 @@ impl<'a> LookupContext<'a> { } } -pub fn get_mode_from_explicit_self(explicit_self: ast::ExplicitSelf_) -> SelfMode { - match explicit_self { - SelfValue(_) => ty::ByRef, - _ => ty::ByCopy, - } -} - impl Repr for RcvrMatchCondition { fn repr(&self, tcx: ty::ctxt) -> ~str { match *self { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 5acca083d7939..242fa1faf9772 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1386,10 +1386,10 @@ pub fn check_lit(fcx: @FnCtxt, lit: &ast::Lit) -> ty::t { let tcx = fcx.ccx.tcx; match lit.node { - ast::LitStr(..) => ty::mk_estr(tcx, ty::vstore_slice(ty::ReStatic)), + ast::LitStr(..) => ty::mk_str(tcx, ty::vstore_slice(ty::ReStatic)), ast::LitBinary(..) => { - ty::mk_evec(tcx, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable }, - ty::vstore_slice(ty::ReStatic)) + ty::mk_vec(tcx, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable }, + ty::vstore_slice(ty::ReStatic)) } ast::LitChar(_) => ty::mk_char(), ast::LitInt(_, t) => ty::mk_mach_int(t), @@ -2629,7 +2629,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, let typ = match ev.node { ast::ExprLit(@codemap::Spanned { node: ast::LitStr(..), .. }) => { let tt = ast_expr_vstore_to_vstore(fcx, ev, vst); - ty::mk_estr(tcx, tt) + ty::mk_str(tcx, tt) } ast::ExprVec(ref args, mutbl) => { let tt = ast_expr_vstore_to_vstore(fcx, ev, vst); @@ -2655,7 +2655,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, } else if any_bot { ty::mk_bot() } else { - ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) + ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) } } ast::ExprRepeat(element, count_expr, mutbl) => { @@ -2674,7 +2674,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, } else if ty::type_is_bot(arg_t) { ty::mk_bot() } else { - ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) + ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutability}, tt) } } _ => @@ -3166,7 +3166,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, fn is_vec(t: ty::t) -> bool { match ty::get(t).sty { - ty::ty_evec(_,_) => true, + ty::ty_vec(..) => true, _ => false } } @@ -3223,8 +3223,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, for e in args.iter() { check_expr_has_type(fcx, *e, t); } - let typ = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, - ty::vstore_fixed(args.len())); + let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutbl}, + ty::vstore_fixed(args.len())); fcx.write_ty(id, typ); } ast::ExprRepeat(element, count_expr, mutbl) => { @@ -3240,8 +3240,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, fcx.write_bot(id); } else { - let t = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl}, - ty::vstore_fixed(count)); + let t = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutbl}, + ty::vstore_fixed(count)); fcx.write_ty(id, t); } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 7938bf3ffe29b..032c8f4575392 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -677,8 +677,8 @@ fn constrain_index(rcx: &mut Rcx, let r_index_expr = ty::ReScope(index_expr.id); match ty::get(indexed_ty).sty { - ty::ty_estr(ty::vstore_slice(r_ptr)) | - ty::ty_evec(_, ty::vstore_slice(r_ptr)) => { + ty::ty_str(ty::vstore_slice(r_ptr)) | + ty::ty_vec(_, ty::vstore_slice(r_ptr)) => { rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span), r_index_expr, r_ptr); } @@ -1215,22 +1215,22 @@ pub mod guarantor { fn pointer_categorize(ty: ty::t) -> PointerCategorization { match ty::get(ty).sty { ty::ty_rptr(r, _) | - ty::ty_evec(_, ty::vstore_slice(r)) | + ty::ty_vec(_, ty::vstore_slice(r)) | ty::ty_trait(_, _, ty::RegionTraitStore(r), _, _) | - ty::ty_estr(ty::vstore_slice(r)) => { + ty::ty_str(ty::vstore_slice(r)) => { BorrowedPointer(r) } ty::ty_uniq(..) | - ty::ty_estr(ty::vstore_uniq) | + ty::ty_str(ty::vstore_uniq) | ty::ty_trait(_, _, ty::UniqTraitStore, _, _) | - ty::ty_evec(_, ty::vstore_uniq) => { + ty::ty_vec(_, ty::vstore_uniq) => { OwnedPointer } ty::ty_box(..) | ty::ty_ptr(..) | - ty::ty_evec(_, ty::vstore_box) | + ty::ty_vec(_, ty::vstore_box) | ty::ty_trait(_, _, ty::BoxTraitStore, _, _) | - ty::ty_estr(ty::vstore_box) => { + ty::ty_str(ty::vstore_box) => { OtherPointer } ty::ty_closure(ref closure_ty) => { diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index cc145e9a52ce5..c8fde97e4d6b3 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -103,7 +103,7 @@ pub fn relate_nested_regions(tcx: ty::ctxt, fn fold_ty(&mut self, ty: ty::t) -> ty::t { match ty::get(ty).sty { ty::ty_rptr(r, ref mt) | - ty::ty_evec(ref mt, ty::vstore_slice(r)) => { + ty::ty_vec(ref mt, ty::vstore_slice(r)) => { self.relate(r); self.stack.push(r); ty_fold::super_fold_ty(self, mt.ty); diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 9466792c62e94..6e944e82a023a 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -20,8 +20,8 @@ use metadata::csearch; use middle::ty::get; use middle::ty::{ImplContainer, lookup_item_type, subst}; use middle::ty::{substs, t, ty_bool, ty_char, ty_bot, ty_box, ty_enum, ty_err}; -use middle::ty::{ty_estr, ty_evec, ty_float, ty_infer, ty_int, ty_nil}; -use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr}; +use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil}; +use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr}; use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup}; use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure}; use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec}; @@ -82,8 +82,8 @@ pub fn get_base_type(inference_context: @InferCtxt, } ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | - ty_estr(..) | ty_evec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) | - ty_infer(..) | ty_param(..) | ty_self(..) | ty_type | ty_opaque_box | + ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) | + ty_infer(..) | ty_param(..) | ty_self(..) | ty_type | ty_opaque_closure_ptr(..) | ty_unboxed_vec(..) | ty_err | ty_box(_) | ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => { debug!("(getting base type) no base type; found {:?}", diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 5971a6b7943bd..6c4a82c628afd 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -107,13 +107,13 @@ impl Coerce { }); } - ty::ty_estr(vstore_slice(_)) => { + ty::ty_str(vstore_slice(_)) => { return self.unpack_actual_value(a, |sty_a| { self.coerce_borrowed_string(a, sty_a, b) }); } - ty::ty_evec(mt_b, vstore_slice(_)) => { + ty::ty_vec(mt_b, vstore_slice(_)) => { return self.unpack_actual_value(a, |sty_a| { self.coerce_borrowed_vector(a, sty_a, b, mt_b) }); @@ -273,15 +273,15 @@ impl Coerce { b.inf_str(self.get_ref().infcx)); match *sty_a { - ty::ty_estr(vstore_box) | - ty::ty_estr(vstore_uniq) => {} + ty::ty_str(vstore_box) | + ty::ty_str(vstore_uniq) => {} _ => { return self.subtype(a, b); } }; let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); - let a_borrowed = ty::mk_estr(self.get_ref().infcx.tcx, vstore_slice(r_a)); + let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, vstore_slice(r_a)); if_ok!(self.subtype(a_borrowed, b)); Ok(Some(@AutoDerefRef(AutoDerefRef { autoderefs: 0, @@ -302,15 +302,15 @@ impl Coerce { let sub = Sub(*self.get_ref()); let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); let ty_inner = match *sty_a { - ty::ty_evec(mt, _) => mt.ty, + ty::ty_vec(mt, _) => mt.ty, _ => { return self.subtype(a, b); } }; - let a_borrowed = ty::mk_evec(self.get_ref().infcx.tcx, - mt {ty: ty_inner, mutbl: mt_b.mutbl}, - vstore_slice(r_borrow)); + let a_borrowed = ty::mk_vec(self.get_ref().infcx.tcx, + mt {ty: ty_inner, mutbl: mt_b.mutbl}, + vstore_slice(r_borrow)); if_ok!(sub.tys(a_borrowed, b)); Ok(Some(@AutoDerefRef(AutoDerefRef { autoderefs: 0, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 2b2115173ae57..01e19f011aa61 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -535,17 +535,17 @@ pub fn super_tys(this: &C, a: ty::t, b: ty::t) -> cres { Ok(ty::mk_rptr(tcx, r, mt)) } - (&ty::ty_evec(ref a_mt, vs_a), &ty::ty_evec(ref b_mt, vs_b)) => { + (&ty::ty_vec(ref a_mt, vs_a), &ty::ty_vec(ref b_mt, vs_b)) => { this.mts(a_mt, b_mt).and_then(|mt| { this.vstores(ty::terr_vec, vs_a, vs_b).and_then(|vs| { - Ok(ty::mk_evec(tcx, mt, vs)) + Ok(ty::mk_vec(tcx, mt, vs)) }) }) } - (&ty::ty_estr(vs_a), &ty::ty_estr(vs_b)) => { + (&ty::ty_str(vs_a), &ty::ty_str(vs_b)) => { let vs = if_ok!(this.vstores(ty::terr_str, vs_a, vs_b)); - Ok(ty::mk_estr(tcx,vs)) + Ok(ty::mk_str(tcx,vs)) } (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index d3f075774c524..0a7f7303a3724 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -148,9 +148,6 @@ pub struct method_map_entry { // (FIXME #3446) self_ty: ty::t, - // the mode of `self` - self_mode: ty::SelfMode, - // the type of explicit self on the method explicit_self: ast::ExplicitSelf_, diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index b5e5bdfd65bfa..509836512c09d 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -625,11 +625,11 @@ impl<'a> ConstraintContext<'a> { self.add_constraints_from_mt(mt, variance); } - ty::ty_estr(vstore) => { + ty::ty_str(vstore) => { self.add_constraints_from_vstore(vstore, variance); } - ty::ty_evec(ref mt, vstore) => { + ty::ty_vec(ref mt, vstore) => { self.add_constraints_from_vstore(vstore, variance); self.add_constraints_from_mt(mt, variance); } @@ -693,8 +693,7 @@ impl<'a> ConstraintContext<'a> { } ty::ty_infer(..) | ty::ty_err | ty::ty_type | - ty::ty_opaque_box | ty::ty_opaque_closure_ptr(..) | - ty::ty_unboxed_vec(..) => { + ty::ty_opaque_closure_ptr(..) | ty::ty_unboxed_vec(..) => { self.tcx().sess.bug( format!("Unexpected type encountered in \ variance inference: {}", diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6ef00fa9d007e..84dece87750a0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -17,8 +17,8 @@ use middle::ty::{mt, t, param_ty}; use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty}; use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum}; -use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure}; -use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param}; +use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure}; +use middle::ty::{ty_nil, ty_opaque_closure_ptr, ty_param}; use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq}; use middle::ty::{ty_trait, ty_int}; use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer}; @@ -501,11 +501,10 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { format!("{}{}{}{}{}", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty, bound_sep, bound_str) } - ty_evec(ref mt, vs) => { + ty_vec(ref mt, vs) => { vstore_ty_to_str(cx, mt, vs) } - ty_estr(vs) => format!("{}{}", vstore_to_str(cx, vs), "str"), - ty_opaque_box => ~"@?", + ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str"), ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"&closure", ty_opaque_closure_ptr(ast::ManagedSigil) => ~"@closure", ty_opaque_closure_ptr(ast::OwnedSigil) => ~"~closure", diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index d6b33fda7455d..acd1cfcf9013a 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -47,9 +47,9 @@ pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId}; pub type GlueFn = extern "Rust" fn(*i8); -// NB: this has to be kept in sync with `type_desc` in `rt` +// NOTE remove after next snapshot #[lang="ty_desc"] -#[cfg(not(test))] +#[cfg(not(test), stage0)] pub struct TyDesc { // sizeof(T) size: uint, @@ -80,6 +80,35 @@ pub struct TyDesc { name: &'static str } +#[lang="ty_desc"] +#[cfg(not(test), not(stage0))] +pub struct TyDesc { + // sizeof(T) + size: uint, + + // alignof(T) + align: uint, + + // Called on a copy of a value of type `T` *after* memcpy + take_glue: GlueFn, + + // Called when a value of type `T` is no longer needed + drop_glue: GlueFn, + + // Called by reflection visitor to visit a value of type `T` + visit_glue: GlueFn, + + // If T represents a box pointer (`@U` or `~U`), then + // `borrow_offset` is the amount that the pointer must be adjusted + // to find the payload. This is always derivable from the type + // `U`, but in the case of `@Trait` or `~Trait` objects, the type + // `U` is unknown. + borrow_offset: uint, + + // Name corresponding to the type + name: &'static str +} + #[lang="opaque"] #[cfg(not(test))] pub enum Opaque { } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0424c71dd590b..b783ea6da3c54 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2276,7 +2276,7 @@ impl Parser { let m = self.parse_mutability(); let e = self.parse_prefix_expr(); hi = e.span.hi; - // HACK: turn &[...] into a &-evec + // HACK: turn &[...] into a &-vec ex = match e.node { ExprVec(..) | ExprLit(@codemap::Spanned { node: LitStr(..), span: _ @@ -2297,7 +2297,7 @@ impl Parser { self.bump(); let e = self.parse_prefix_expr(); hi = e.span.hi; - // HACK: turn @[...] into a @-evec + // HACK: turn @[...] into a @-vec ex = match e.node { ExprVec(..) | ExprLit(@codemap::Spanned { node: LitStr(..), span: _}) | @@ -2310,7 +2310,7 @@ impl Parser { let e = self.parse_prefix_expr(); hi = e.span.hi; - // HACK: turn ~[...] into a ~-evec + // HACK: turn ~[...] into a ~-vec ex = match e.node { ExprVec(..) | ExprLit(@codemap::Spanned { node: LitStr(..), span: _}) | @@ -2337,7 +2337,7 @@ impl Parser { // Otherwise, we use the unique pointer default. let subexpression = self.parse_prefix_expr(); hi = subexpression.span.hi; - // HACK: turn `box [...]` into a boxed-evec + // HACK: turn `box [...]` into a boxed-vec ex = match subexpression.node { ExprVec(..) | ExprLit(@codemap::Spanned { diff --git a/src/test/run-pass/self-in-mut-slot-immediate-value.rs b/src/test/run-pass/self-in-mut-slot-immediate-value.rs new file mode 100644 index 0000000000000..f2482474073e0 --- /dev/null +++ b/src/test/run-pass/self-in-mut-slot-immediate-value.rs @@ -0,0 +1,30 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Assert that `mut self` on an immediate value doesn't +// allow mutating the original - issue #10615. + +struct Value { + n: int +} + +impl Value { + fn squared(mut self) -> Value { + self.n *= self.n; + self + } +} + +pub fn main() { + let x = Value { n: 3 }; + let y = x.squared(); + assert_eq!(x.n, 3); + assert_eq!(y.n, 9); +}