export_service! macro should correctly name records wrapped in `ManualReply`s
Describe the bug
The candid export service doesn't correctly handle canister methods with a return type of ManualReply. Instead of exporting the record type in the canister method signature, it exports a generic ManualReply type. Subsequent ManualReplys will be given incrementing names of format ManualReply_n where n increases for the amount of records.
To Reproduce Steps to reproduce the behavior:
-
Create a Rust canister with the following contents:
use ic_cdk::api::call::{self, ManualReply}; #[derive(candid::CandidType)] struct User { id: String, } #[ic_cdk_macros::query] #[candid::candid_method(query)] async fn method() -> ManualReply<User> { let user = User { id: "a".to_string(), }; call::reply((user,)); ManualReply::empty() } candid::export_service!(); #[ic_cdk_macros::query(name = "__get_candid_interface_tmp_hack")] fn export_candid() -> String { __export_service() } #[cfg(test)] mod tests { use super::*; #[test] fn write_candid_to_disk() { std::fs::write("test.did", export_candid()).unwrap(); } }Full example can be found at https://github.com/dansteren/candid_export_bug
-
Run
cargo test -
Inspect the generated candid file at canisters/tests/test.did
-
Notice that it contains a type
ManualReplywhich doesn't have the same name as theUserstruct in canisters/test/src/lib.rstype ManualReply = record { id : text }; service : { method : () -> (ManualReply) query }
Expected behavior
The candid file should name the user type User not ManualReply. I.e.
type User = record { id : text };
service : { method : () -> (User) query }
Screenshots N/A
Platform
- OS: Ubuntu 22.04
- Rust Version: rustc 1.63.0 (4b91a6ea7 2022-08-08)
- DFX Version: 0.11.0
- Candid Crate Version: 0.7.4
Additional context The problem occurs regardless of whether the function is a Query or an Update. The problem does not occur if another function also returns that type (See https://github.com/dansteren/candid_export_bug/tree/include_type_in_other_function_sig).
PS: Your Bug issue template isn't working so I was unable to apply the Bug label.
Have you tried this: https://github.com/dfinity/cdk-rs/blob/main/src/ic-cdk/src/api/call.rs#L636
I think @chenyan-dfinity was referring to #[query(manual_reply = true)] and #[update(manual_reply = true)]
I use these and my exported interface contains multiple ManualReply types.
However, it's not a problem for me because I'm not writing the exported service to disk; I'm comparing it with a hand-written file that's already on disk using service_compatible.
@chenyan-dfinity I think I just accidentally left that attribute out somehow when making this issue, but yes, I am also using #[ic_cdk_macros::query(manual_reply = true)] (See https://github.com/dansteren/candid_export_bug/blob/main/canisters/test/src/lib.rs#L8).
This does not fix the problem. The candid file still lists the type as ManualReply instead of User.
This seems to still be an issue in 0.9.0-beta.2. I just bumped all the dependencies in my reproducible to the latest available beta versions and am still experiencing this issue.