From 05d68777377f36472d3989dfca5bd8c567cd8965 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 28 Oct 2021 14:25:18 +0100 Subject: [PATCH 1/2] fix: Disallow omitting a return value for init methods --- .../code_generator/impl_item_method_info.rs | 8 ++++++++ .../core_impl/code_generator/item_impl_info.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs b/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs index b73f296e1..fa6d87b1f 100644 --- a/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs +++ b/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs @@ -78,6 +78,10 @@ impl ImplItemMethodInfo { quote! {} }; let body = if matches!(method_type, &MethodType::Init) { + if matches!(returns, ReturnType::Default) { + return syn::Error::new(ident.span(), "Init methods must return the contract state") + .to_compile_error(); + } quote! { if near_sdk::env::state_exists() { near_sdk::env::panic_str("The contract has already been initialized"); @@ -86,6 +90,10 @@ impl ImplItemMethodInfo { near_sdk::env::state_write(&contract); } } else if matches!(method_type, &MethodType::InitIgnoreState) { + if matches!(returns, ReturnType::Default) { + return syn::Error::new(ident.span(), "Init methods must return the contract state") + .to_compile_error(); + } quote! { let contract = #struct_type::#ident(#arg_list); near_sdk::env::state_write(&contract); diff --git a/near-sdk-macros/src/core_impl/code_generator/item_impl_info.rs b/near-sdk-macros/src/core_impl/code_generator/item_impl_info.rs index fc461f291..21ae4a55a 100644 --- a/near-sdk-macros/src/core_impl/code_generator/item_impl_info.rs +++ b/near-sdk-macros/src/core_impl/code_generator/item_impl_info.rs @@ -467,6 +467,21 @@ mod tests { assert_eq!(expected.to_string(), actual.to_string()); } + #[test] + fn init_no_return() { + let impl_type: Type = syn::parse_str("Hello").unwrap(); + let mut method: ImplItemMethod = parse_quote! { + #[init] + pub fn method(k: &mut u64) { } + }; + let method_info = ImplItemMethodInfo::new(&mut method, impl_type).unwrap(); + let actual = method_info.method_wrapper(); + let expected = quote!( + compile_error! { "Init methods must return the contract state" } + ); + assert_eq!(expected.to_string(), actual.to_string()); + } + #[test] fn init_ignore_state() { let impl_type: Type = syn::parse_str("Hello").unwrap(); From 6421a54055215fd5ba2110fbe529429ac59a84f6 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 28 Oct 2021 14:36:51 +0100 Subject: [PATCH 2/2] fmt --- .../code_generator/impl_item_method_info.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs b/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs index fa6d87b1f..73db83908 100644 --- a/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs +++ b/near-sdk-macros/src/core_impl/code_generator/impl_item_method_info.rs @@ -79,8 +79,11 @@ impl ImplItemMethodInfo { }; let body = if matches!(method_type, &MethodType::Init) { if matches!(returns, ReturnType::Default) { - return syn::Error::new(ident.span(), "Init methods must return the contract state") - .to_compile_error(); + return syn::Error::new( + ident.span(), + "Init methods must return the contract state", + ) + .to_compile_error(); } quote! { if near_sdk::env::state_exists() { @@ -91,8 +94,11 @@ impl ImplItemMethodInfo { } } else if matches!(method_type, &MethodType::InitIgnoreState) { if matches!(returns, ReturnType::Default) { - return syn::Error::new(ident.span(), "Init methods must return the contract state") - .to_compile_error(); + return syn::Error::new( + ident.span(), + "Init methods must return the contract state", + ) + .to_compile_error(); } quote! { let contract = #struct_type::#ident(#arg_list);