-
Notifications
You must be signed in to change notification settings - Fork 172
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 errors with generics when using the proc macro #433
Conversation
hmm suppose I want to have this: // Hash needs some bounds and lifetime but to simplify the point.
#[rpc(server, namespace = "state")]
pub trait Rpc<Hash> {
/// Async method call example.
#[method(name = "getPairs")]
async fn storage_pairs(&self, hash: Hash) -> Vec<usize>;
}
pub struct RpcServerImpl;
#[async_trait]
impl RpcServer<()> for RpcServerImpl {
async fn storage_pairs(&self, _hash: ()) -> Vec<usize> {
vec![1, 2, 3, 4]
}
} That won't work right? Otherwise, please show an example how to use this 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code looks good but it's not quite want I had in mind but I guess a step in the right direction?
see my previous comment
fn handle_register_result(tokens: TokenStream2) -> TokenStream2 { | ||
quote! {{ | ||
let res = #tokens; | ||
debug_assert!(res.is_ok(), "RPC macro method names should never conflict, this is a bug, please report it."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make this a debug-only assert? Isn't it worth the cost to catch these violations in all builds?
Also, I'd clarify that the bug is in the user code, in not jsonrpsee
:
debug_assert!(res.is_ok(), "RPC macro method names should never conflict, this is a bug, please report it."); | |
debug_assert!(res.is_ok(), "RPC names must never conflict, please ensure all method names are unique."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just related to jsonrpsee proc macros
that actually ensures that each method is unique so the user should not have to do it, it would just be a compile time error then.
But this is just assertion if we introduce any bugs in that logic and I think Maciej doesn't like overhead of expect
in release builds :P
Alternatively we could just add a test for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively we could just add a test for this
How would that work? Wouldn't it have to be in the users' code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it has to be in users code but we could just do a UI test:
#[rpc(client, server, namespace = "state")]
pub trait Rpc {
/// Async method call example.
#[method(name = "getPairs")]
async fn storage_pairs(&self, prefix: usize, hash: Option<u128>) -> Vec<usize>;
/// Async method call example.
#[method(name = "getPairs")]
async fn dup(&self, prefix: usize, hash: Option<u128>) -> Vec<usize>;
}
pub struct RpcServerImpl;
#[async_trait]
impl RpcServer for RpcServerImpl {
async fn storage_pairs(&self, _prefix: usize, _hash: Option<u128>) -> Vec<usize> {
vec![1, 2, 3, 4]
}
async fn dup(&self, _prefix: usize, _hash: Option<u128>) -> Vec<usize> {
vec![1, 2, 3, 4]
}
}
expect error: error: "state_getPairs" is already defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already got this: https://github.com/paritytech/jsonrpsee/blob/master/proc-macros/tests/ui/incorrect/rpc/rpc_name_conflict.rs so I merged this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks sane to me, and fairly simple/easy to adjust if needed going forwards!
The
inner
closure was causing issues when parent types were using generics, since those types aren't usable inside closures (unless said closure would be made to be generic).Since all we used the closure for is collect all errors to
.expect
on them at the end, this PR strips the closure altogether, and instead handles errors in place: ignoring them and panicking in debug builds if the macro somehow were to produce conflicting names.