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 missing_transmute_annotations lint #12239

Merged
merged 4 commits into from Mar 24, 2024

Conversation

GuillaumeGomez
Copy link
Member

@GuillaumeGomez GuillaumeGomez commented Feb 7, 2024

Fixes #715.

r? @blyxyas

changelog: Add missing_transmute_annotations lint

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Feb 7, 2024
@GuillaumeGomez GuillaumeGomez changed the title Add missing_transmute_annotation lint Add missing_transmute_annotations lint Feb 7, 2024
@GuillaumeGomez
Copy link
Member Author

And as usual I discover that there is already a transmute module which does pretty much all I originally did manually. Moved the lint there.

@blyxyas
Copy link
Member

blyxyas commented Feb 7, 2024

#715?? Guillaume, that issue was open 8 years ago. Really going on a journey back inntime

@Centri3
Copy link
Member

Centri3 commented Feb 7, 2024

There's also #11047 for basically an identical lint, it's inactive though

@GuillaumeGomez
Copy link
Member Author

Which also provides type suggestions. Maybe I should add that.

@GuillaumeGomez
Copy link
Member Author

#715?? Guillaume, that issue was open 8 years ago. Really going on a journey back inntime

Told you I was going through issues. :p

I generally pick a random page and start taking a look there.

There's also #11047 for basically an identical lint, it's inactive though

Didn't see that one. ^^' Oh well, since it's inactive I think it's fine. I added suggestions as well.

@blyxyas
Copy link
Member

blyxyas commented Feb 9, 2024

I'll have to reroll this one, we are at Feb. 9 and I have practically no progress on performance (which is kinda really important), I've also set myself on vacation for this exact reason (I'd love to not have my busyness status in version control D:).

r? rust-lang/clippy

@rustbot rustbot assigned y21 and unassigned blyxyas Feb 9, 2024
Copy link
Member

@y21 y21 left a comment

Choose a reason for hiding this comment

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

Looks like a really nice lint to have! Implementation looks pretty good already. Not sure about the category and if we want to have it be warn-by-default though - that might deserve discussion :)

clippy_lints/src/transmute/mod.rs Show resolved Hide resolved
clippy_lints/src/transmute/mod.rs Show resolved Hide resolved
tests/ui/missing_transmute_annotations.rs Show resolved Hide resolved
@GuillaumeGomez GuillaumeGomez force-pushed the missing_transmute_annotation branch 2 times, most recently from 8a5b75a to e55f017 Compare February 10, 2024 11:19
@GuillaumeGomez
Copy link
Member Author

Applied suggestions.

@bors
Copy link
Collaborator

bors commented Feb 11, 2024

☔ The latest upstream changes (presumably #12040) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez GuillaumeGomez force-pushed the missing_transmute_annotation branch 4 times, most recently from f40a339 to 235c9f3 Compare February 19, 2024 14:05
@GuillaumeGomez
Copy link
Member Author

Updated, cleaned up the commit history as well and implemented the two limitations:

  • not emitting if it comes from an external macro
  • not emitting if the transmute returned value is put into a let binding with type annotations

@GuillaumeGomez
Copy link
Member Author

Anything else to be done here?

last.ident.span.with_hi(path.span.hi()),
"transmute used without annotations",
"consider adding missing annotations",
format!("{}::<{from_ty}, {to_ty}>", last.ident.as_str()),
Copy link
Member

Choose a reason for hiding this comment

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

If one/more of the types can be left inferred, can we keep it like that here? e.g., let _: T.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd rather not.

Copy link
Member

Choose a reason for hiding this comment

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

Why not? Is it because it'd require rewriting it? I don't see why this shouldn't be done.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe I misunderstood what you meant but this lint is about making it explicit what the transmute types are (both input and output). So if we provide annotation for one of the two, better provide for both directly.

Copy link
Member

Choose a reason for hiding this comment

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

What I meant was that, if it's within a let statement for example, we could keep Dst as _. If it's better to provide both directly, and this is still an issue with let, then we shouldn't special case let at all, no?

I see what you mean that providing them is better, but special-casing it then not suggesting it is a bit contradictory.

Copy link
Member Author

Choose a reason for hiding this comment

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

The idea behind my position is that if you ever remove the let binding or change the type annotation, if we originally suggested both types, it'll prevent compilation and require user to check that the code is still valid. I think it's pretty important considering how easy it is to have unexpected behaviours with transmute.

tests/ui/missing_transmute_annotations.rs Show resolved Hide resolved

macro_rules! local_bad_transmute {
($e:expr) => {
std::mem::transmute($e)
Copy link
Member

Choose a reason for hiding this comment

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

Can you special case _ here in all macros? The type can't always be specified like this automatically

Copy link
Member Author

Choose a reason for hiding this comment

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

In such cases, I think it means the macro should be rewritten instead of us dropping the level of detection.

if !missing_generic {
return false;
}
// If it's being set as a local variable value...
Copy link
Member

Choose a reason for hiding this comment

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

We should include closures here imo, if they have type annotations. This could include the parameter if it's specified as well, but not something like:

// i64 is known, but [i32; 2] is never specified
|x: i32, y: i32| -> i64 unsafe { transmute::<[i32; 2], _>([x, y]) };

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think we should special case closures either. It adds a lot of complexity to detect such cases for a very marginal gain imo.

Copy link
Member

Choose a reason for hiding this comment

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

Not really. The return type part is easy, and the parameter is too - Get the Res from the QPath, the HirId of the local, then the parent's parent should include the types in FnDecl.

I wouldn't block it on this so if it's not done I can add it after, eventually.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not in this sense. I meant, for the same reason we want to enforce having type annotations when transmute is used as return expr, we want to enforce for it for closures as well.

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 agree with that as closures are usually private and not public. It's more akin to let than functions. I don't think you can fold a closure either in IDEs.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see why closures being private or public changes anything. If you want to bring this back to debate, let's continue on zulip. ;)

Copy link
Member

Choose a reason for hiding this comment

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

I'll bring up my current points on zulip sometime.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 There is an open thread already, don't hesitate to comment there directly. ;)

@GuillaumeGomez
Copy link
Member Author

I added check for let var: _ =, I also extended the check to look up if the transmute call parent is a block that it is assigned in a variable with type annotations (or not). And finally, I added ADT tests as well to check suggestions look correct.

With this I think I didn't forget anything?

@GuillaumeGomez
Copy link
Member Author

And updated ui test.

@bors
Copy link
Collaborator

bors commented Mar 14, 2024

☔ The latest upstream changes (presumably #12386) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez
Copy link
Member Author

As discussed on zulip, if the transmute call is the only thing in the function, then the lint won't be emitted.

Anything else to be done?

@GuillaumeGomez
Copy link
Member Author

Updated!

Copy link
Member

@y21 y21 left a comment

Choose a reason for hiding this comment

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

Looks fine to me. The implementation seems more lax now (e.g. it allows a tail transmute expression in a function no matter how many other statements there are), but that's fine by me and should also make it less controversial.

It would probably be useful to have an optional configuration variable for disallowing inferred transmute node args everywhere if a user specifically wants that behavior, but I don't want to block the (initial) PR adding it for too much longer. It could always be improved separately

if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {
// ... which does have type annotations.
if let Some(ty) = local.ty
// If this is a `let x: _ =`, we shouldn't lint.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// If this is a `let x: _ =`, we shouldn't lint.
// If this is a `let x: _ =`, we should lint.

?
Otherwise this comment is a bit confusing, because the opposite happens: we do lint specifically let x: _ because of the !matches!(ty.kind, TyKind::Infer) below

Copy link
Member Author

Choose a reason for hiding this comment

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

Forgot to update the comment, good catch!

@y21
Copy link
Member

y21 commented Mar 23, 2024

The history here is a bit "convoluted", I tried cleaning it up a little bit by resolving my previous comments, but I don't know about @Centri3 's comments. Some of them aren't implemented, but I'm also not sure if you both agreed that its okay to not do it or if there's something left from your side?

@GuillaumeGomez
Copy link
Member Author

Fixed comment.

It would probably be useful to have an optional configuration variable for disallowing inferred transmute node args everywhere if a user specifically wants that behavior, but I don't want to block the (initial) PR adding it for too much longer. It could always be improved separately

Please open an issue and assign me to it so it's not forgotten. 😉

@GuillaumeGomez
Copy link
Member Author

GuillaumeGomez commented Mar 23, 2024

The history here is a bit "convoluted", I tried cleaning it up a little bit by resolving my previous comments, but I don't know about @Centri3 's comments. Some of them aren't implemented, but I'm also not sure if you both agreed that its okay to not do it or if there's something left from your side?

I think it was resolved based on their comment in the zulip conversation.

EDIT: It would still be worth confirming with @Centri3 though.

@Centri3
Copy link
Member

Centri3 commented Mar 23, 2024

I didn't bring up anything, though I don't think it's worth it to block on anything. It was mostly supposed to be about allowing some edge cases (like closures) which don't need to be added, but my rationale behind them.

Everything else is good.

@GuillaumeGomez
Copy link
Member Author

Thanks for confirming!

@y21 time for r+? :3

@y21
Copy link
Member

y21 commented Mar 23, 2024

Sounds good, can you squash the commits? r=me with that done

@bors delegate+

@bors
Copy link
Collaborator

bors commented Mar 23, 2024

✌️ @GuillaumeGomez, you can now approve this pull request!

If @y21 told you to "r=me" after making some further change, please make that change, then do @bors r=@y21

@GuillaumeGomez
Copy link
Member Author

@bors r=y21

@bors
Copy link
Collaborator

bors commented Mar 24, 2024

📌 Commit ee25582 has been approved by y21

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Mar 24, 2024

⌛ Testing commit ee25582 with merge 95c62ff...

@bors
Copy link
Collaborator

bors commented Mar 24, 2024

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: y21
Pushing 95c62ff to master...

@bors bors merged commit 95c62ff into rust-lang:master Mar 24, 2024
8 checks passed
@GuillaumeGomez GuillaumeGomez deleted the missing_transmute_annotation branch March 24, 2024 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint transmute where source type is unspecified.
7 participants