-
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
Fix incorrect suggestion for trait bounds involving binary operators #94034
Fix incorrect suggestion for trait bounds involving binary operators #94034
Conversation
r? @cjgillot (rust-highfive has picked a reviewer for you, use r? to override) |
r? @oli-obk cc @rust-lang/wg-diagnostics |
.collect::<Vec<_>>(); | ||
if !predicates.is_empty() { | ||
for pred in predicates { | ||
self.infcx.suggest_restricting_param_bound( |
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 we should teach this function about associated type bounds. You could filter all projection predicates for one that is for the current trait and type and if there is such a projection predicate, extend the suggestion with the assoc bound
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.
One issue I'm encountering. I don't think there's a sound way to determine what the appropriate Output
type should be. The function check_overloaded_binop
attempts to do this, but it can only compute return_ty
if the initial lookup_op_method
returns a MethodCallee
, which it does not in the case being addressed.
Is there some possibility here that I'm missing?
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 hoping that the correct associated type bound is in the errors
list. Try dumping the entire list and checking if it contains PredicateKind::Projection
that match the pred
in the loop here.
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.
Yes I've checked, and a Projection
predicate does not already exist. This is because the relevant predicates are generated by the function obligation_for_method
. That function would have to be extended to produce a Projection
predicate, except it can only do so if it knows about the expected associated types of a method, which it cannot in this case.
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 I made some related changes in https://github.com/rust-lang/rust/pull/90006/files, which won't be landing until I manage to get rid of the perf regression.
@@ -6,10 +6,10 @@ LL | a.iter().map(|a| a*a) | |||
| | | |||
| &T | |||
| | |||
help: consider restricting type parameter `T` | |||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement |
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.
Preexisting, but this message is too vague. We should probably check all occurrences in our ui tests and see if we can be more targetted (or at least change the wording)
Do we suggest the right |
LL | fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> where &T: Mul<&T> { | ||
| +++++++++++++++++ |
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.
Is this suggestion change correct?
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.
Yes, albeit underconstrained on Output
. It actually fixes the previously incorrect suggestion of T: std::ops::Mul<Output = f64>
. In that case, Rhs = Self
means only T * T
is valid, whereas in this case you specifically need T * f64
here.
Edit: I got mixed up. resolution-in-overloaded-op.stderr is what I was referring to.
This suggestion is still correct, but underconstrained by not suggesting Output
.
No, because I don't think there is a sound way to guess what |
☔ The latest upstream changes (presumably #93368) made this pull request unmergeable. Please resolve the merge conflicts. |
@willcrichton |
to fix incorrect suggestion for trait bounds involving binary operators. Fixes rust-lang#93927, rust-lang#92347, rust-lang#93744.
r=me after rebasing |
f79c5d3
to
dc41dba
Compare
Ok, I have rebased / fixed and also updated the tests such that everything now passes under this PR. |
@rustbot ready |
@bors r=estebank |
📌 Commit dc41dba has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (d6a57d3): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
LL | impl<B: std::ops::Add<Output = B>> Add for D<B> { | ||
| +++++++++++++++++++++++++++ | ||
LL | impl<B: std::ops::Add> Add for D<B> { | ||
| +++++++++++++++ |
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.
Note to self: check if we can get this back.
…-binops, r=estebank Add Output = expected type trait obligation for known binary operators This PR is a follow-on to rust-lang#94034 that addresses rust-lang#96442. That is, after replacing the trait-suggestion logic in `op.rs` with a more generic path that analyzes a general set of `Obligation`s, then we lost some specificity in the suggestions where the bounds on the associated type `Output=` would not get suggested. This PR fixes this issue by changing `FnCtxt::construct_obligation_for_trait` to include a new `ProjectionPredicate` obligation for binary operators that obliges that `Output` is the same as the expected type of the expression. Additionally, to get the expected type of the expression, this PR threads the `Expectation<'tcx>` structure throughout several functions. See src/test/ui/generic-associated-types/missing-bounds.stderr for an example of how this works. One side effect of this change is it causes type-check failures with binops to include additional information. Specifically, many now say ``` error: type mismatch resolving `<Lhs as TheBinop>::Output == ExpectedTy` ``` It's up for discussion whether this added context is worth it to the user. r? `@estebank`
This PR fixes #93927, #92347, #93744 by replacing the bespoke trait-suggestion logic in
op.rs
with a more common code path.The downside is that this fix causes some suggestions to not include an
Output=
type, reducing their usefulness.Note that this causes one case in the
missing-bounds.rs
test to fail rustfix. So I would need to move that code into a separate non-fix test if this PR is otherwise acceptable.