From d13856695fd36a59de5634d6e6812bab21e418b8 Mon Sep 17 00:00:00 2001 From: Agost Biro Date: Mon, 19 Jun 2023 20:21:56 +0200 Subject: [PATCH] fix: add compiler error for using Result with init fixes #926 --- .../code_generator/impl_item_method_info.rs | 24 ++++++++++++------- .../code_generator/item_impl_info.rs | 17 +++++++++++++ 2 files changed, 32 insertions(+), 9 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 cc247672e..c0aade990 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 @@ -154,15 +154,8 @@ impl ImplItemMethodInfo { .to_compile_error(); } ReturnType::Type(_, return_type) if utils::type_is_result(return_type) => { - return syn::Error::new( - return_type.span(), - "Serializing Result has been deprecated. Consider marking your method \ - with #[handle_result] if the second generic represents a panicable error or \ - replacing Result with another two type sum enum otherwise. If you really want \ - to keep the legacy behavior, mark the method with #[handle_result] and make \ - it return Result, near_sdk::Abort>.", - ) - .to_compile_error(); + return syn::Error::new(return_type.span(), RESULT_DEPRECATED_MESSAGE) + .to_compile_error(); } ReturnType::Type(_, _) => { let value_ser = match result_serializer { @@ -243,6 +236,12 @@ fn init_method_wrapper( return_type.span(), "Method marked with #[handle_result] should return Result (where E implements FunctionError).", )), + ReturnType::Type(_, return_type) if utils::type_is_result(return_type) => { + Err(syn::Error::new( + return_type.span(), + RESULT_DEPRECATED_MESSAGE + )) + } ReturnType::Type(_, _) => Ok(quote! { #state_check let contract = #struct_type::#ident(#arg_list); @@ -250,3 +249,10 @@ fn init_method_wrapper( }), } } + +static RESULT_DEPRECATED_MESSAGE: &str = "\ +Serializing Result has been deprecated. Consider marking your method \ +with #[handle_result] if the second generic represents a panicable error or \ +replacing Result with another two type sum enum otherwise. If you really want \ +to keep the legacy behavior, mark the method with #[handle_result] and make \ +it return Result, near_sdk::Abort>."; 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 b2c6fefd4..602feca17 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 @@ -786,6 +786,23 @@ mod tests { assert_eq!(expected.to_string(), actual.to_string()); } + #[test] + fn init_result_without_handle_result() { + let impl_type: Type = syn::parse_str("Hello").unwrap(); + let mut method: ImplItemMethod = parse_quote! { + #[init] + pub fn new() -> Result { } + }; + let method_info = ImplItemMethodInfo::new(&mut method, false, impl_type).unwrap().unwrap(); + let actual = method_info.method_wrapper(); + let expected = quote!( + compile_error! { + "Serializing Result has been deprecated. Consider marking your method with #[handle_result] if the second generic represents a panicable error or replacing Result with another two type sum enum otherwise. If you really want to keep the legacy behavior, mark the method with #[handle_result] and make it return Result, near_sdk::Abort>." + } + ); + assert_eq!(expected.to_string(), actual.to_string()); + } + #[test] fn handle_result_init_ignore_state() { let impl_type: Type = syn::parse_str("Hello").unwrap();