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 clippy::manual_let_else at warn level to lints #10684

Merged
merged 4 commits into from
Nov 28, 2023

Conversation

Kanabenki
Copy link
Contributor

Objective

Related to #10612.

Enable the clippy::manual_let_else lint as a warning. The let else form seems more idiomatic to me than a match/if else that either match a pattern or diverge, and from the clippy doc, the lint doesn't seem to have any possible false positive.

Solution

Add the lint as warning in Cargo.toml, refactor places where the lint triggers.

@Kanabenki Kanabenki added A-Build-System Related to build systems or continuous integration C-Code-Quality A section of code that is hard to understand or change labels Nov 21, 2023
Copy link
Contributor

@rlidwka rlidwka left a comment

Choose a reason for hiding this comment

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

Having this lint is good, and it did simplify a lot of code. In particular, let Ok(...) are all nice changes.

I'm concerned about few cases where variable being assigned is hidden deep inside the destructuring, so it is not obvious from the first glance what it is. uuid_str being a very egregious example of this. Maybe keep old code in there, disable lint for the statement, and (if you want) open clippy bugreport for emitting bad advice.

@@ -17,9 +17,12 @@ pub(crate) fn type_uuid_derive(input: DeriveInput) -> syn::Result<TokenStream> {
continue;
};

let uuid_str = match &name_value.value {
Copy link
Contributor

Choose a reason for hiding this comment

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

This expression became much less readable imho.

uuid_str is hidden inside a lot of syntax, and it is not immediately clear that it is the value being assigned.

Maybe disable lint just for this one line, or rewrite it to let uuid_str = if (...) {} else {} statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted this one, but for some reason the allow attribute only works when applied on the upper block level, not on the expression itself 😕

VertexFormat::Float32x3,
))
}
let VertexAttributeValues::Float32x3(positions) =
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, kind of

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While I agree for the other since matched value was quite deep in the pattern, here I think that while it introduce a bit of indentation to read the binded variable, it is still clearer than the match version ?

Copy link
Contributor

Choose a reason for hiding this comment

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

not sure about this one, do as you like

Copy link
Contributor

@rlidwka rlidwka Nov 22, 2023

Choose a reason for hiding this comment

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

I guess my problem is with one overly complex statement:

let VertexAttributeValues::Float32x3(positions) =
    mesh.attribute(Mesh::ATTRIBUTE_POSITION).ok_or(
        GenerateTangentsError::MissingVertexAttribute(Mesh::ATTRIBUTE_POSITION.name),
    )?
else {
    return Err(GenerateTangentsError::InvalidVertexAttributeFormat(
        Mesh::ATTRIBUTE_POSITION.name,
        VertexFormat::Float32x3,
    ));
};

Breaking it into multiple simpler statements might be more readable (here, I'm creating attribute variable for this purpose):

let attribute = mesh.attribute(Mesh::ATTRIBUTE_POSITION).ok_or(
    GenerateTangentsError::MissingVertexAttribute(Mesh::ATTRIBUTE_POSITION.name),
)?;
let VertexAttributeValues::Float32x3(positions) = attribute else {
    return Err(GenerateTangentsError::InvalidVertexAttributeFormat(
        Mesh::ATTRIBUTE_POSITION.name,
        VertexFormat::Float32x3,
    ));
};

edit: that's called "expression complexity", I've just found a nice article about it:
https://grugbrain.dev/#grug-on-expression-complexity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, done 🙂

Copy link
Member

@JoJoJet JoJoJet left a comment

Choose a reason for hiding this comment

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

I think you should follow rlidwka's suggestion for the vertex attributes, but otherwise LGTM.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Nov 27, 2023
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Nov 28, 2023
Merged via the queue into bevyengine:main with commit 0e9f6e9 Nov 28, 2023
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Build-System Related to build systems or continuous integration C-Code-Quality A section of code that is hard to understand or change S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants