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

codegen: Add codegen error #841

Merged
merged 13 commits into from
Mar 3, 2023
Merged

codegen: Add codegen error #841

merged 13 commits into from
Mar 3, 2023

Conversation

lexnv
Copy link
Collaborator

@lexnv lexnv commented Feb 28, 2023

This PR adds a specific CodegenError to ensure that codegen functions can be used outside of proc_macros.

Previously, the codegen was using the proc-macro-error which panicked upon errors when used from subxt/cli.

Closes: #740.

@niklasad1 niklasad1 self-requested a review February 28, 2023 14:25
codegen/src/types/mod.rs Outdated Show resolved Hide resolved
Comment on lines 50 to 55
let mut storage_fns = Vec::new();
for entry in &storage.entries {
let storage_fn =
generate_storage_entry_fns(metadata, type_gen, pallet, entry, crate_path)?;
storage_fns.push(storage_fn);
}
Copy link
Collaborator

@jsdw jsdw Feb 28, 2023

Choose a reason for hiding this comment

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

I guess some of these bits could have been done with a .collect::<Result<Vec<_>,_>() style thing (like you did ielsewhere) instead of changing to loops, but I'm happy with either really!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Have reverted to using collect::<...> everywhere, that sounds pretty cool!

One strange thing about it, the compiler seems to be quite strict in resolving collect::<Result<Vec<_>, _>.
If the Error is not explicitly typed in the closure, then the scope in which the compiler finds Error type is not increased. Such is the case where we use ? and the error could be deduced from the function's return type.
This leads to some places where the CodegenError needs to be typed next to collect.

Copy link
Collaborator

@jsdw jsdw left a comment

Choose a reason for hiding this comment

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

Looks great to me! I have a feeling that this will fix some other issue I ran into a while back with codegen stuff too, but off the top of my head I can't remember what :)

match runtime_api {
Ok(runtime_api) => println!("{runtime_api}"),
Err(e) => {
// `Span` cannot be sent between threads.
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this comment, is that the reason why you can't propagate the error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The CodegenError includes a Span in some variants that can be used to hint at better compile errors.
The color_eyre does impose StdError + Send + Sync on the returned error, to circumvent that I've just printed the error message in red. I'll update the comment :D

calls
} else {
return quote!()
let Some(call) = &pallet.calls else {
Copy link
Member

Choose a reason for hiding this comment

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

this syntax is neat, I probably need to add this to my bank as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep its a really cool syntax, tho I can see two small downsides:

  • it cannot capture the error, that should be totally fine with Options tho
  • rustfmt doesn't seem to work with this syntax, seems that anything in the else { } block is ignored for formatting

Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting on the latter point; I guess they will fix it eventually and we'll have to do some reformatting everywhere!

@@ -211,35 +271,36 @@ impl RuntimeGenerator {

let metadata_hash = get_metadata_per_pallet_hash(&self.metadata, &pallet_names);

let modules = pallets_with_mod_names.iter().map(|(pallet, mod_name)| {
let mut modules = Vec::new();
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need to use a Vec here as as quote is implemented for iterators as well but it's fine either way

codegen/src/api/mod.rs Outdated Show resolved Hide resolved
Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

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

nice, LGTM

@lexnv
Copy link
Collaborator Author

lexnv commented Mar 1, 2023

Have picked the collect::<Result<..>> as the way to go for loops.
While at it, have also improved the error messages we report back to the user.
This should give a small boost in understanding what the problem is (mostly regarding invalid metadata V14 formats).
Thanks for the feedback!

InvalidModule(Span),
/// Expected named or unnamed fields.
#[error("Fields should either be all named or all unnamed, make sure you are providing a valid metadata V14: {0}")]
InvalidFields(String),
Copy link
Collaborator

Choose a reason for hiding this comment

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

The error messages look good to me overall :)

@lexnv lexnv merged commit a7b45ef into master Mar 3, 2023
@lexnv lexnv deleted the lexnv/impr_codegen_err branch March 3, 2023 17:57
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.

improve message when generating from corrupted scale file
3 participants