Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add compiler error for using Result with init #1024

Merged
merged 1 commit into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, E> 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<Result<T, E>, 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 {
Expand Down Expand Up @@ -243,10 +236,23 @@ fn init_method_wrapper(
return_type.span(),
"Method marked with #[handle_result] should return Result<T, E> (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);
near_sdk::env::state_write(&contract);
}),
}
}

static RESULT_DEPRECATED_MESSAGE: &str = "\
Serializing Result<T, E> 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<Result<T, E>, near_sdk::Abort>.";
17 changes: 17 additions & 0 deletions near-sdk-macros/src/core_impl/code_generator/item_impl_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self, &'static str> { }
};
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<T, E> 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<Result<T, E>, 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();
Expand Down
Loading