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| {
llself: ValueRef,
self_ty: ty::t,
self_mode: ty::SelfMode,
+ explicit_self: ast::explicit_self_
}
pub enum CalleeData {
// 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);
}
_ => {}
trans_arg_expr(bcx,
arg_tys[i],
ty::ByCopy,
+ ast::sty_static,
*arg_expr,
&mut temp_cleanups,
if i == last { ret_flag } else { None },
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>,
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)));
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.
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",
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)
}
let result = trans_arg_expr(bcx,
self_ty,
mentry.self_mode,
+ mentry.explicit_self,
base,
&mut temp_cleanups,
None,
llself: val,
self_ty: node_id_type(bcx, this.id),
self_mode: mentry.self_mode,
+ explicit_self: mentry.explicit_self
})
}
}
llself: llself_val,
self_ty: node_id_type(bcx, base.id),
self_mode: mentry.self_mode,
+ explicit_self: mentry.explicit_self
})
}
}
llself: llself,
self_ty: ty::mk_opaque_box(bcx.tcx()),
self_mode: self_mode,
+ explicit_self: explicit_self
/* XXX: Some(llbox) */
})
};
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
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,
- }
-}