11use crate :: {
2- attribute:: pass_through_attr_to_gen_code, map_type:: map_type, syn_ext:: ty_to_safe_ident_str,
2+ attribute:: pass_through_attr_to_gen_code,
3+ map_type:: map_type,
4+ syn_ext:: { fn_arg_type_validate_no_mut, ty_to_safe_ident_str} ,
35} ;
46use itertools:: MultiUnzip ;
57use proc_macro2:: TokenStream as TokenStream2 ;
@@ -63,6 +65,11 @@ pub fn derive_pub_fn(
6365 // signature_payload of type Bytes (32 size), to be a Hash.
6466 let allow_hash = ident == "__check_auth" && i == 0 ;
6567
68+ // Error if the type of the fn arg is mutable.
69+ if let Err ( e) = fn_arg_type_validate_no_mut ( & pat_ty. ty ) {
70+ errors. push ( e) ;
71+ }
72+
6673 // Error if the type of the fn is not mappable.
6774 if let Err ( e) = map_type ( & pat_ty. ty , true , allow_hash) {
6875 errors. push ( e) ;
@@ -84,20 +91,7 @@ pub fn derive_pub_fn(
8491 let passthrough_call = quote ! { #ident } ;
8592
8693 let call_prefix = match * pat_ty. ty {
87- // Disallow &mut because it is semantically confusing for a contract function
88- // to receive an input that would mutate a value coming from outside the
89- // program.
90- Type :: Reference ( TypeReference { mutability : Some ( _) , .. } ) => {
91- errors. push ( syn:: Error :: new (
92- pat_ty. ty . span ( ) ,
93- "mutable references (&mut) are not supported in contract function parameters, use immutable references (&) instead" ,
94- ) ) ;
95- quote ! ( & )
96- }
97- // Allow & because it is convenient to be able to define contract functions
98- // with borrowed parameters.
99- Type :: Reference ( TypeReference { mutability : None , .. } ) => quote ! ( & ) ,
100- // Any other parameter type doesn't need a call prefix.
94+ Type :: Reference ( TypeReference { .. } ) => quote ! ( & ) ,
10195 _ => quote ! ( ) ,
10296 } ;
10397 let call = quote ! {
0 commit comments