-
-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
add function_export_name_changed lint #728
Conversation
FWIW here's the line that breaks nightly tests - it doesn't seem like an issue with this lint. |
Separate PRs for each lint is fine. That's usually faster and easier to review, and shows up more nicely in the changelog as well. That test has been flaky for a while and I'm not sure why. I've never managed to reproduce the flakiness locally, so my gut feeling is that it might possibly be a GitHub Actions bug of some sort? Not sure, haven't had time to dig into it... Don't worry about it, I don't think you broke any of it — I just restarted it and I expect it'll probably pass. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have unintentionally pointed you a bit in the wrong direction on this. Sorry about that!
It should be easy to straighten things out. This is part of why semver linting is so hard! Too many edge cases! But getting them right is important, and I feel like our users will appreciate it.
... on Function { | ||
name @output | ||
|
||
export_name @filter(op: "!=", value: ["%export_name"]) @filter(op: "!=", value: ["$null"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a failure of our docs, so don't worry about it -- there's a built-in filter operator for this:
export_name @filter(op: "!=", value: ["%export_name"]) @filter(op: "!=", value: ["$null"]) | |
export_name @filter(op: "!=", value: ["%export_name"]) @filter(op: "is_not_null") |
}"#, | ||
arguments: { | ||
"zero": 0, | ||
"null": null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"null": null, |
since we used the built-in filter operator for this
item @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { | ||
... on Function { | ||
export_name @filter(op: "=", value: ["%export_name"]) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a good idea to write the lint for "export name no longer exists" first, just to get us a bit more test coverage and help us decide how to split the responsibilities between this lint and that one.
Here's what I'm worried about.
If both this lint and that other one enforce that the export name doesn't exist anymore, then it sounds like this lint is just a stricter version of that other one -- so whenever this one triggers, the other one will too. We want to avoid that.
So maybe we reshape this lint a bit to say "a function in the public API has changed its export name in the ABI" instead. So the invariant that is broken (and that we're reporting) is "call func()
via the API, and export_func()
via the ABI, those do the same thing because they are the same function." If the ABI export name changes to something else, then even if the ABI name export_func()
continues to exist on some other function, this is likely worth flagging because it's a possible bug.
If we do end up taking that route, then I think:
- This block I've highlighted becomes unnecessary.
- The other lint doesn't need to look at
importable_path
at all, and can just focus onexport_name
alone.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking about that when I was writing it - it was pretty much the same query except checking if the current export_name
is null. If we don't need granular feedback between missing vs changed, they can be easily combined. Do you think it's necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not at my computer right now but I can push the other lint to a branch when I get a chance
/// negative test - export name on one function gets moved to the other | ||
/// this is not necessarily a breaking change, as long as the ABIs are the same | ||
/// but that is a different lint | ||
pub mod export_name_moved { | ||
pub fn export_name_moved_1() {} | ||
|
||
#[export_name = "export_name_moved"] | ||
pub fn export_name_moved_2() {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may want to flag this, because a public API call to export_name_moved::export_name_moved_1()
is no longer equivalent to a call to export_name_moved()
via the ABI.
See comment on the lint above for details.
Yeah, we can just the missing one for both cases, I think that's fine.
…On Sat, Mar 30, 2024, 6:59 PM Max Carr ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/lints/function_export_name_changed.ron
<#728 (comment)>
:
> + item @fold @Transform(op: "count") @filter(op: "=", value: ["$zero"]) {
+ ... on Function {
+ export_name @filter(op: "=", value: ["%export_name"])
+ }
+ }
Yeah, I was thinking about that when I was writing it - it was pretty much
the same query except checking if the current export_name *is* null. If
we don't need granular feedback between missing vs changed, they can be
easily combined. Do you think it's necessary?
—
Reply to this email directly, view it on GitHub
<#728 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAR5MSRHMSANZ27FFUX257TY247WRAVCNFSM6AAAAABFPX6VJOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTSNZQGA3DMOJVGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
All good. For these categories from the original issue:
Would these (just) apply to exported non-public functions? Because changing the API of a public function would already be a breaking change, so do we want to flag this twice? |
That's a great question. I think it's reasonable to start by flagging twice here, because we're flagging two separate problems: the API is broken, and the ABI is also broken. Down the line, if this proves to be problematic for any reason, we can build something more sophisticated. For example, we could have three lints instead of two: broken API but not ABI, broken ABI but not API, and both broken at once. But going straight for this seems like major overkill right now, so let's go with the simpler option of flagging twice for now. |
OK, I consolidated the two cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a set of tiny nitpicks. The lint is correct and the tests are in great shape as well. Less than 5min of polishing left and this is good to merge.
required_update: Major, // Not specified in rust semver doc? most similar is for #[repr] changes: https://doc.rust-lang.org/cargo/reference/semver.html#type-layout | ||
reference_link: Some("https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute"), // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave both of these comments in the file that will get merged?
Asking because the TODO seems completed, and the other comment seemed like a question for reviewers that I believe I replied to in my previous comment near here.
/// positive test - export name on one function gets moved to the other | ||
/// this is still a breaking change because a call to `export_name_moved_1` in the API | ||
/// is no longer equivalent to a call to `export_name_moved` in the ABI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great comments throughout, and this one is particularly good! Well done!
Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
- remove old comments - add output from new `new_export_name` field
Thanks for the feedback! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome job!
Second bullet point of #502. Should I put all the lints in one (draft, I haven't finished them yet) PR or do separate PRs?