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

Make borrow_as_ptr flag implicit casts as well #14408

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

samueltardieu
Copy link
Contributor

While I like replacing &x by &raw const x and &mut x by &raw mut x, I'm less sure I like the suggested reborrows such as &raw const *p. There was one in Clippy sources, see the PR diff.

@RalfJung, any opinion on this?

Fix #14406

changelog: [borrow_as_ptr]: lint implicit casts as well

@rustbot
Copy link
Collaborator

rustbot commented Mar 14, 2025

r? @llogiq

rustbot has assigned @llogiq.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Mar 14, 2025
@samueltardieu
Copy link
Contributor Author

samueltardieu commented Mar 14, 2025

Note: I really dislike the reborrow suggestions, I'll remove them, and I'm not even sure this should be covered by this lint according to the description. Edit: done, especially given the hundreds of hits in lintcheck

@RalfJung
Copy link
Member

RalfJung commented Mar 14, 2025 via email

@samueltardieu
Copy link
Contributor Author

Can you give a self-contained example of the reborrow case you asked about?

fn main() {
    let p = &0i32;
    let r: *const i32 = p;
}

Initially I had this suggest let r: *const i32 = &raw const *p;, but this should not be covered by the lint. This was particulary ugly with a function call instead of p, as it was proposing using things like &raw const *f(x) if f(x) was returning a ref.

@samueltardieu samueltardieu force-pushed the push-qoosxpuusyzn branch 2 times, most recently from 13b6772 to 2857cca Compare March 14, 2025 17:40
@samueltardieu
Copy link
Contributor Author

samueltardieu commented Mar 14, 2025

Incidentally, the lintcheck output without regard to MSRV made me notice some suspicious code in tracing-core where it looks like *const &Self pointers are compared with ptr::eq() when comparing *const Self pointers might have been intended.

@samueltardieu
Copy link
Contributor Author

The lintcheck seems reasonable.

@RalfJung
Copy link
Member

Initially I had this suggest let r: *const i32 = &raw const *p;, but this should not be covered by the lint

Agreed. Ideally this code would be changed so p becomes a raw pointer (if it has no other uses), but that's probably beyond the scope of the lint.

@RalfJung
Copy link
Member

Does this cover all coercion sites, including e.g. function calls? I guess the fact that this triggered on that tracing-core code means the answer is "yes".

@samueltardieu
Copy link
Contributor Author

samueltardieu commented Mar 16, 2025

Does this cover all coercion sites, including e.g. function calls? I guess the fact that this triggered on that tracing-core code means the answer is "yes".

Yes. It looks for all explicit references which are auto-reborrowed by the compiler as raw pointers, except for references in explicit casts, as those are linted separately.

Interestingly, this discussion brought me to think about one problematic case: &0 (or any ref to a temporary value) can be auto-reborrowed as &raw const 0, but the latter cannot be written as-is ("cannot take address of a temporary"). I have to think more about how to lint let _: *const i32 = &0. Should it warn? Should it suggest putting the temporary into a variable, but to what effect?

Edit: I've changed not to lint references to temporaries, as was done in the &temp as *const T already.

@samueltardieu samueltardieu force-pushed the push-qoosxpuusyzn branch 2 times, most recently from 96dedba to e1bc192 Compare March 16, 2025 11:57
@RalfJung
Copy link
Member

Yes. It looks for all explicit references which are auto-reborrowed by the compiler as raw pointers, except for references in explicit casts, as those are linted separately.

Can't this be just one joint check? The diagnostics can then be different, but ideally the logic for "do we lint" is unified.
(I'm not familiar with clippy's codebase though, maybe there's a good reason to have these separate.)

I have to think more about how to lint let _: *const i32 = &0. Should it warn? Should it suggest putting the temporary into a variable, but to what effect?

Good point. This should not lint.

@samueltardieu
Copy link
Contributor Author

Yes. It looks for all explicit references which are auto-reborrowed by the compiler as raw pointers, except for references in explicit casts, as those are linted separately.

Can't this be just one joint check? The diagnostics can then be different, but ideally the logic for "do we lint" is unified. (I'm not familiar with clippy's codebase though, maybe there's a good reason to have these separate.)

The only part to share is the temporary expression check, and this is done. Otherwise, entry points are different (cast expression vs. any pointer expression whose parent is not a cast).

I have to think more about how to lint let _: *const i32 = &0. Should it warn? Should it suggest putting the temporary into a variable, but to what effect?

Good point. This should not lint.

Yes, this is what I ended up doing.

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.

borrow_as_ptr does not detect implicit casts due to coercions
4 participants