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
needless_borrow false positive in case when compiler does not automatically borrow #9111
Comments
Looks to be the same as #9095. Checking if a generic trait is implemented by a reference type isn't working correctly. |
The fix hasn't been merged into the main rustc repo yet. |
ah true, I thought I had seen a release go out. |
Has this been released? I am still seeing this with rustup 2022-09-08 toolchain. |
The issue is fixed on the 2022-09-16 toolchain (tested on playground) |
Do you know in which PR/commit ? |
I'd assume #9096 |
I'm still getting similar false positive on 2022-10-13.
|
@BusyJay With your example, I see:
I think this is a different bug. |
Fix `needless_borrow` false positive The PR fixes the false positive exposed by `@BusyJay's` example in: #9111 (comment) The current approach is described in #9674 (comment) and #9674 (comment). The original approach appears below. --- The proposed fix is to flag only "simple" trait implementations involving references, a concept that I introduce next. Intuitively, a trait implementation is "simple" if all it does is dereference and apply the trait implementation of a type named by a type parameter. `AsRef` provides a good example of a simple implementation: https://doc.rust-lang.org/std/convert/trait.AsRef.html#impl-AsRef%3CU%3E-for-%26T We can make this idea more precise as follows. Given a trait implementation, first determine whether the implementation is "used defined." If so, then examine its nested obligations. Consider the implementation simple if-and-only-if: - there is at least one nested obligation for the same trait - for each type `X` in the nested obligation's substitution, either `X` is the same as that of the original obligation's substitution, or the original type is `&X` For example, the following implementation from `@BusyJay's` example is "complex" (i.e., not simple) because it produces no nested obligations: ```rust impl<'a> Extend<&'a u8> for A { ... } ``` On the other hand, the following slightly modified implementation is simple, because it produces a nested obligation for `Extend<X>`: ```rust impl<'a, X> Extend<&'a X> for A where A: Extend<X> { ... } ``` How does flagging only simple implementations help? One way of interpreting the false positive in `@BusyJay's` example is that it separates a reference from a concrete type. Doing so turns a successful type inference into a failing one. By flagging only simple implementations, we separate references from type variables only, thereby eliminating this class of false positives. Note that `Deref` is a special case, as the obligations generated for it already involve the underlying type. r? `@Jarcho` (Sorry to keep pinging you with `needless_borrow` stuff. But my impression is no one knows this code better than you.) changelog: fix `needless_borrow` false positive
This issue seems to be fixed. None of the reproducers mentioned here get linted anymore it looks like: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3c4b7032d2e1c46d488b42a1a5cc4627 |
Thank you for triaging. |
Summary
The needless_borrow lint has a false positive where the suggested fix results in code that won't compile, because the compiler doesn't automatically borrow, even though the lint says it does.
Lint Name
needless_borrow
Reproducer
I tried this code:
Making the change that clippy suggests, results in the following and the following compiler error:
Version
Additional Labels
@rustbot label +I-suggestion-causes-error
The text was updated successfully, but these errors were encountered: