Skip to content

Commit 61dc776

Browse files
committed
auto merge of #7410 : luqmana/rust/bare-self, r=catamorphism
Finally sorted this out. Fixes #5321, #4439, and #4850.
2 parents 927f454 + 0aa94ff commit 61dc776

File tree

6 files changed

+73
-33
lines changed

6 files changed

+73
-33
lines changed

src/librustc/middle/trans/asm.rs

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
4141
callee::trans_arg_expr(bcx,
4242
expr_ty(bcx, out),
4343
ty::ByCopy,
44+
ast::sty_static,
4445
out,
4546
&mut cleanups,
4647
None,
@@ -56,6 +57,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
5657
callee::trans_arg_expr(bcx,
5758
expr_ty(bcx, e),
5859
ty::ByCopy,
60+
ast::sty_static,
5961
e,
6062
&mut cleanups,
6163
None,
@@ -77,6 +79,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
7779
callee::trans_arg_expr(bcx,
7880
expr_ty(bcx, in),
7981
ty::ByCopy,
82+
ast::sty_static,
8083
in,
8184
&mut cleanups,
8285
None,

src/librustc/middle/trans/base.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -1680,23 +1680,15 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
16801680
let mut bcx = bcx;
16811681

16821682
match fcx.llself {
1683-
Some(slf) => {
1684-
let self_val = if slf.is_owned
1685-
&& datum::appropriate_mode(slf.t).is_by_value() {
1686-
let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t));
1687-
let alloc = alloc_ty(bcx, slf.t);
1688-
Store(bcx, tmp, alloc);
1689-
alloc
1690-
} else {
1691-
PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to())
1692-
};
1693-
1694-
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
1695-
if slf.is_owned {
1696-
add_clean(bcx, self_val, slf.t);
1697-
}
1698-
}
1699-
_ => {}
1683+
Some(slf) => {
1684+
let self_val = PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to());
1685+
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
1686+
1687+
if slf.is_owned {
1688+
add_clean(bcx, slf.v, slf.t);
1689+
}
1690+
}
1691+
_ => {}
17001692
}
17011693

17021694
for uint::range(0, arg_tys.len()) |arg_n| {

src/librustc/middle/trans/callee.rs

+28-5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct MethodData {
6363
llself: ValueRef,
6464
self_ty: ty::t,
6565
self_mode: ty::SelfMode,
66+
explicit_self: ast::explicit_self_
6667
}
6768

6869
pub enum CalleeData {
@@ -565,7 +566,8 @@ pub fn trans_call_inner(in_cx: block,
565566
// Now that the arguments have finished evaluating, we need to revoke
566567
// the cleanup for the self argument, if it exists
567568
match callee.data {
568-
Method(d) if d.self_mode == ty::ByCopy => {
569+
Method(d) if d.self_mode == ty::ByCopy ||
570+
d.explicit_self == ast::sty_value => {
569571
revoke_clean(bcx, d.llself);
570572
}
571573
_ => {}
@@ -687,6 +689,7 @@ pub fn trans_args(cx: block,
687689
trans_arg_expr(bcx,
688690
arg_tys[i],
689691
ty::ByCopy,
692+
ast::sty_static,
690693
*arg_expr,
691694
&mut temp_cleanups,
692695
if i == last { ret_flag } else { None },
@@ -720,16 +723,18 @@ pub enum AutorefArg {
720723
pub fn trans_arg_expr(bcx: block,
721724
formal_arg_ty: ty::t,
722725
self_mode: ty::SelfMode,
726+
ex_self: ast::explicit_self_,
723727
arg_expr: @ast::expr,
724728
temp_cleanups: &mut ~[ValueRef],
725729
ret_flag: Option<ValueRef>,
726730
autoref_arg: AutorefArg) -> Result {
727731
let _icx = push_ctxt("trans_arg_expr");
728732
let ccx = bcx.ccx();
729733

730-
debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \
734+
debug!("trans_arg_expr(formal_arg_ty=(%s), explicit_self=%? self_mode=%?, arg_expr=%s, \
731735
ret_flag=%?)",
732736
formal_arg_ty.repr(bcx.tcx()),
737+
ex_self,
733738
self_mode,
734739
arg_expr.repr(bcx.tcx()),
735740
ret_flag.map(|v| bcx.val_to_str(*v)));
@@ -789,8 +794,26 @@ pub fn trans_arg_expr(bcx: block,
789794
val = arg_datum.to_ref_llval(bcx);
790795
}
791796
DontAutorefArg => {
792-
match self_mode {
793-
ty::ByRef => {
797+
match (self_mode, ex_self) {
798+
(ty::ByRef, ast::sty_value) => {
799+
debug!("by value self with type %s, storing to scratch",
800+
bcx.ty_to_str(arg_datum.ty));
801+
let scratch = scratch_datum(bcx, arg_datum.ty, false);
802+
803+
arg_datum.store_to_datum(bcx,
804+
arg_expr.id,
805+
INIT,
806+
scratch);
807+
808+
// Technically, ownership of val passes to the callee.
809+
// However, we must cleanup should we fail before the
810+
// callee is actually invoked.
811+
scratch.add_clean(bcx);
812+
temp_cleanups.push(scratch.val);
813+
814+
val = scratch.to_ref_llval(bcx);
815+
}
816+
(ty::ByRef, _) => {
794817
// This assertion should really be valid, but because
795818
// the explicit self code currently passes by-ref, it
796819
// does not hold.
@@ -801,7 +824,7 @@ pub fn trans_arg_expr(bcx: block,
801824
bcx.ty_to_str(arg_datum.ty));
802825
val = arg_datum.to_ref_llval(bcx);
803826
}
804-
ty::ByCopy => {
827+
(ty::ByCopy, _) => {
805828
if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) ||
806829
arg_datum.appropriate_mode().is_by_ref() {
807830
debug!("by copy arg with type %s, storing to scratch",

src/librustc/middle/trans/meth.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,7 @@ pub fn trans_method(ccx: @mut CrateContext,
110110
debug!("calling trans_fn with self_ty %s",
111111
self_ty.repr(ccx.tcx));
112112
match method.explicit_self.node {
113-
ast::sty_value => {
114-
impl_owned_self(self_ty)
115-
}
113+
ast::sty_value => impl_owned_self(self_ty),
116114
_ => {
117115
impl_self(self_ty)
118116
}
@@ -145,6 +143,7 @@ pub fn trans_self_arg(bcx: block,
145143
let result = trans_arg_expr(bcx,
146144
self_ty,
147145
mentry.self_mode,
146+
mentry.explicit_self,
148147
base,
149148
&mut temp_cleanups,
150149
None,
@@ -231,6 +230,7 @@ pub fn trans_method_callee(bcx: block,
231230
llself: val,
232231
self_ty: node_id_type(bcx, this.id),
233232
self_mode: mentry.self_mode,
233+
explicit_self: mentry.explicit_self
234234
})
235235
}
236236
}
@@ -453,6 +453,7 @@ pub fn trans_monomorphized_callee(bcx: block,
453453
llself: llself_val,
454454
self_ty: node_id_type(bcx, base.id),
455455
self_mode: mentry.self_mode,
456+
explicit_self: mentry.explicit_self
456457
})
457458
}
458459
}
@@ -692,6 +693,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
692693
llself: llself,
693694
self_ty: ty::mk_opaque_box(bcx.tcx()),
694695
self_mode: self_mode,
696+
explicit_self: explicit_self
695697
/* XXX: Some(llbox) */
696698
})
697699
};

src/librustc/middle/typeck/check/method.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,9 @@ impl<'self> LookupContext<'self> {
976976
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty});
977977
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
978978

979-
let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self);
979+
// FIXME(#7411): We always pass self by-ref since we stuff it in the environment slot.
980+
// Eventually that should not be the case
981+
let self_mode = ty::ByRef;
980982

981983
// before we only checked whether self_ty could be a subtype
982984
// of rcvr_ty; now we actually make it so (this may cause
@@ -1242,10 +1244,3 @@ impl<'self> LookupContext<'self> {
12421244
self.tcx().sess.bug(s)
12431245
}
12441246
}
1245-
1246-
pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode {
1247-
match explicit_self {
1248-
sty_value => ty::ByCopy,
1249-
_ => ty::ByRef,
1250-
}
1251-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Fooable {
12+
fn yes(self);
13+
}
14+
15+
impl Fooable for uint {
16+
fn yes(self) {
17+
for self.times {
18+
println("yes");
19+
}
20+
}
21+
}
22+
23+
fn main() {
24+
2.yes();
25+
}

0 commit comments

Comments
 (0)