Improve cause information for NLL higher-ranked errors#89249
Conversation
|
r? @estebank (rust-highfive has picked a reviewer for you, use r? to override) |
|
cc @estebank @lqd @matthewjasper @rust-lang/wg-compiler-nll |
|
@bors r+ |
|
📌 Commit ae4916bd3d0433eb2375068af42e0b4295279359 has been approved by |
|
This should probably have a perf run beforehand, now that I think about it. @bors r- |
|
@bors try @rust-timer queue |
|
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
|
⌛ Trying commit ae4916bd3d0433eb2375068af42e0b4295279359 with merge e155d2a2ad47d98b5b62f8b9fba9a9e7b4c6c2de... |
|
☀️ Try build successful - checks-actions |
|
Queued e155d2a2ad47d98b5b62f8b9fba9a9e7b4c6c2de with parent c09d637, future comparison URL. |
|
Finished benchmarking commit (e155d2a2ad47d98b5b62f8b9fba9a9e7b4c6c2de): comparison url. Summary: This change led to very large relevant regressions 😿 in compiler performance.
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never |
This PR has several interconnected pieces: 1. In some of the NLL region error code, we now pass around an `ObligationCause`, instead of just a plain `Span`. This gets forwarded into `fulfill_cx.register_predicate_obligation` during error reporting. 2. The general InferCtxt error reporting code is extended to handle `ObligationCauseCode::BindingObligation` 3. A new enum variant `ConstraintCategory::Predicate` is added. We try to avoid using this as the 'best blame constraint' - instead, we use it to enhance the `ObligationCause` of the `BlameConstraint` that we do end up choosing. As a result, several NLL error messages now contain the same "the lifetime requirement is introduced here" message as non-NLL errors. Having an `ObligationCause` available will likely prove useful for future improvements to NLL error messages.
This shirnks the size of `ConstraintCategory`, hopefully fixing a performance regression.
ae4916b to
41ad383
Compare
|
@bors try @rust-timer queue |
|
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
|
⌛ Trying commit 41ad383 with merge b13e7a00e877f93c9b85b09fddfef60e03d9d07b... |
|
☀️ Try build successful - checks-actions |
|
Queued b13e7a00e877f93c9b85b09fddfef60e03d9d07b with parent 3e8f32e, future comparison URL. |
|
Finished benchmarking commit (b13e7a00e877f93c9b85b09fddfef60e03d9d07b): comparison url. Summary: This change led to small relevant regressions 😿 in compiler performance.
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never |
|
@estebank The regressions are now much smaller. Can you review the latest commit? |
| // We currentl'y doesn't store the `DefId` in the `ConstraintCategory` | ||
| // for perforamnce reasons. The error reporting code used by NLL only | ||
| // uses the span, so this doesn't cause any problems at the moment. | ||
| Some(ObligationCauseCode::BindingObligation( | ||
| CRATE_DEF_ID.to_def_id(), | ||
| predicate_span, | ||
| )) |
There was a problem hiding this comment.
We should create a new ObligationCauseCode variant instead, but it's fine to do this I guess.
There was a problem hiding this comment.
I was trying to mimic the non-NLL code, which also uses ObligationCauseCode::BindingObligation for this message:
rust/compiler/rustc_infer/src/infer/error_reporting/note.rs
Lines 396 to 405 in 2b6ed3b
| // Make sure this enum doesn't unintentionally grow | ||
| rustc_data_structures::static_assert_size!(ConstraintCategory, 12); | ||
|
|
|
@bors r+ The performance impact seems small, but I'm sure the perf triage team can make a better determination about it. It seems to me that the majority of the impact is due to tracking extra metadata. It's a shame it doesn't impact "only" the NLL errors. |
|
📌 Commit 41ad383 has been approved by |
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (8a12be7): comparison url. Summary: This benchmark run did not return any relevant changes. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression |
…ath, r=JohnTitor borrowck: Introduce BlameConstraint::to_obligation_cause_from_path() Before this commit, `BlameConstraint` is a bit hard to understand at first, because of its `ObligationCause` field. In practice, `BlameConstraint` is just a slimmed down version of an `OutlivesConstraint` from `Vec<OutlivesConstraint>`. The artificial `ObligationCause` is only needed in one place. Rather than having that exception polute the lower level logic, bubble it up as much as we can. That way, it becomes clearer what `BlameConstraint` actually is. For reference, `ObligationCause` was introdued by rust-lang#89249, but the codebase looked quite different back then. This takes us one step closer (this is commit 1 of 4) towards the end result illustrated in rust-lang#158623. # Notes I have removed the comment ```rs // We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint. // Instead, we use it to produce an improved `ObligationCauseCode`. ```` because I think [this](https://github.com/rust-lang/rust/blob/e2af9c03ef4cfb769e391968a5cfbb1afe6f01e2/compiler/rustc_borrowck/src/region_infer/mod.rs#L1763-L1762) existing comment is sufficient: ```rs // We handle predicates and opaque types specially; don't prioritize them here. ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4, ```
…ath, r=JohnTitor borrowck: Introduce BlameConstraint::to_obligation_cause_from_path() Before this commit, `BlameConstraint` is a bit hard to understand at first, because of its `ObligationCause` field. In practice, `BlameConstraint` is just a slimmed down version of an `OutlivesConstraint` from `Vec<OutlivesConstraint>`. The artificial `ObligationCause` is only needed in one place. Rather than having that exception polute the lower level logic, bubble it up as much as we can. That way, it becomes clearer what `BlameConstraint` actually is. For reference, `ObligationCause` was introdued by rust-lang#89249, but the codebase looked quite different back then. This takes us one step closer (this is commit 1 of 4) towards the end result illustrated in rust-lang#158623. # Notes I have removed the comment ```rs // We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint. // Instead, we use it to produce an improved `ObligationCauseCode`. ```` because I think [this](https://github.com/rust-lang/rust/blob/e2af9c03ef4cfb769e391968a5cfbb1afe6f01e2/compiler/rustc_borrowck/src/region_infer/mod.rs#L1763-L1762) existing comment is sufficient: ```rs // We handle predicates and opaque types specially; don't prioritize them here. ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4, ```
…ath, r=JohnTitor borrowck: Introduce BlameConstraint::to_obligation_cause_from_path() Before this commit, `BlameConstraint` is a bit hard to understand at first, because of its `ObligationCause` field. In practice, `BlameConstraint` is just a slimmed down version of an `OutlivesConstraint` from `Vec<OutlivesConstraint>`. The artificial `ObligationCause` is only needed in one place. Rather than having that exception polute the lower level logic, bubble it up as much as we can. That way, it becomes clearer what `BlameConstraint` actually is. For reference, `ObligationCause` was introdued by rust-lang#89249, but the codebase looked quite different back then. This takes us one step closer (this is commit 1 of 4) towards the end result illustrated in rust-lang#158623. # Notes I have removed the comment ```rs // We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint. // Instead, we use it to produce an improved `ObligationCauseCode`. ```` because I think [this](https://github.com/rust-lang/rust/blob/e2af9c03ef4cfb769e391968a5cfbb1afe6f01e2/compiler/rustc_borrowck/src/region_infer/mod.rs#L1763-L1762) existing comment is sufficient: ```rs // We handle predicates and opaque types specially; don't prioritize them here. ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4, ```
Rollup merge of #158624 - Enselic:to_obligation_cause_from_path, r=JohnTitor borrowck: Introduce BlameConstraint::to_obligation_cause_from_path() Before this commit, `BlameConstraint` is a bit hard to understand at first, because of its `ObligationCause` field. In practice, `BlameConstraint` is just a slimmed down version of an `OutlivesConstraint` from `Vec<OutlivesConstraint>`. The artificial `ObligationCause` is only needed in one place. Rather than having that exception polute the lower level logic, bubble it up as much as we can. That way, it becomes clearer what `BlameConstraint` actually is. For reference, `ObligationCause` was introdued by #89249, but the codebase looked quite different back then. This takes us one step closer (this is commit 1 of 4) towards the end result illustrated in #158623. # Notes I have removed the comment ```rs // We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint. // Instead, we use it to produce an improved `ObligationCauseCode`. ```` because I think [this](https://github.com/rust-lang/rust/blob/e2af9c03ef4cfb769e391968a5cfbb1afe6f01e2/compiler/rustc_borrowck/src/region_infer/mod.rs#L1763-L1762) existing comment is sufficient: ```rs // We handle predicates and opaque types specially; don't prioritize them here. ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4, ```
This PR has several interconnected pieces:
around an
ObligationCause, instead of just a plainSpan.This gets forwarded into
fulfill_cx.register_predicate_obligationduring error reporting.
handle
ObligationCauseCode::BindingObligationConstraintCategory::Predicateis added.We try to avoid using this as the 'best blame constraint' - instead,
we use it to enhance the
ObligationCauseof theBlameConstraintthat we do end up choosing.
As a result, several NLL error messages now contain the same
"the lifetime requirement is introduced here" message as non-NLL
errors.
Having an
ObligationCauseavailable will likely prove usefulfor future improvements to NLL error messages.