@@ -63,6 +63,7 @@ pub struct MethodData {
63
63
llself : ValueRef ,
64
64
self_ty : ty:: t ,
65
65
self_mode : ty:: SelfMode ,
66
+ explicit_self : ast:: explicit_self_
66
67
}
67
68
68
69
pub enum CalleeData {
@@ -565,7 +566,8 @@ pub fn trans_call_inner(in_cx: block,
565
566
// Now that the arguments have finished evaluating, we need to revoke
566
567
// the cleanup for the self argument, if it exists
567
568
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 => {
569
571
revoke_clean ( bcx, d. llself ) ;
570
572
}
571
573
_ => { }
@@ -687,6 +689,7 @@ pub fn trans_args(cx: block,
687
689
trans_arg_expr( bcx,
688
690
arg_tys[ i] ,
689
691
ty:: ByCopy ,
692
+ ast:: sty_static,
690
693
* arg_expr,
691
694
& mut temp_cleanups,
692
695
if i == last { ret_flag } else { None } ,
@@ -720,16 +723,18 @@ pub enum AutorefArg {
720
723
pub fn trans_arg_expr( bcx: block,
721
724
formal_arg_ty: ty:: t,
722
725
self_mode: ty:: SelfMode ,
726
+ ex_self: ast:: explicit_self_,
723
727
arg_expr: @ast:: expr,
724
728
temp_cleanups: & mut ~[ ValueRef ] ,
725
729
ret_flag: Option < ValueRef > ,
726
730
autoref_arg: AutorefArg ) -> Result {
727
731
let _icx = push_ctxt( "trans_arg_expr" ) ;
728
732
let ccx = bcx. ccx( ) ;
729
733
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, \
731
735
ret_flag=%?)",
732
736
formal_arg_ty. repr( bcx. tcx( ) ) ,
737
+ ex_self,
733
738
self_mode,
734
739
arg_expr. repr( bcx. tcx( ) ) ,
735
740
ret_flag. map( |v| bcx. val_to_str( * v) ) ) ;
@@ -789,8 +794,26 @@ pub fn trans_arg_expr(bcx: block,
789
794
val = arg_datum. to_ref_llval ( bcx) ;
790
795
}
791
796
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 , _) => {
794
817
// This assertion should really be valid, but because
795
818
// the explicit self code currently passes by-ref, it
796
819
// does not hold.
@@ -801,7 +824,7 @@ pub fn trans_arg_expr(bcx: block,
801
824
bcx. ty_to_str( arg_datum. ty) ) ;
802
825
val = arg_datum. to_ref_llval ( bcx) ;
803
826
}
804
- ty:: ByCopy => {
827
+ ( ty:: ByCopy , _ ) => {
805
828
if ty:: type_needs_drop ( bcx. tcx ( ) , arg_datum. ty ) ||
806
829
arg_datum. appropriate_mode ( ) . is_by_ref ( ) {
807
830
debug ! ( "by copy arg with type %s, storing to scratch" ,
0 commit comments