diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f92acbaf5c68..08073fba7456 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1036,13 +1036,13 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef { pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = cx.insn_ctxt("spill_if_immediate"); - if ty::type_is_immediate(t) { return do_spill(cx, v, t); } + if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); } return v; } pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = cx.insn_ctxt("load_if_immediate"); - if ty::type_is_immediate(t) { return Load(cx, v); } + if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); } return v; } @@ -1573,7 +1573,7 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { // slot where the return value of the function must go. pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef { unsafe { - if !ty::type_is_immediate(output_type) { + if !ty::type_is_immediate(fcx.ccx.tcx, output_type) { llvm::LLVMGetParam(fcx.llfn, 0) } else { let lloutputtype = type_of::type_of(*fcx.ccx, output_type); @@ -1614,7 +1614,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type) } }; - let is_immediate = ty::type_is_immediate(substd_output_type); + let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type); let fcx = @mut fn_ctxt_ { llfn: llfndecl, @@ -1734,7 +1734,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, // 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(arg_ty).is_by_value() { + let llarg = if datum::appropriate_mode(bcx.tcx(), arg_ty).is_by_value() { let alloc = alloc_ty(bcx, arg_ty); Store(bcx, raw_llarg, alloc); alloc diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 3d4649bba466..6243cbd644ec 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -510,7 +510,7 @@ pub fn trans_call_inner(in_cx: block, let mut llargs = ~[]; - if ty::type_is_immediate(ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { unsafe { llargs.push(llvm::LLVMGetUndef(T_ptr(T_i8()))); } @@ -559,7 +559,7 @@ pub fn trans_call_inner(in_cx: block, // case to ignore instead of invoking the Store // below into a scratch pointer of a mismatched // type. - } else if ty::type_is_immediate(ret_ty) { + } else if ty::type_is_immediate(bcx.tcx(), ret_ty) { let llscratchptr = alloc_ty(bcx, ret_ty); Store(bcx, llresult, llscratchptr); bcx = glue::drop_ty(bcx, llscratchptr, ret_ty); @@ -573,7 +573,7 @@ pub fn trans_call_inner(in_cx: block, // If this is an immediate, store into the result location. // (If this was not an immediate, the result will already be // directly written into the output slot.) - if ty::type_is_immediate(ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { Store(bcx, llresult, lldest); } } @@ -776,7 +776,7 @@ pub fn trans_arg_expr(bcx: block, scratch.add_clean(bcx); temp_cleanups.push(scratch.val); - match arg_datum.appropriate_mode() { + match arg_datum.appropriate_mode(bcx.tcx()) { ByValue => val = Load(bcx, scratch.val), ByRef => val = scratch.val, } diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 6be5dbe1beb6..e84fcadacd37 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -197,7 +197,7 @@ pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum { Datum { val: scratch, ty: ty, mode: ByRef, source: RevokeClean } } -pub fn appropriate_mode(ty: ty::t) -> DatumMode { +pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode { /*! * * Indicates the "appropriate" mode for this value, @@ -206,7 +206,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode { if ty::type_is_nil(ty) || ty::type_is_bot(ty) { ByValue - } else if ty::type_is_immediate(ty) { + } else if ty::type_is_immediate(tcx, ty) { ByValue } else { ByRef @@ -476,10 +476,10 @@ pub impl Datum { } } - fn appropriate_mode(&self) -> DatumMode { + fn appropriate_mode(&self, tcx: ty::ctxt) -> DatumMode { /*! See the `appropriate_mode()` function */ - appropriate_mode(self.ty) + appropriate_mode(tcx, self.ty) } fn to_appropriate_llval(&self, bcx: block) -> ValueRef { @@ -487,7 +487,7 @@ pub impl Datum { * * Yields an llvalue with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_llval(bcx), ByRef => self.to_ref_llval(bcx) } @@ -498,7 +498,7 @@ pub impl Datum { * * Yields a datum with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_datum(bcx), ByRef => self.to_ref_datum(bcx) } @@ -622,13 +622,7 @@ pub impl Datum { ByValue => { // Actually, this case cannot happen right // now, because enums are never immediate. - // But in principle newtype'd immediate - // values should be immediate, and in that - // case the * would be a no-op except for - // changing the type, so I am putting this - // code in place here to do the right - // thing if this change ever goes through. - assert!(ty::type_is_immediate(ty)); + assert!(ty::type_is_immediate(bcx.tcx(), ty)); (Some(Datum {ty: ty, ..*self}), bcx) } }; @@ -661,14 +655,7 @@ pub impl Datum { ) } ByValue => { - // Actually, this case cannot happen right now, - // because structs are never immediate. But in - // principle, newtype'd immediate values should be - // immediate, and in that case the * would be a no-op - // except for changing the type, so I am putting this - // code in place here to do the right thing if this - // change ever goes through. - assert!(ty::type_is_immediate(ty)); + assert!(ty::type_is_immediate(bcx.tcx(), ty)); (Some(Datum {ty: ty, ..*self}), bcx) } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d581d8043f8e..4140c0f67358 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -289,7 +289,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx)); let scratch = scratch_datum(bcx, closure_ty, false); let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]); - assert_eq!(datum.appropriate_mode(), ByValue); + assert_eq!(datum.appropriate_mode(tcx), ByValue); Store(bcx, datum.to_appropriate_llval(bcx), llfn); let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]); Store(bcx, base::null_env_ptr(bcx), llenv); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 58c77f037ded..e90be150da00 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -101,7 +101,7 @@ fn foreign_signature(ccx: @CrateContext, fn_sig: &ty::FnSig) LlvmSignature { llarg_tys: llarg_tys, llret_ty: llret_ty, - sret: !ty::type_is_immediate(fn_sig.output), + sret: !ty::type_is_immediate(ccx.tcx, fn_sig.output), } } @@ -193,7 +193,7 @@ fn build_wrap_fn_(ccx: @CrateContext, // Patch up the return type if it's not immediate and we're returning via // the C ABI. - if needs_c_return && !ty::type_is_immediate(tys.fn_sig.output) { + if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) { let lloutputtype = type_of::type_of(*fcx.ccx, tys.fn_sig.output); fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype)); @@ -697,7 +697,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, // is not necessary since, for intrinsics, there is no // cleanup to concern ourselves with. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode, source: RevokeClean}; bcx = src.move_to(bcx, DROP_EXISTING, @@ -706,7 +706,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, ~"move_val_init" => { // See comments for `"move_val"`. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode, source: RevokeClean}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); @@ -777,7 +777,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, let lldestptr = PointerCast(bcx, lldestptr, T_ptr(T_i8())); let llsrcval = get_param(decl, first_real_arg); - let llsrcptr = if ty::type_is_immediate(in_type) { + let llsrcptr = if ty::type_is_immediate(ccx.tcx, in_type) { let llsrcptr = alloca(bcx, llintype); Store(bcx, llsrcval, llsrcptr); llsrcptr @@ -1228,7 +1228,7 @@ pub fn trans_foreign_fn(ccx: @CrateContext, let mut i = 0u; let n = tys.fn_sig.inputs.len(); - if !ty::type_is_immediate(tys.fn_sig.output) { + if !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) { let llretptr = load_inbounds(bcx, llargbundle, [0u, n]); llargvals.push(llretptr); } else { @@ -1256,7 +1256,7 @@ pub fn trans_foreign_fn(ccx: @CrateContext, shim_types: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - if ty::type_is_immediate(shim_types.fn_sig.output) { + if ty::type_is_immediate(bcx.tcx(), shim_types.fn_sig.output) { // Write the value into the argument bundle. let arg_count = shim_types.fn_sig.inputs.len(); let llretptr = load_inbounds(bcx, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 2f48eda7edd2..8cacc7f80201 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -655,7 +655,7 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { pub fn declare_tydesc_addrspace(ccx: @CrateContext, t: ty::t) -> addrspace { if !ty::type_needs_drop(ccx.tcx, t) { return default_addrspace; - } else if ty::type_is_immediate(t) { + } else if ty::type_is_immediate(ccx.tcx, t) { // For immediate types, we don't actually need an addrspace, because // e.g. boxed types include pointers to their contents which are // already correctly tagged with addrspaces. diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index aa4bb775323c..9fdcb6ad6aa3 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -13,7 +13,7 @@ use core::prelude::*; use metadata::csearch; use middle::astencode; use middle::trans::base::{get_insn_ctxt}; -use middle::trans::base::{impl_owned_self, impl_self, no_self}; +use middle::trans::base::{impl_self, no_self}; use middle::trans::base::{trans_item, get_item_val, trans_fn}; use middle::trans::common::*; use middle::ty; @@ -109,7 +109,6 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::def_id, debug!("calling inline trans_fn with self_ty %s", ty_to_str(ccx.tcx, self_ty)); match mth.explicit_self.node { - ast::sty_value => impl_owned_self(self_ty), _ => impl_self(self_ty), } } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 381c257f6511..8e7ceffde0bc 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -130,9 +130,6 @@ pub fn trans_method(ccx: @CrateContext, base_self_ty.repr(ccx.tcx), self_ty.repr(ccx.tcx)); match method.explicit_self.node { - ast::sty_value => { - impl_owned_self(self_ty) - } _ => { impl_self(self_ty) } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 1b3150f14b20..a35d8ca0580f 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -379,7 +379,7 @@ pub fn make_mono_id(ccx: @CrateContext, let llty = type_of::type_of(ccx, subst); let size = machine::llbitsize_of_real(ccx, llty); let align = machine::llalign_of_pref(ccx, llty); - let mode = datum::appropriate_mode(subst); + let mode = datum::appropriate_mode(ccx.tcx, subst); let data_class = mono_data_classify(subst); // Special value for nil to prevent problems diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index bddcb9a1d737..b89fa34b6e99 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -21,8 +21,8 @@ use util::ppaux; use syntax::ast; -pub fn arg_is_indirect(_: @CrateContext, arg_ty: &ty::t) -> bool { - !ty::type_is_immediate(*arg_ty) +pub fn arg_is_indirect(ccx: @CrateContext, arg_ty: &ty::t) -> bool { + !ty::type_is_immediate(ccx.tcx, *arg_ty) } pub fn type_of_explicit_arg(ccx: @CrateContext, arg_ty: &ty::t) -> TypeRef { @@ -42,7 +42,7 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t) // Arg 0: Output pointer. // (if the output type is non-immediate) - let output_is_immediate = ty::type_is_immediate(output); + let output_is_immediate = ty::type_is_immediate(cx.tcx, output); let lloutputtype = type_of(cx, output); if !output_is_immediate { atys.push(T_ptr(lloutputtype)); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 621ce48a4fd0..c99663192858 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1706,9 +1706,23 @@ pub fn type_is_scalar(ty: t) -> bool { } } -pub fn type_is_immediate(ty: t) -> bool { +pub fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool { + match get(ty).sty { + ty_struct(def_id, ref substs) => { + let fields = struct_fields(cx, def_id, substs); + + // Is this an immediate newtype struct? + fields.len() == 1 && fields[0].ident == special_idents::unnamed_field + && type_is_immediate(cx, fields[0].mt.ty) + } + _ => false + } +} + +pub fn type_is_immediate(cx: ctxt, ty: t) -> bool { return type_is_scalar(ty) || type_is_boxed(ty) || - type_is_unique(ty) || type_is_region_ptr(ty); + type_is_unique(ty) || type_is_region_ptr(ty) || + type_is_newtype_immediate(cx, ty); } pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { @@ -3228,7 +3242,7 @@ pub fn expr_kind(tcx: ctxt, ast::expr_cast(*) => { match tcx.node_types.find(&(expr.id as uint)) { Some(&t) => { - if ty::type_is_immediate(t) { + if ty::type_is_immediate(tcx, t) { RvalueDatumExpr } else { RvalueDpsExpr diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 68deb900886f..f5598359c9bb 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1035,7 +1035,9 @@ pub impl<'self> LookupContext<'self> { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty}); debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty)); - let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self); + // XXX: We always pass self by-ref since we stuff it in the environment slot. + // Eventually that should not be the case + let self_mode = ty::ByRef; // before we only checked whether self_ty could be a subtype // of rcvr_ty; now we actually make it so (this may cause @@ -1302,10 +1304,3 @@ pub impl<'self> LookupContext<'self> { self.tcx().sess.bug(s) } } - -pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode { - match explicit_self { - sty_value => ty::ByCopy, - _ => ty::ByRef, - } -} diff --git a/src/test/run-pass/issue-3559 b/src/test/run-pass/issue-3559 deleted file mode 100755 index 505b9b65512f..000000000000 Binary files a/src/test/run-pass/issue-3559 and /dev/null differ diff --git a/src/test/run-pass/issue-3702 b/src/test/run-pass/issue-3702 deleted file mode 100755 index 3f39ee314421..000000000000 Binary files a/src/test/run-pass/issue-3702 and /dev/null differ diff --git a/src/test/run-pass/issue-4016 b/src/test/run-pass/issue-4016 deleted file mode 100755 index ff979383c102..000000000000 Binary files a/src/test/run-pass/issue-4016 and /dev/null differ diff --git a/src/test/run-pass/issue-4092 b/src/test/run-pass/issue-4092 deleted file mode 100755 index 761b6ab46862..000000000000 Binary files a/src/test/run-pass/issue-4092 and /dev/null differ diff --git a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs new file mode 100644 index 000000000000..ee2bfe4b1949 --- /dev/null +++ b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs @@ -0,0 +1,25 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Fooable { + fn yes(self); +} + +impl Fooable for uint { + fn yes(self) { + for self.times { + io::println("yes"); + } + } +} + +fn main() { + 2.yes(); +}