-
Notifications
You must be signed in to change notification settings - Fork 251
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: concretize Self
references in method signatures
#1001
Conversation
7f95609
to
d7a17f8
Compare
Shouldn't this be fixed in the abi? Seems like it should be handled there and not banned. Witgen handles it. |
Well, the issue here is mostly that the intermediate code generated that eventually generates the ABI derives the schema for a type from a method call that is generic over the type. Specifically a line that does: gen.subschema_for::<T>(); and in the case where At the moment, the example code just fails on master (See #972). This patch fixes that to make sure it both compiles and has ABI generated for the appropriate type. An alternative as mentioned in #972 would just be to warn / fail with a useful error nudging users to use concrete types, but I wanted to submit this first so we know it's possible and not just jump head-first into disallowing 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.
LGTM, just a couple of nitpicks. This is a great fix for the current major version of SDK, but I wonder if we should still explore whether banning Self
makes sense in 5.0. Not because this PR does an unsatisfactory job but rather because it seems like a potentially harmful practice as was pointed out here. I can create an issue if you agree that it is worth exploring.
} | ||
|
||
pub fn sanitize_self(typ: &Type, replace_with: &TokenStream2) -> syn::Result<Type> { | ||
syn::parse2(_sanitize_self(quote! { #typ }, replace_with)).map_err(|original| { |
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.
Sanitizing TokenStream
instead of Type
is a nice trick. I remember trying to sanitize Self
in the past, and it required so much boilerplate to traverse all Type
variants.
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, nightmarish 😨
Yup, Sounds good to me! |
Done: #1005 |
Hey Team, #[ext_contract(ext_my_contract)]
pub trait MyContract {
#[init]
fn new() -> Self;
} as it expands into pub trait MyContract {
fn new() -> MyContract;
}
pub mod ext_my_contract {
// ...
}
|
Resolves: #972, #1000.
This patch replaces any
Self
references in method signatures with the concrete type of theimpl
block itself.Example:
the impl block is transformed into:
this transformation is maintained regardless of type complexity or nesting level.
Worth noting, this does not transform
Self
references in generic bounds. But they're going to be prohibited following #980 anyway. So I left it out.