auto merge of #11252 : eddyb/rust/ty-cleanup, r=pcwalton

This commit is contained in:
bors 2014-01-11 07:31:40 -08:00
commit 4bdda359c3
48 changed files with 772 additions and 915 deletions

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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
}),
})
}
})
}

View File

@ -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)
}

View File

@ -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

View File

@ -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");
}

View File

@ -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;
}

View File

@ -157,14 +157,14 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
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<deref_kind> {
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<deref_kind> {
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
}
}

View File

@ -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);
}
lldest
}
TrByValue(lldest) => lldest,
// By ref binding: use the ptr into the matched value
TrByRef => {
binding_info.llmatch
}
TrByRef => binding_info.llmatch
};
let datum = Datum {
val: llval,
ty: binding_info.ty,
mode: ByRef(ZeroMem)
};
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(<pat>: 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 datum = Datum {
val: llval,
ty: var_ty,
mode: ByRef(ZeroMem)
};
{
let mut llmap = match binding_mode {
BindLocal => bcx.fcx.lllocals.borrow_mut(),
BindArgument => bcx.fcx.llargs.borrow_mut(),
BindArgument => bcx.fcx.llargs.borrow_mut()
};
llmap.get().insert(p_id, llval);
add_clean(bcx, llval, var_ty);
return bcx;
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
}
}

View File

@ -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)

View File

@ -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<ty::t>,
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<ty::t>, 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<ty::t>,
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
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
}
}));
}
no_self => ()
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 {
PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to())
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 {
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
} else {
raw_llarg
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")
};
bcx = _match::store_arg(bcx, args[arg_n].pat, llarg);
Store(bcx, arg.val, alloc);
datum::Datum {
val: alloc,
ty: arg.ty,
mode: datum::ByRef(datum::ZeroMem)
}
} else {
arg
};
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<ty::t>,
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<ty::t>,
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<ast::Ty> { self.node.ty }
}
pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
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<A:IdAndTy>(
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<A:IdAndTy>(
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,11 +2509,12 @@ fn finish_register_fn(ccx: @CrateContext, sp: Span, sym: ~str, node_id: ast::Nod
}
}
pub fn register_fn(ccx: @CrateContext,
fn register_fn(ccx: @CrateContext,
sp: Span,
sym: ~str,
node_id: ast::NodeId,
node_type: ty::t)
node_type: ty::t,
self_ty: Option<ty::t>)
-> ValueRef {
let f = match ty::get(node_type).sty {
ty::ty_bare_fn(ref f) => {
@ -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,
fn register_method(ccx: @CrateContext,
id: ast::NodeId,
path: @ast_map::Path,
m: @ast::Method) -> ValueRef {
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);

View File

@ -60,8 +60,7 @@ pub struct FnData {
pub struct MethodData {
llfn: ValueRef,
llself: ValueRef,
temp_cleanup: Option<ValueRef>,
self_mode: ty::SelfMode,
temp_cleanup: Option<ValueRef>
}
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)
}
}
val = arg_datum.to_appropriate_llval(bcx);
}
}

View File

@ -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))
}

View File

@ -94,7 +94,6 @@ pub struct tydesc_info {
name: ValueRef,
take_glue: Cell<Option<ValueRef>>,
drop_glue: Cell<Option<ValueRef>>,
free_glue: Cell<Option<ValueRef>>,
visit_glue: Cell<Option<ValueRef>>,
}
@ -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<Option<ValSelfData>>,
llself: Cell<Option<datum::Datum>>,
// The a value alloca'd for calls to upcalls.rust_personality. Used when
// outputting the resume instruction.
personality: Cell<Option<ValueRef>>,
@ -239,10 +231,10 @@ pub struct FunctionContext<'a> {
caller_expects_out_pointer: bool,
// Maps arguments to allocas created for them in llallocas.
llargs: RefCell<HashMap<ast::NodeId, ValueRef>>,
llargs: RefCell<HashMap<ast::NodeId, datum::Datum>>,
// Maps the def_ids for local variables to the allocas created for
// them in llallocas.
lllocals: RefCell<HashMap<ast::NodeId, ValueRef>>,
lllocals: RefCell<HashMap<ast::NodeId, datum::Datum>>,
// Same as above, but for closure upvars
llupvars: RefCell<HashMap<ast::NodeId, ValueRef>>,
@ -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,
/// a datum.
struct DatumDroppingCleanupFunction {
datum: datum::Datum
}
impl CleanupFunction for TypeDroppingCleanupFunction {
impl CleanupFunction for DatumDroppingCleanupFunction {
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,
}
impl CleanupFunction for ImmediateTypeDroppingCleanupFunction {
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 {
cleanups.get().push(Clean(@DatumDroppingCleanupFunction {
datum: datum::Datum {
val: val,
t: t,
ty: ty,
mode: datum::ByRef(datum::ZeroMem)
}
} as @CleanupFunction,
cleanup_type));
}
@ -460,19 +439,22 @@ 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,
ty: ty,
mode: datum::ByValue
}
} as @CleanupFunction,
cleanup_type));
}
@ -501,10 +483,12 @@ pub fn add_clean_temp_mem_in_scope_(bcx: &Block, scope_id: Option<ast::NodeId>,
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,
ty: t,
mode: datum::ByRef(datum::RevokeClean)
}
} as @CleanupFunction,
cleanup_type));
}
@ -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()
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

View File

@ -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 {

View File

@ -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)

View File

@ -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))
};

View File

@ -287,7 +287,7 @@ 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,
let slice_ty = ty::mk_vec(tcx,
ty::mt { ty: unit_ty, mutbl: ast::MutImmutable },
ty::vstore_slice(ty::ReStatic));
@ -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<ast::NodeId, ValueRef>,
nid: ast::NodeId)
-> Datum {
let v = match table.find(&nid) {
table: &HashMap<ast::NodeId, Datum>,
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
}
}

View File

@ -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;
}

View File

@ -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_take_glue && ty::type_is_boxed(t) {
return ty::mk_imm_box(tcx, ty::mk_nil());
}
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_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()),
return ty::mk_imm_box(tcx, ty::mk_nil()),
ty::ty_evec(mt, ty::vstore_box)
ty::ty_vec(mt, ty::vstore_box)
if !ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_box(tcx, ty::mk_u32()),
return ty::mk_imm_box(tcx, ty::mk_nil()),
ty::ty_uniq(mt) |
ty::ty_evec(mt, ty::vstore_uniq)
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_u32()),
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 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,19 +254,15 @@ 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)
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)
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| {
@ -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<ValueRef>,
t: ty::t)
-> &'a Block<'a> {
fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef,
t: Option<ty::t>) -> &'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);
CondBr(decr_bcx, IsNull(decr_bcx, rc), 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)
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,17 +580,13 @@ 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,
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();
@ -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

View File

@ -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)

View File

@ -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());

View File

@ -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<ty::t>| -> 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
})
};
}

View File

@ -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;

View File

@ -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();
meth::trans_method(ccx, pt, mth, Some(psubsts), |self_ty| {
let d = mk_lldecl(self_ty);
set_llvm_fn_attrs(mth.attrs, d);
meth::trans_method(ccx, pt, mth, Some(psubsts), d);
d
})
}
ast_map::NodeTraitMethod(@ast::Provided(mth), _, pt) => {
let d = mk_lldecl();
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), |self_ty| {
let d = mk_lldecl(self_ty);
set_llvm_fn_attrs(mth.attrs, d);
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), 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,

View File

@ -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)];

View File

@ -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,7 +239,7 @@ 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(),
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();
@ -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
};

View File

@ -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

View File

@ -44,6 +44,7 @@ pub fn type_of_explicit_args(ccx: &CrateContext,
}
pub fn type_of_rust_fn(cx: &CrateContext,
self_ty: Option<ty::t>,
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<ty::t>, 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),

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
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)
}
})
}

View File

@ -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<mt> {
pub fn index_sty(sty: &sty) -> Option<mt> {
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);
}
}

View File

@ -152,9 +152,8 @@ pub fn super_fold_sty<T:TypeFolder>(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<T:TypeFolder>(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()
}

View File

@ -293,8 +293,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
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<AC:AstConv,
RS:RegionScope>(
@ -314,7 +314,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
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<AC:AstConv, RS:RegionScope>(
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<AC:AstConv, RS:RegionScope>(
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<AC:AstConv, RS:RegionScope>(
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,10 +552,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
Ok(ref r) => {
match *r {
const_eval::const_int(i) =>
ty::mk_evec(tcx, ast_ty_to_mt(this, rscope, ty),
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::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty),
ty::vstore_fixed(i as uint)),
_ => {
tcx.sess.span_fatal(

View File

@ -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)
);

View File

@ -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,14 +699,14 @@ 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,
|m,r| ty::mk_vec(tcx,
ty::mt {ty:mt.ty, mutbl:m},
vstore_slice(r)));
@ -716,7 +716,7 @@ 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,
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
@ -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 {

View File

@ -1386,9 +1386,9 @@ 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::mk_vec(tcx, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable },
ty::vstore_slice(ty::ReStatic))
}
ast::LitChar(_) => ty::mk_char(),
@ -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,7 +3223,7 @@ 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},
let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutbl},
ty::vstore_fixed(args.len()));
fcx.write_ty(id, typ);
}
@ -3240,7 +3240,7 @@ 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},
let t = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: mutbl},
ty::vstore_fixed(count));
fcx.write_ty(id, t);
}

View File

@ -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) => {

View File

@ -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);

View File

@ -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 {:?}",

View File

@ -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,13 +302,13 @@ 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,
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));

View File

@ -535,17 +535,17 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
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)) => {

View File

@ -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_,

View File

@ -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: {}",

View File

@ -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",

View File

@ -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 { }

View File

@ -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 {

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// 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);
}