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

Improve diag when calling method on result of index op #125985

Closed
wants to merge 1 commit into from

Conversation

mu001999
Copy link
Contributor

@mu001999 mu001999 commented Jun 4, 2024

Fixes #125924

@rustbot
Copy link
Collaborator

rustbot commented Jun 4, 2024

r? @BoxyUwU

rustbot has assigned @BoxyUwU.
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 S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 4, 2024
Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should add a special case just for the index operator, and one that essentially inlines structurally_resolve_type with some special span casing.

I would like for you to investigate if there's a less invasive approach here.

} else {
let e = self
.tainted_by_errors()
.or_else(|| self.report_ambiguity_errors())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe it's correct to call report_ambiguity_errors here. Please look at the definition of that function -- since it calls collect_remaining_errors, it essentially forces all obligations that are currently waiting on inference to be reported as errors. It's only meant to be called at the end of type checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling report_ambiguity_errors cause the inference of recv_t has failed, so I want to check if there are any remaining errors and emit them. If no such errors, then just emit the inference failure of recv.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any ways to do such things? cause I'd like to suggest like what thing[i]; did.

@compiler-errors
Copy link
Member

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 4, 2024
@mu001999
Copy link
Contributor Author

mu001999 commented Jun 5, 2024

@rustbot ready

@compiler-errors I pushed the new change and it just replace the span.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 5, 2024
@@ -1330,7 +1330,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let rcvr_t = self.check_expr(rcvr);
// no need to check for bot/err -- callee does that
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
let rcvr_t = if let ExprKind::Index(_, index, _) = rcvr.kind {
self.structurally_resolve_type(index.span, rcvr_t)
Copy link
Member

@compiler-errors compiler-errors Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct in case the ambiguity is not due to the index expression:

fn main() {
    let x = vec![];
    x[0usize].method();
}
error[E0282]: type annotations needed for `Vec<_>`
 --> /home/michael/test.rs:2:9
  |
2 |     let x = vec![];
  |         ^
3 |     x[0usize].method();
  |       ------ type must be known at this point

See above how after this PR, we now underline the 0usize even though it is not ambiguous, and there is a single implementation that satisfies the index operator.

Again, I really don't think we should make this change in such a special case.

Systematically determining why the method receiver is ambiguous due to inference is difficult, and I'd rather not patch a single case since it doesn't seem to me more special than any other example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the new change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct for cases where the key's ambiguity doesn't affect the value's ambiguity. Consider HashMap<i32, _>.

@mu001999 mu001999 force-pushed the fix/125924 branch 3 times, most recently from 1dbaf61 to 6b7c6d6 Compare June 5, 2024 02:42
Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still not the right approach, and I really don't think there is going to be a correct approach to handle this without a very involved algorithm to deduce the best "blame" span for an ambiguity. Anything simpler has a very high risk of causing false-positives where we point at the completely wrong span for the ambiguity. That's what I meant above when I said:

Systematically determining why the method receiver is ambiguous due to inference is difficult, and I'd rather not patch a single case since it doesn't seem to me more special than any other example.

For this specific approach, calling report_ambiguity_errors will cause us to report errors for any ambiguity we still have in the function body, even if it has nothing to do with the inference failure of the method call for an indexed receiver.

For example:

fn main() {
    // A totally unrelated variable, which is ambiguous until after the index operation happens below.
    let mut y = Default::default();

    // Now we have an unconstrained vec, and we try to call a method on its element (which is unconstrained).
    let x = vec![];
    x[0usize].method();

    // We constrain the unrelated variable. This is *okay*, since `y` has nothing to do with `x` or the method call above.
    y = 1i32;
}
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
 --> /home/michael/test.rs:3:17
  |
3 |     let mut y = Default::default();
  |                 ^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
  |
help: use a fully-qualified path to a specific available implementation
  |
3 |     let mut y = </* self type */ as Default>::default();
  |                 +++++++++++++++++++        +

error: aborting due to 1 previous error

@mu001999
Copy link
Contributor Author

mu001999 commented Jun 5, 2024

@compiler-errors Thanks for the example! It's very clear to me.

@mu001999
Copy link
Contributor Author

mu001999 commented Jun 5, 2024

@compiler-errors I am trying to check if the index ty is known at this point, then use rvcr.span. Do you think it's possible? Or I will close this PR if it requires more complex changes.

@mu001999
Copy link
Contributor Author

mu001999 commented Jun 5, 2024

@compiler-errors I pushed new change, it only uses index.span if we don't know the ty of index, but idk if there are any other false-positives.

@mu001999 mu001999 requested a review from compiler-errors June 5, 2024 06:51
@bors
Copy link
Contributor

bors commented Jun 5, 2024

☔ The latest upstream changes (presumably #126016) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all the back and forth, but I'm going to go ahead and repeat myself by saying that this is probably not possible to fix in general, and I don't think we need to have this special casing for such a rare case.

Supporting this in general, which is probably what @oli-obk wanted in the original diagnostic issue, would require far more invasive changes to the way we track ambiguity in the type checker.

@@ -1330,7 +1330,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let rcvr_t = self.check_expr(rcvr);
// no need to check for bot/err -- callee does that
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
let rcvr_t = if let ExprKind::Index(_, index, _) = rcvr.kind {
self.structurally_resolve_type(index.span, rcvr_t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct for cases where the key's ambiguity doesn't affect the value's ambiguity. Consider HashMap<i32, _>.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 18, 2024
@compiler-errors
Copy link
Member

I'm gonna go ahead and close this since I don't think there's a simple tweak to this PR to make it work in general

@mu001999 mu001999 deleted the fix/125924 branch June 18, 2024 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unhelpful type annotations needed when calling method on result of index op
5 participants