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

Don't do post-method-probe error reporting steps if we're in a suggestion #125100

Merged
merged 2 commits into from
May 14, 2024

Conversation

compiler-errors
Copy link
Member

Currently in method probing, if we fail to pick a method, then we reset and try to collect relevant candidates for method errors:

// things failed, so lets look at all traits, for diagnostic purposes now:
self.reset();
let span = self.span;
let tcx = self.tcx;
self.assemble_extension_candidates_for_all_traits();
let out_of_scope_traits = match self.pick_core() {
Some(Ok(p)) => vec![p.item.container_id(self.tcx)],
Some(Err(MethodError::Ambiguity(v))) => v
.into_iter()
.map(|source| match source {
CandidateSource::Trait(id) => id,
CandidateSource::Impl(impl_id) => match tcx.trait_id_of_impl(impl_id) {
Some(id) => id,
None => span_bug!(span, "found inherent method when looking at traits"),
},
})
.collect(),
Some(Err(MethodError::NoMatch(NoMatchData {
out_of_scope_traits: others, ..
}))) => {
assert!(others.is_empty());
vec![]
}
_ => vec![],
};
if let Some((kind, def_id)) = private_candidate {
return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits));
}
let similar_candidate = self.probe_for_similar_candidate()?;
Err(MethodError::NoMatch(NoMatchData {
static_candidates,
unsatisfied_predicates,
out_of_scope_traits,
similar_candidate,
mode: self.mode,
}))

However, we do method lookups via lookup_method_for_diagnostic and only care about the result if the method probe was a success.

Namely, we don't need to do a bunch of other lookups on failure, since we throw away these results anyways, such as an expensive call to:

self.assemble_extension_candidates_for_all_traits();

And:

let similar_candidate = self.probe_for_similar_candidate()?;


This PR also renames some methods so it's clear that they're for diagnostics.

r? @nnethercote

@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 May 14, 2024
@@ -91,7 +91,7 @@ pub enum CandidateSource {
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Determines whether the type `self_ty` supports a visible method named `method_name` or not.
#[instrument(level = "debug", skip(self))]
pub fn method_exists(
pub fn method_exists_for_diagnostic(
Copy link
Contributor

Choose a reason for hiding this comment

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

I find the for_diagnostic suffix naming convention confusing. I think it means "method exists (as considered for diagnostic purposes)", rather than "method exists for this diagnostic"? It feels like there should be a contrasting method_exists_for_non_diagnostic method. I'm just not sure how to read it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it means "and you should only call this method if you're doing diagnostics".

Copy link
Member Author

Choose a reason for hiding this comment

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

Kinda don't want to change it though now lol

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I can live with it.

@nnethercote
Copy link
Contributor

r=me once we consider the for_diagnostic suffix. Is it necessary? I'm having trouble thinking of a better alternative.

@compiler-errors
Copy link
Member Author

Is it necessary?

Well I'd like to make it more difficult for people to call methods that aren't correct on the good path. It's not necessary per se, but we are really bad at modularizing diagnostics code in rustc_hir_typeck. If and once we finally do that, then it'll be self-explanatory due to (hopefully) mod privacy, but until then, I'd like to keep the suffix or give it a similar name that makes it sure the user knows that this obtusely named method is not meant for the good path.

@compiler-errors
Copy link
Member Author

This regressed in #120730, which added new calls to assemble_extension_candidates_for_traits_in_scope which significant increases the amount of work we are doing when calls to (e.g.) lookup_method_for_diagnostic, etc fail. Since this is on the error path, we call this a lot more times than on the good path.

Before 1.78, this file still takes a few seconds. After 1.78, it essentially hangs. After this PR, it should take less than a second.

@compiler-errors compiler-errors added the beta-nominated Nominated for backporting to the compiler in the beta channel. label May 14, 2024
@compiler-errors
Copy link
Member Author

compiler-errors commented May 14, 2024

Beta nominating as it can pretty negatively affect user experience when a programmer has many method errors in large projects.

For example: Slow edit_distance on Zulip

@@ -0,0 +1,157 @@
#![allow(non_snake_case)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Excellent that you have a test case! Please add a brief comment explaining what this is testing and pointing to this PR.

@nnethercote
Copy link
Contributor

r=me with the comment on the test. Thanks for fixing this!

@compiler-errors
Copy link
Member Author

@bors r=nnethercote

@bors
Copy link
Contributor

bors commented May 14, 2024

📌 Commit 8f97a25 has been approved by nnethercote

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 14, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request May 14, 2024
…mpiler-errors

Rollup of 7 pull requests

Successful merges:

 - rust-lang#119838 (style-guide: When breaking binops handle multi-line first operand better)
 - rust-lang#124844 (Use a proper probe for shadowing impl)
 - rust-lang#125047 (Migrate `run-make/issue-14500` to new `rmake.rs` format)
 - rust-lang#125080 (only find segs chain for missing methods when no available candidates)
 - rust-lang#125088 (Uplift `AliasTy` and `AliasTerm`)
 - rust-lang#125100 (Don't do post-method-probe error reporting steps if we're in a suggestion)
 - rust-lang#125118 (Use new utility functions/methods in run-make tests)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit d59f430 into rust-lang:master May 14, 2024
6 checks passed
@rustbot rustbot added this to the 1.80.0 milestone May 14, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request May 14, 2024
Rollup merge of rust-lang#125100 - compiler-errors:faster, r=nnethercote

Don't do post-method-probe error reporting steps if we're in a suggestion

Currently in method probing, if we fail to pick a method, then we reset and try to collect relevant candidates for method errors:

https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L953-L993

However, we do method lookups via `lookup_method_for_diagnostic` and only care about the result if the method probe was a *success*.

Namely, we don't need to do a bunch of other lookups on failure, since we throw away these results anyways, such as an expensive call to:

https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L959

And:
https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L985

---

This PR also renames some methods so it's clear that they're for diagnostics.

r? `@nnethercote`
@apiraino
Copy link
Contributor

Beta backport accepted as per compiler team on Zulip. A backport PR will be authored by the release team at the end of the current development cycle.

@rustbot label +beta-accepted

@rustbot rustbot added the beta-accepted Accepted for backporting to the compiler in the beta channel. label May 16, 2024
@cuviper cuviper mentioned this pull request May 16, 2024
@cuviper cuviper modified the milestones: 1.80.0, 1.79.0 May 16, 2024
@cuviper cuviper removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label May 16, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request May 17, 2024
[beta] backports

- Do not ICE on foreign malformed `diagnostic::on_unimplemented` rust-lang#124683
- Fix more ICEs in `diagnostic::on_unimplemented` rust-lang#124875
- rustdoc: use stability, instead of features, to decide what to show rust-lang#124864
- Don't do post-method-probe error reporting steps if we're in a suggestion rust-lang#125100
-  Make `non-local-def` lint Allow by default rust-lang#124950

r? cuviper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

None yet

6 participants