Skip to content

Commit

Permalink
auto merge of #7410 : luqmana/rust/bare-self, r=catamorphism
Browse files Browse the repository at this point in the history
Finally sorted this out. Fixes #5321, #4439, and #4850.
  • Loading branch information
bors committed Jun 28, 2013
2 parents 927f454 + 0aa94ff commit 61dc776
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 33 deletions.
3 changes: 3 additions & 0 deletions src/librustc/middle/trans/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
26 changes: 9 additions & 17 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1680,23 +1680,15 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
let mut bcx = bcx;

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

fcx.llself = Some(ValSelfData {v: self_val, ..slf});
if slf.is_owned {
add_clean(bcx, self_val, slf.t);
}
}
_ => {}
Some(slf) => {
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, slf.v, slf.t);
}
}
_ => {}
}

for uint::range(0, arg_tys.len()) |arg_n| {
Expand Down
33 changes: 28 additions & 5 deletions src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
_ => {}
Expand Down Expand Up @@ -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 },
Expand Down Expand Up @@ -720,16 +723,18 @@ 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>,
autoref_arg: AutorefArg) -> Result {
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)));
Expand Down Expand Up @@ -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.
Expand All @@ -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",
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
})
}
}
Expand Down Expand Up @@ -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
})
}
}
Expand Down Expand Up @@ -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) */
})
};
Expand Down
11 changes: 3 additions & 8 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 changes: 25 additions & 0 deletions src/test/run-pass/issue-5321-immediates-with-bare-self.rs
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit 61dc776

Please sign in to comment.