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: prohibit NEAR function generics #980

Merged
merged 12 commits into from
Jan 23, 2023
Merged

Conversation

itegulov
Copy link
Contributor

Closes #979

@itegulov
Copy link
Contributor Author

itegulov commented Nov 28, 2022

Hmm, this also prohibits lifetimes (see #974). I can make it so that this only blocks certain types of generic parameters, but honestly not sure if there is a legitimate pattern for lifetime params at all.

We are specifically asserting this behaviour though (https://github.com/near/near-sdk-rs/blob/master/near-sdk/compilation_tests/lifetime_method.rs), so maybe I am missing something. @miraclx @austinabell do you have any thoughts on this?

UPD: Let's move this conversation to #974

@@ -38,6 +38,12 @@ impl AttrSigInfo {
original_attrs: &mut Vec<Attribute>,
original_sig: &mut Signature,
) -> syn::Result<Self> {
if !original_sig.generics.params.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's maybe only do this for pub-lic functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dude, why is this method even being called for private methods 🤔

I am guessing there are two separate logic flows happening in this method: checking that there are no weird variadic async etc modifiers (that is supposed to work on both private and public functions) and processing near_bindgen stuff (only for public functions). I will refactor this.

@itegulov
Copy link
Contributor Author

Decided to leave lifetimes out of this PR for now, we can discuss this separately under #974.

This became more of a refactoring PR, but I feel like the current logic is backward from what it should be. I left async/variadic/extern checks for all impl methods (even private), but honestly not sure that is necessary. For example, an async function is compilable for wasm on its own, you just wouldn't be able to use it in any meaningful way since public functions can't be async. @austinabell you would probably have the most context on what the original intention of these checks was.

Copy link
Contributor

@miraclx miraclx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left async/variadic/extern checks for all impl methods (even private), but honestly not sure that is necessary. For example, an async function is compilable for wasm on its own, you just wouldn't be able to use it in any meaningful way since public functions can't be async.

Eh, should be fine to retain those checks.

A small side effect of the current logic (or perhaps intentional?) is we're no longer checking them for #[ext_contract] traits. And while technically, neither async traits nor C-variadic methods are stable, explicit definition of support on our end would be nice.

@@ -241,7 +241,7 @@ mod tests {
#[warn(unused)]
pub fn method(&self) { }
};
let method_info = ImplItemMethodInfo::new(&mut method, impl_type).unwrap();
let method_info = ImplItemMethodInfo::new(&mut method, false,impl_type).unwrap().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious, doesn't look like cargo-fmt acted on these..

Suggested change
let method_info = ImplItemMethodInfo::new(&mut method, false,impl_type).unwrap().unwrap();
let method_info = ImplItemMethodInfo::new(&mut method, false, impl_type).unwrap().unwrap();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's interesting. Looks like a bug, wondering if I can create a minimal reproduction.

Comment on lines +14 to +16
pub fn is_ident<T>(&self, val: T) -> T {
val
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the logic is extended to disallow const generics, lets add a case here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a separate test case so that we can check the error message (it only reports one at a time, probably because the macro errors work differently from regular compilation errors).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. should resolve this issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, resolving this issue would require doing the same refactoring in ItemImplInfo, ItemTraitInfo and potentially some other places. I think this is better done in a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, right! That's unfortunate.. combining errors doesn't apply then, since AttrSigInfo is called per-method signature. But hey, at least we get good spans 😅.

But refactoring the macro system is in order tbh.

Comment on lines +14 to +16
pub fn is_ident<T>(&self, val: T) -> T {
val
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. should resolve this issue

@itegulov itegulov merged commit 8846dab into master Jan 23, 2023
@itegulov itegulov deleted the daniyar/prohibit-generics branch January 23, 2023 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use of generics returns a confusing error
2 participants