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

Add final Clippy lints #704

Merged
merged 8 commits into from
Dec 13, 2023
Merged

Conversation

Xanewok
Copy link
Contributor

@Xanewok Xanewok commented Dec 11, 2023

Final Clippy part of #155

Lints

From the additional lint list mentioned by @OmarTawfik:

  • Cargo - added everything, except the duplicate packages lint, as this is not fixable and we should strive to periodically do that ourselves. In any case, it's not something we should lint against and deny in CI
  • Restriction:
    • clippy::same_name_method - sounds useful but std traits are covered already by should_implement_trait and this fires on wrapper functions/traits; only 4 occurences in our codebase are intentional wrappers
    • clippy::allow_attributes_without_reason - requires a nightly rustc feature
    • clippy::self_named_module_files - forcing mod.rs onto users seems backwards, as that's one of the key issues addressed for Rust 2018 in terms of module/file path ergonomics, see https://dev-doc.rust-lang.org/stable/edition-guide/rust-2018/path-changes.html#no-more-modrs for more context
    • clippy::format_push_string - alternative proposed is fallible, whereas the "offending" code is infallible, not enough value IMO
    • clippy::str_to_string - will be better fixed with implicit_clone once we bump Rust to 1.7{3,4} with a new Clippy that has less false positives
    • clippy::wildcard_enum_match_arm - we already have match_wildcard_for_single_variants + can have more false positives
  • Nursery:
    • clippy::use_self - unstable, false positives
    • clippy::collection_is_never_read ✅ added
    • clippy::equatable_if_let ✅ added
    • clippy::useless_let_if_seq ✅ added

Panicking

The remaining items from #155 are about panicking in N-API-exposed crate.

Unfortunately, there is no way to guarantee or more broadly verify that certain code paths don't panic, as rustc only compiles a single crate at a time and panicking is not encoded in the type system. We could brainstorm how we can make this more resilient on the Rust side but that requires more data (maybe we could plug in Sentry for the Rust side of VSCode extension?) and a more careful thinking rather than trying to tackle this as part of the "Lint Rust code" item.

This can be expressed more cleanly using safe code.

Done when trying to limit unwraps/panics in the code but this should be
done as a separate PR/push.
@Xanewok Xanewok requested a review from a team as a code owner December 11, 2023 17:39
Copy link

changeset-bot bot commented Dec 11, 2023

⚠️ No Changeset found

Latest commit: 5faa20a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@@ -30,4 +33,8 @@ rustflags = [
"-Aclippy::module_name_repetitions", # It seems we prefer it this way; we'd need to discuss that
"-Aclippy::must_use_candidate", # Overzealous, we'd have to `[must_use]` a lot of things
"-Aclippy::redundant_closure_for_method_calls", # Not always clearer, let's not pepper `allow`s whenever needed
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we already did a great push in Q4 with linting/code quality, so I'm not suggesting we spend more time on this. However, I think there are a few things remaining in #155 so I would like to keep it open for now. If you agree, we can unassign it and push it out of this sprint, or split the issue:

  • panics: while we cannot prevent it 100%, especially in depenedencies, we can still prevent the majority of it (panic/unwrap/expect/etc...) in our code, which I think is more likely to have panics. I would like to try turning it on just in outputs/cargo/crate/.cargo/config.toml and outputs/npm/crate/.cargo/config.toml. The rest of the codebase is internal, and panicing there is fine.
  • Not sure if we reviewed allowed-by-default already for anything useful?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suggest separating panics out, because the core issue here that we want to adress is not just about enabling select lints and fixing the code.

Rather, it's a more conscious effort to minimize panics on Rust side when used from the TS/client side, which would need more involved setup e.g. running the node with the additional flags (NomicFoundation/hardhat-vscode#523 (comment)), probably collecting the crash reports from Sentry, adding further soak/regression tests and the like, since it's impossible to statically guarantee that certain code paths are (reasonably) panic-free.

Copy link
Collaborator

@OmarTawfik OmarTawfik left a comment

Choose a reason for hiding this comment

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

LGTM! Left a couple of suggestions

Unfortunately, we can't turn it on because it has false positives that
suggest a code that fails to compile, i.e.
```rust
enum Errors<'err> {
    #[error("An item with the name '{0}' already exists.")]
    ExistingItem(&'err Identifier),
    #[error("A variant referencing '{0}' already exists.")]
    ExistingVariant(&'err Identifier),
    #[error("An expression with the name '{0}' already exists.")]
    ExistingExpression(&'err Identifier),
}
```

suggests to remove the `'err` but it's impossible to define the enum
using the elided lifetime, i.e. `enum Errors<'_>`.

See rust-lang/rust#117965 for the existing bug report.
The first one is enabled in the `rustc` itself and vendored-in tools:
`unused_lifetimes`. It makes sense to warn against it by default and
pepper allows or change the code such that it's used, e.g. with
PhantomData.

The second one will be already uplifted to `dead_code` (which is
warn-by-default) but since we're warning against some lints, it can't
hurt.
@Xanewok
Copy link
Contributor Author

Xanewok commented Dec 12, 2023

Not sure if we reviewed allowed-by-default already for anything useful?

I've added few more from the list in c721b9f, 9f6733e, and 5faa20a. The rest is either:

  • guarded by other tools (variant_size_differences - clippy has large_enum_variant enabled by default, same with trivial_casts; or unused_import_braces handled by Rustfmt),
  • pedantic/noisy (unused_results is better handled by explicit must_use markers, unused_qualifications is purely style noise)
  • edition-related, which doesn't apply (rust_2021_* are already irrelevant, since we're in Rust 2021, unsafe_op_in_unsafe_fn will warn in Rust 2024 but we don't have nor will have unsafe fns ourselves quite likely anyway, absolute_paths_not_starting_with_crate or macro_use_extern_crate is for Rust 2015 or irrelevant; keyword_idents could only trigger against gen idents in our case, very niche)
  • historical (a bit similar to above, box_pointers is invalid since there are no built-in boxes nowadays, missing_{copy,debug}_implementations is not always desirable and Clippy suggests trivial Copy impls as well)
  • unstable (e.g. unnameable_types, must_not_suspend, fuzzy_provenance_casts, multiple_supertrait_upcastable)
  • restriction-like lints that are neutral (let_underscore_drop is very common and idiomatic, non_ascii_idents seem harmless/unnecessarily restrictive to additionally warn against them?)
  • have false-positives (single_use_lifetimes; it's better to rely on rustc to decide what's stable enough to be warn-by-default)
  • exotic/niche/unapplicable (ffi_unwind_calls, missing_abi, pointer_structural_match, non_exhaustive_omitted_patterns goes exactly against the idea of non_exhaustive in the first place and can break our code without our interaction, so better to check periodically ourselves)

Some crates have prided themselves at some point as being #![deny(unsafe_code)] but seeing as we're exposing our API to JS-land, I think that's impossible/unreasonable. Maybe in some select crates/when slang_napi_interfaces feature is disabled?

Also missing_docs would be nice to enable but again, this probably deserves a separate "let's document all of our public API" push and can be enabled then; we should fix some of the clippy::missing_*_doc instances then as well. Let's punt that.

Other than that, I'd say we went above and beyond and did our due dilligence here and as part of the #155 in general and the rustc/Cargo/Clippy lint list should be now exhaustive (I know I am exhausted!).

@OmarTawfik could I get a rubber stamp on the rustc lints as well, as part of this PR?

Copy link
Collaborator

@OmarTawfik OmarTawfik 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! Thank you for the push on this.

I created #707 and #708 based on your suggestions above.

@Xanewok
Copy link
Contributor Author

Xanewok commented Dec 13, 2023

Awesome! Thank you for your reviews on this ❤️

@Xanewok Xanewok added this pull request to the merge queue Dec 13, 2023
Merged via the queue into NomicFoundation:main with commit 1e3ef7a Dec 13, 2023
1 check passed
@Xanewok Xanewok deleted the clippy-final-fixes branch December 13, 2023 09:19
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.

None yet

2 participants