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 lint trait_associated_const_added #875

Merged
merged 9 commits into from
Aug 25, 2024
Merged

Conversation

mrnossiom
Copy link
Contributor

@mrnossiom mrnossiom commented Aug 20, 2024

Lint for "non-sealed trait added associated constant without default value"

See #870

This is my first semver-checks lint. I'm unsure how to proceed to check how a default value has disappeared for a given associated constant.

I think I need to check if the default value of the assoc const is still null for the current crate. Looking at other lints, I should be able to do that with fold and filter?

Could someone provide a little guidance, so I can better understand how diff queries works?

Thanks

@obi1kenobi
Copy link
Owner

a default value has disappeared for a given associated constant

Just to make sure, is this lint looking for "the const's default has disappeared" or "there's a new const that didn't exist before, and doesn't have a default"?

Your query is very close either way, and I'll be happy to point you in the right direction.

There are also a couple of filter operators that might be useful: "is_null" and "is_not_null", which you can use like this:

property @filter(op: "is_null")

@mrnossiom
Copy link
Contributor Author

mrnossiom commented Aug 20, 2024

Lint is looking for "there's a new const that didn't exist before, and doesn't have a default".

How can I check the addition of an assoc const?

@obi1kenobi
Copy link
Owner

Try framing the query like this:

  • in the new version, there exists a const without a default
  • the old version has no const by that name on that trait

For the second part: "X does not exist" is a @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) clause sequence on the edge that produces the X. We specifically want to say "the same trait exists but the named const doesn't exist" so be mindful of where those clauses go. This is important because we don't want the lint to trigger if the trait is new and didn't exist before — adding a new trait with a const is not a problem.

I think you already have the first part just about working in your PR.

So minimal changes needed — you're super close.

@obi1kenobi
Copy link
Owner

Lmk if you'd like more in-depth suggestions than I gave in my last post!

No pressure to move this forward, it's totally fine if you had other things to do etc. I just want to make sure you aren't blocked because I did a bad job of explaining stuff :)

Feel free to ping me with more questions anytime!

@mrnossiom
Copy link
Contributor Author

Just didn't have time these last days. Simply switch the query parts made the tests pass with logical results.

@mrnossiom mrnossiom marked this pull request as ready for review August 23, 2024 17:46
@obi1kenobi
Copy link
Owner

obi1kenobi commented Aug 23, 2024

Nice! The new query looks good.

A few remaining things to look into:

  • Figure out the remaining TODOs in the query file.
  • Consider using @filter(op: "is_null") and @filter(op: "is_not_null") instead of @filter(op: "=", value: ["$null"]). They both work, but the former is a bit more idiomatic.
  • Add some more test cases, making sure that the lint always triggers when expected and never triggers when not expected. For example:
    • if the trait was previously sealed, adding a const doesn't trigger the lint
    • if the trait was not previously sealed, sealing it in the new version + adding a const still triggers the lint
    • adding a const with a default value doesn't trigger the lint, regardless of whether the trait was sealed
    • if the trait already had at least one const, adding a second one still triggers the lint when appropriate

@mrnossiom
Copy link
Contributor Author

I don't know where to look for the reference_link.

Copy link
Owner

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

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

The cargo SemVer reference, and the API evolution RFC 1105, are the two authoritative documents on SemVer in Rust.

I suggested a link to the "trait added non-defaulted item" section, which encompasses this lint.

src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
@obi1kenobi
Copy link
Owner

If a trait is being annoying in tests and you want to make it not object-safe when it doesn't have a const already, just make a method that returns -> Self. That also makes it not object-safe, and adding a const to it won't cause the extra SemVer breakage.

@mrnossiom
Copy link
Contributor Author

I would love to be able to bless tests

@mrnossiom
Copy link
Contributor Author

mrnossiom commented Aug 23, 2024

I'll remove the comments in test_crates/trait_associated_const_added/new/src/lib.rs, but can you check that I've annotated the traits that should trigger the lint?

@@ -5,30 +5,44 @@ mod sealed {
// trigger
pub trait WillGainConstWithoutDefault {
const BAR: bool;

fn make_me_object_safe() -> Self;
Copy link
Owner

Choose a reason for hiding this comment

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

These are actually making the trait stop being object-safe, just like having a const does.

Perhaps a better name:

Suggested change
fn make_me_object_safe() -> Self;
fn make_me_non_object_safe() -> Self;

@obi1kenobi
Copy link
Owner

I would love to be able to bless tests

We have an open issue for switching to insta for lint snapshot testing: #688

When I originally started cargo-semver-checks, insta wasn't yet available nor widespread 😅 Would love your help with it, if that sounds interesting!

Copy link
Owner

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

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

A couple of minor typo fixes, plus some edge cases with the lint I just noticed. Sorry I missed these earlier!

src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
src/lints/trait_associated_const_added.ron Outdated Show resolved Hide resolved
Copy link
Owner

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

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

Awesome! 🚀

@obi1kenobi obi1kenobi merged commit a7e3c51 into obi1kenobi:main Aug 25, 2024
33 checks passed
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.

2 participants