-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Suggest borrowing if a trait implementation is found for &/&mut <type> #85369
Conversation
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
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 sure how I feel about the blacklist. Can you provide some examples of errors with/without it? (And add some tests for those (with))
Also, these suggestions are only shown if &T: Trait
actually holds right? Not just if T: Trait
doesn't?
| ^ | ||
| | | ||
| expected an implementor of trait `Trait` | ||
| help: consider borrowing mutably here: `&mut s` |
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 it's better to say "mutably borrowing"
The blacklist doesn't endanger soundness or anything — it just controls whether we issue a suggestion in this particular function or not. Currently, no suggestions are issued at all for the obligation causes I have addressed in this PR, so we don't lose anything by blacklisting a few traits. Without the blacklist, there are many test case failures in As an example, fn foo<T: Copy>(t: T) {}
fn main() {
foo("".to_string());
} gives
with the blacklist, and
without it.
Yes, of course. I have added another test case to emphasize this, along with one test case for the blacklisted traits. I have also adjusted the wording of the suggestion. |
This comment has been minimized.
This comment has been minimized.
Thank you ♥ @bors r+ rollup |
📌 Commit 572bb13 has been approved by |
@jackh726 Thanks for taking the time to review this PR! |
Suggest borrowing if a trait implementation is found for &/&mut <type> This pull request fixes rust-lang#84973 by suggesting to borrow if a trait is not implemented for some type `T`, but it is for `&T` or `&mut T`. For instance: ```rust trait Ti {} impl<T> Ti for &T {} fn foo<T: Ti>(_: T) {} trait Tm {} impl<T> Tm for &mut T {} fn bar<T: Tm>(_: T) {} fn main() { let a: i32 = 5; foo(a); let b: Box<i32> = Box::new(42); bar(b); } ``` gives, on current nightly: ``` error[E0277]: the trait bound `i32: Ti` is not satisfied --> t2.rs:11:9 | 3 | fn foo<T: Ti>(_: T) {} | -- required by this bound in `foo` ... 11 | foo(a); | ^ the trait `Ti` is not implemented for `i32` error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied --> t2.rs:14:9 | 7 | fn bar<T: Tm>(_: T) {} | -- required by this bound in `bar` ... 14 | bar(b); | ^ the trait `Tm` is not implemented for `Box<i32>` error: aborting due to 2 previous errors ``` whereas with my changes, I get: ``` error[E0277]: the trait bound `i32: Ti` is not satisfied --> t2.rs:11:9 | 3 | fn foo<T: Ti>(_: T) {} | -- required by this bound in `foo` ... 11 | foo(a); | ^ | | | expected an implementor of trait `Ti` | help: consider borrowing here: `&a` error[E0277]: the trait bound `Box<i32>: Tm` is not satisfied --> t2.rs:14:9 | 7 | fn bar<T: Tm>(_: T) {} | -- required by this bound in `bar` ... 14 | bar(b); | ^ | | | expected an implementor of trait `Tm` | help: consider borrowing mutably here: `&mut b` error: aborting due to 2 previous errors ``` In my implementation, I have added a "blacklist" to make these suggestions flexible. In particular, suggesting to borrow can interfere with other suggestions, such as to add another trait bound to a generic argument. I have tried to configure this blacklist to cause the least amount of test case failures, i.e. to model the current behavior as closely as possible (I only had to change one existing test case, and this change was quite clearly an improvement).
…laumeGomez Rollup of 7 pull requests Successful merges: - rust-lang#84587 (rustdoc: Make "rust code block is empty" and "could not parse code block" warnings a lint (`INVALID_RUST_CODEBLOCKS`)) - rust-lang#85280 (Toggle-wrap items differently than top-doc.) - rust-lang#85338 (Implement more Iterator methods on core::iter::Repeat) - rust-lang#85339 (Report an error if a lang item has the wrong number of generic arguments) - rust-lang#85369 (Suggest borrowing if a trait implementation is found for &/&mut <type>) - rust-lang#85393 (Suppress spurious errors inside `async fn`) - rust-lang#85415 (Clean up remnants of BorrowOfPackedField) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Can you add a test where both the |
No, because this pull request has already been merged. The output will be a suggestion to immutably borrow; you can see for yourself on nightly: trait Tr {}
struct S {}
impl Tr for &S {}
impl Tr for &mut S {}
fn foo<T: Tr>(t: T) {}
fn main() {
let s = S {};
foo(s);
}
|
This pull request fixes #84973 by suggesting to borrow if a trait is not implemented for some type
T
, but it is for&T
or&mut T
. For instance:gives, on current nightly:
whereas with my changes, I get:
In my implementation, I have added a "blacklist" to make these suggestions flexible. In particular, suggesting to borrow can interfere with other suggestions, such as to add another trait bound to a generic argument. I have tried to configure this blacklist to cause the least amount of test case failures, i.e. to model the current behavior as closely as possible (I only had to change one existing test case, and this change was quite clearly an improvement).