auto merge of #7410 : luqmana/rust/bare-self, r=catamorphism
Finally sorted this out. Fixes #5321, #4439, and #4850.
This commit is contained in:
commit
61dc7760d0
6 changed files with 72 additions and 32 deletions
|
@ -41,6 +41,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
|
|||
callee::trans_arg_expr(bcx,
|
||||
expr_ty(bcx, out),
|
||||
ty::ByCopy,
|
||||
ast::sty_static,
|
||||
out,
|
||||
&mut cleanups,
|
||||
None,
|
||||
|
@ -56,6 +57,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
|
|||
callee::trans_arg_expr(bcx,
|
||||
expr_ty(bcx, e),
|
||||
ty::ByCopy,
|
||||
ast::sty_static,
|
||||
e,
|
||||
&mut cleanups,
|
||||
None,
|
||||
|
@ -77,6 +79,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
|
|||
callee::trans_arg_expr(bcx,
|
||||
expr_ty(bcx, in),
|
||||
ty::ByCopy,
|
||||
ast::sty_static,
|
||||
in,
|
||||
&mut cleanups,
|
||||
None,
|
||||
|
|
|
@ -1681,19 +1681,11 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
|
|||
|
||||
match fcx.llself {
|
||||
Some(slf) => {
|
||||
let self_val = if slf.is_owned
|
||||
&& datum::appropriate_mode(slf.t).is_by_value() {
|
||||
let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t));
|
||||
let alloc = alloc_ty(bcx, slf.t);
|
||||
Store(bcx, tmp, alloc);
|
||||
alloc
|
||||
} else {
|
||||
PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to())
|
||||
};
|
||||
|
||||
let self_val = PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to());
|
||||
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
|
||||
|
||||
if slf.is_owned {
|
||||
add_clean(bcx, self_val, slf.t);
|
||||
add_clean(bcx, slf.v, slf.t);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -63,6 +63,7 @@ pub struct MethodData {
|
|||
llself: ValueRef,
|
||||
self_ty: ty::t,
|
||||
self_mode: ty::SelfMode,
|
||||
explicit_self: ast::explicit_self_
|
||||
}
|
||||
|
||||
pub enum CalleeData {
|
||||
|
@ -565,7 +566,8 @@ pub fn trans_call_inner(in_cx: block,
|
|||
// Now that the arguments have finished evaluating, we need to revoke
|
||||
// the cleanup for the self argument, if it exists
|
||||
match callee.data {
|
||||
Method(d) if d.self_mode == ty::ByCopy => {
|
||||
Method(d) if d.self_mode == ty::ByCopy ||
|
||||
d.explicit_self == ast::sty_value => {
|
||||
revoke_clean(bcx, d.llself);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -687,6 +689,7 @@ pub fn trans_args(cx: block,
|
|||
trans_arg_expr(bcx,
|
||||
arg_tys[i],
|
||||
ty::ByCopy,
|
||||
ast::sty_static,
|
||||
*arg_expr,
|
||||
&mut temp_cleanups,
|
||||
if i == last { ret_flag } else { None },
|
||||
|
@ -720,6 +723,7 @@ pub enum AutorefArg {
|
|||
pub fn trans_arg_expr(bcx: block,
|
||||
formal_arg_ty: ty::t,
|
||||
self_mode: ty::SelfMode,
|
||||
ex_self: ast::explicit_self_,
|
||||
arg_expr: @ast::expr,
|
||||
temp_cleanups: &mut ~[ValueRef],
|
||||
ret_flag: Option<ValueRef>,
|
||||
|
@ -727,9 +731,10 @@ pub fn trans_arg_expr(bcx: block,
|
|||
let _icx = push_ctxt("trans_arg_expr");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \
|
||||
debug!("trans_arg_expr(formal_arg_ty=(%s), explicit_self=%? self_mode=%?, arg_expr=%s, \
|
||||
ret_flag=%?)",
|
||||
formal_arg_ty.repr(bcx.tcx()),
|
||||
ex_self,
|
||||
self_mode,
|
||||
arg_expr.repr(bcx.tcx()),
|
||||
ret_flag.map(|v| bcx.val_to_str(*v)));
|
||||
|
@ -789,8 +794,26 @@ pub fn trans_arg_expr(bcx: block,
|
|||
val = arg_datum.to_ref_llval(bcx);
|
||||
}
|
||||
DontAutorefArg => {
|
||||
match self_mode {
|
||||
ty::ByRef => {
|
||||
match (self_mode, ex_self) {
|
||||
(ty::ByRef, ast::sty_value) => {
|
||||
debug!("by value self with type %s, storing to scratch",
|
||||
bcx.ty_to_str(arg_datum.ty));
|
||||
let scratch = scratch_datum(bcx, arg_datum.ty, false);
|
||||
|
||||
arg_datum.store_to_datum(bcx,
|
||||
arg_expr.id,
|
||||
INIT,
|
||||
scratch);
|
||||
|
||||
// Technically, ownership of val passes to the callee.
|
||||
// However, we must cleanup should we fail before the
|
||||
// callee is actually invoked.
|
||||
scratch.add_clean(bcx);
|
||||
temp_cleanups.push(scratch.val);
|
||||
|
||||
val = scratch.to_ref_llval(bcx);
|
||||
}
|
||||
(ty::ByRef, _) => {
|
||||
// This assertion should really be valid, but because
|
||||
// the explicit self code currently passes by-ref, it
|
||||
// does not hold.
|
||||
|
@ -801,7 +824,7 @@ pub fn trans_arg_expr(bcx: block,
|
|||
bcx.ty_to_str(arg_datum.ty));
|
||||
val = arg_datum.to_ref_llval(bcx);
|
||||
}
|
||||
ty::ByCopy => {
|
||||
(ty::ByCopy, _) => {
|
||||
if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) ||
|
||||
arg_datum.appropriate_mode().is_by_ref() {
|
||||
debug!("by copy arg with type %s, storing to scratch",
|
||||
|
|
|
@ -110,9 +110,7 @@ pub fn trans_method(ccx: @mut CrateContext,
|
|||
debug!("calling trans_fn with self_ty %s",
|
||||
self_ty.repr(ccx.tcx));
|
||||
match method.explicit_self.node {
|
||||
ast::sty_value => {
|
||||
impl_owned_self(self_ty)
|
||||
}
|
||||
ast::sty_value => impl_owned_self(self_ty),
|
||||
_ => {
|
||||
impl_self(self_ty)
|
||||
}
|
||||
|
@ -145,6 +143,7 @@ pub fn trans_self_arg(bcx: block,
|
|||
let result = trans_arg_expr(bcx,
|
||||
self_ty,
|
||||
mentry.self_mode,
|
||||
mentry.explicit_self,
|
||||
base,
|
||||
&mut temp_cleanups,
|
||||
None,
|
||||
|
@ -231,6 +230,7 @@ pub fn trans_method_callee(bcx: block,
|
|||
llself: val,
|
||||
self_ty: node_id_type(bcx, this.id),
|
||||
self_mode: mentry.self_mode,
|
||||
explicit_self: mentry.explicit_self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -453,6 +453,7 @@ pub fn trans_monomorphized_callee(bcx: block,
|
|||
llself: llself_val,
|
||||
self_ty: node_id_type(bcx, base.id),
|
||||
self_mode: mentry.self_mode,
|
||||
explicit_self: mentry.explicit_self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -692,6 +693,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
|
|||
llself: llself,
|
||||
self_ty: ty::mk_opaque_box(bcx.tcx()),
|
||||
self_mode: self_mode,
|
||||
explicit_self: explicit_self
|
||||
/* XXX: Some(llbox) */
|
||||
})
|
||||
};
|
||||
|
|
|
@ -976,7 +976,9 @@ 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);
|
||||
// FIXME(#7411): 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
|
||||
|
@ -1242,10 +1244,3 @@ 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,
|
||||
}
|
||||
}
|
||||
|
|
25
src/test/run-pass/issue-5321-immediates-with-bare-self.rs
Normal file
25
src/test/run-pass/issue-5321-immediates-with-bare-self.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait Fooable {
|
||||
fn yes(self);
|
||||
}
|
||||
|
||||
impl Fooable for uint {
|
||||
fn yes(self) {
|
||||
for self.times {
|
||||
println("yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
2.yes();
|
||||
}
|
Loading…
Reference in a new issue