@@ -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
6869pub 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 {
720723pub 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" ,
0 commit comments