-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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 against function pointer comparisons #118833
Add lint against function pointer comparisons #118833
Conversation
r? @cjgillot (rustbot has picked a reviewer for you, use r? to override) |
Some changes occurred in src/tools/clippy cc @rust-lang/clippy The Miri subtree was changed cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
The lint name is very long, it would be nice if we could come up with a shorter name. I don't have a suggestion though. |
Sure, but I don't think it matter that much, I'm not expecting anyone to write the lint name by hand (since it's warn-by-default, people can just copy/paste in the diagnostic output). We also already have some pretty long lint name, like unknown_or_malformed_diagnostic_attributes. But if someone comes up with a name as descriptive but shorter I can integrate it, I'm just not sure it's worth anyone time. |
e0a6772
to
4798319
Compare
This comment has been minimized.
This comment has been minimized.
444a0b9
to
23214cb
Compare
If it's not too much work, could we do a crater run here to find out what kind of places are using this kind of comparison in the wild? |
Sure, I just pushed a commit making the lint deny-by-default. I will let you do the bors+craterbot commands. |
@bors try |
…ons, r=<try> Add lint against function pointer comparisons This is kind of a follow-up to rust-lang#117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it. ----- ## `unpredictable_function_pointer_comparisons` *warn-by-default* The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands. ### Example ```rust fn foo() {} let a = foo as fn(); let _ = a == foo; ``` ### Explanation Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together. ---- This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`. `@rustbot` labels +I-lang-nominated
This comment has been minimized.
This comment has been minimized.
☀️ Try build successful - checks-actions |
@rustbot labels -I-lang-nominated We discussed this in the T-lang meeting today. There was some support for this, but people were concerned about whether there may be legitimate use cases and what we would be suggesting that those people do instead. For wide pointer comparisons, we suggest that people use The consensus was that seeing use cases would help, and that a crater run would help to find those use cases. That's now happening in the comments above. Once the crater run comes back and has been analyzed, please renominate for T-lang discussion. For the analysis, we're looking to find 1) use cases of this that are correct in the sense that they rely only on the actual semantics, and 2) the prevalence of bugs where people are using this in ways that rely on semantics that do not actually hold. |
There's no such thing, comparing Rust functions for equality is in general just inherently meaningless. That doesn't make code using The flip side of this is that the standard library itself actually relies on such a comparison in the format-args machinery... it's for a special case (a monomorphic function) where the current implementation AFAIK does not generate duplicates (but I don't know how multi-CGU handling works so I am not sure). It's certainly not guaranteed by the language. |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
One thought expressed in the meeting was as follows: Comparing functions for equality via pointers may yield false negatives but not false positives. The fact that two functions may compare unequal (based on pointers to them) but in fact do the same thing is a rather fundamental property of not just Rust, but of any language. In general, it's impossible to know whether two different functions may in fact do the same thing. In this light, maybe it's OK that these comparisons produce false negatives, and maybe there exist valid use cases that only rely on the property that we will not return false positives. |
That's not true. There are both false negatives and false positives. That's exactly why I wanted the lint description to be clear about this. False positives arise when LLVM merges two functions because they optimized to the same code. |
@rfcbot reviewed |
This comment was marked as resolved.
This comment was marked as resolved.
33e1745
to
2ed43d9
Compare
2ed43d9
to
7b06fcf
Compare
@rustbot labels -S-blocked -S-waiting-on-fcp +finished-final-comment-period |
…isons, r=cjgillot Add lint against function pointer comparisons This is kind of a follow-up to rust-lang#117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it. ----- ## `unpredictable_function_pointer_comparisons` *warn-by-default* The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands. ### Example ```rust fn foo() {} let a = foo as fn(); let _ = a == foo; ``` ### Explanation Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together. ---- This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`. `@rustbot` labels +I-lang-nominated ~~Edit: Blocked on rust-lang/libs-team#323 being accepted and it's follow-up pr~~
…isons, r=cjgillot Add lint against function pointer comparisons This is kind of a follow-up to rust-lang#117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it. ----- ## `unpredictable_function_pointer_comparisons` *warn-by-default* The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands. ### Example ```rust fn foo() {} let a = foo as fn(); let _ = a == foo; ``` ### Explanation Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together. ---- This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`. ``@rustbot`` labels +I-lang-nominated ~~Edit: Blocked on rust-lang/libs-team#323 being accepted and it's follow-up pr~~
Rollup of 7 pull requests Successful merges: - rust-lang#118833 (Add lint against function pointer comparisons) - rust-lang#122161 (Fix suggestion when shorthand `self` has erroneous type) - rust-lang#133233 (Add context to "const in pattern" errors) - rust-lang#133843 (Do not emit empty suggestion) - rust-lang#133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`) - rust-lang#133872 (No need to create placeholders for GAT args in confirm_object_candidate) - rust-lang#133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 7 pull requests Successful merges: - rust-lang#118833 (Add lint against function pointer comparisons) - rust-lang#122161 (Fix suggestion when shorthand `self` has erroneous type) - rust-lang#133233 (Add context to "const in pattern" errors) - rust-lang#133843 (Do not emit empty suggestion) - rust-lang#133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`) - rust-lang#133872 (No need to create placeholders for GAT args in confirm_object_candidate) - rust-lang#133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 10 pull requests Successful merges: - rust-lang#118833 (Add lint against function pointer comparisons) - rust-lang#122161 (Fix suggestion when shorthand `self` has erroneous type) - rust-lang#133233 (Add context to "const in pattern" errors) - rust-lang#133761 (Update books) - rust-lang#133843 (Do not emit empty suggestion) - rust-lang#133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`) - rust-lang#133872 (No need to create placeholders for GAT args in confirm_object_candidate) - rust-lang#133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder) - rust-lang#133890 (Add a new test ui/incoherent-inherent-impls/no-other-unrelated-errors to check E0116 does not cause unrelated errors) - rust-lang#133892 (Revert rust-lang#133817) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#118833 - Urgau:lint_function_pointer_comparisons, r=cjgillot Add lint against function pointer comparisons This is kind of a follow-up to rust-lang#117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it. ----- ## `unpredictable_function_pointer_comparisons` *warn-by-default* The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands. ### Example ```rust fn foo() {} let a = foo as fn(); let _ = a == foo; ``` ### Explanation Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together. ---- This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`. ```@rustbot``` labels +I-lang-nominated ~~Edit: Blocked on rust-lang/libs-team#323 being accepted and it's follow-up pr~~
This is kind of a follow-up to #117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it.
unpredictable_function_pointer_comparisons
warn-by-default
The
unpredictable_function_pointer_comparisons
lint checks comparison of function pointer as the operands.Example
Explanation
Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together.
This PR also uplift the very similar
clippy::fn_address_comparisons
lint, which only linted on if one of the operand was anty::FnDef
while this PR lints proposes to lint on allty::FnPtr
andty::FnDef
.@rustbot labels +I-lang-nominated
Edit: Blocked on rust-lang/libs-team#323 being accepted and it's follow-up pr