Skip to content

Conversation

@amandasystems
Copy link
Contributor

@amandasystems amandasystems commented Jun 17, 2025

This PR supersedes #130227. It removes precise tracking of placeholders in borrowck, moving them to an earlier stage. This leads to better performance, since we track less information. It is also part of the preparations for Polonius by moving specialised logic out of region inference itself and into the region graph or other, common pre-processing steps. Originally, the intention was to do this in multiple steps, but since some of them incur performance penalties won back by later stages, doing them in one go makes the net results clearer.

Error reporting changes

  1. Higher-kinded region errors (placeholder outliving a placeholder, etc) are only reported if there are no other borrowck errors.
  2. Due to the less precise nature of the revised tracking, there can be multiple overlapping errors involving the same placeholders/existential regions. In that case, not all errors will be reported. Crucially, only one pair per constraint graph SCC will be reported. A common case is Trait<r1, r2>, which frequently gives two error messages, one for each region. Under this logic it only gives one.
  3. In some cases, finding named regions to slot into diagnostics is now more difficult, since not all outlived named regions are traced. This degrades some diagnostics by replacing named regions with anonymous ones, or by picking differently named ones.
  4. In precisely one test, tests/ui/impl-trait/nested-rpit-hrtb.rs, we now also add r: 'static, which causes an extra error. Being more conservative when rewriting the constraint graph and avoiding it when invalid outlives are already detected breaks existing diagnostics for many, many tests that rely on the extra r: 'static to find out why they error.

Due to reason 2., several UI tests change, a lot, since they rely on diagnostic duplication being turned off to find several duplicate errors.

Code structure changes

  • Placeholder errors are now detected earlier, if they happen.
  • SCC annotations are dynamically chosen to be less rich for region graphs with no placeholders, opting to skip a lot of the logic. This is crucial for performance; both runtime and memory use, since it allows simple function bodies to skip some allocations and extra computation during SCC construction.
  • SCC annotations are now written in an update-style as opposed to the previous, more functional style. It seems to be more performant and it's certainly more succinct.

r? lcnr

@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 17, 2025
@rust-log-analyzer

This comment has been minimized.

@amandasystems
Copy link
Contributor Author

Wow, a merge conflict with upstream for a commit I JUST PUSHED, that's record time!

@amandasystems amandasystems force-pushed the early-placeholder-errors branch 2 times, most recently from fd18095 to 199f961 Compare June 17, 2025 15:11
@amandasystems amandasystems changed the title [WIP] Move placeholder error handling to before region inference Move placeholder error handling to before region inference Jun 25, 2025
@lcnr
Copy link
Contributor

lcnr commented Jul 3, 2025

@rustbot blocked

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 3, 2025
@amandasystems amandasystems force-pushed the early-placeholder-errors branch from 199f961 to 3a46042 Compare August 27, 2025 11:03
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from 3a46042 to 9b555d3 Compare August 27, 2025 19:44
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from 9b555d3 to f31393f Compare August 27, 2025 20:01
@amandasystems
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Aug 27, 2025
Comment on lines -26 to +16
= note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`...
= note: `Getter<'_>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'1>>`, for any two lifetimes `'0` and `'1`...
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hate this, but can't find a way around it. My gut feeling says it's another case of an order-dependent extraction procedure somewhere. For what it's worth, it wasn't in the earlier version of this code but it seems to have appeared after the recent changes to the base commit. Presumably the difference is from selecting smallest placeholder by rvid, etc. Help very much appreciated!

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from f31393f to f542ec5 Compare September 3, 2025 09:17
error_element
{
let adjusted_universe =
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
Copy link
Contributor Author

@amandasystems amandasystems Sep 3, 2025

Choose a reason for hiding this comment

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

I think the "checked sub" part is what really broke me here. Why are universes being adjusted? What's a base universe? And why can the subtraction sometimes overflow?!?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the record, these are the only reads of base_universe on CanonicalTypeOpDeeplyNormalizeGoal, CanonicalTypeOpAscribeUserTypeGoal and InstantiateOpaqueType.

@rust-log-analyzer

This comment has been minimized.

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from f542ec5 to 8269a42 Compare September 11, 2025 09:41
@rust-log-analyzer

This comment has been minimized.

@amandasystems
Copy link
Contributor Author

amandasystems commented Sep 11, 2025

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)

 95 | |         constraints.clone(),
 96 | |         &universal_region_relations,
 97 | |         infcx,
 98 | |     );
    | |_____- argument #4 of type `&mut RegionErrors<'_>` is missing
    |
note: function defined here
   --> compiler/rustc_borrowck/src/handle_placeholders.rs:306:15
    |
306 | pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
310 |     errors_buffer: &mut RegionErrors<'tcx>,
    |     --------------------------------------
help: provide the argument
    |
 94 -     let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints(
 95 -         constraints.clone(),
 96 -         &universal_region_relations,
 97 -         infcx,
 98 -     );
 94 +     let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints(constraints.clone(), &universal_region_relations, infcx, /* &mut RegionErrors<'_> */);
    |

For more information about this error, try `rustc --explain E0061`.
[RUSTC-TIMING] rustc_borrowck test:false 4.478
error: could not compile `rustc_borrowck` (lib) due to 1 previous error

I don't understand where these errors come from. On my branch every single commit passes the ./x check command. What's emitting these? The error refers to a line that doesn't exist in a file that doesn't look like that during any commit in the PR.

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from 8269a42 to e0b30fa Compare September 11, 2025 10:15
@rust-log-analyzer

This comment has been minimized.

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from c3bafae to fbe2418 Compare November 25, 2025 12:33
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lcnr
Copy link
Contributor

lcnr commented Nov 25, 2025

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Nov 25, 2025
@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Nov 25, 2025
Move placeholder error handling to before region inference
@rust-bors
Copy link
Contributor

rust-bors bot commented Nov 25, 2025

☀️ Try build successful (CI)
Build commit: e7d6bec (e7d6bec114ec0fed7e3ed6ccb2bf98d1385e8992, parent: 7934bbdf84a6b9a30297caf4f4f38286dedf876a)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (e7d6bec): comparison URL.

Overall result: ✅ improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.2% [-0.4%, -0.1%] 25
Improvements ✅
(secondary)
-0.3% [-0.9%, -0.1%] 38
All ❌✅ (primary) -0.2% [-0.4%, -0.1%] 25

Max RSS (memory usage)

Results (primary -0.4%, secondary -0.4%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.6% [0.6%, 0.6%] 1
Regressions ❌
(secondary)
0.6% [0.6%, 0.6%] 1
Improvements ✅
(primary)
-1.4% [-1.4%, -1.4%] 1
Improvements ✅
(secondary)
-1.4% [-1.4%, -1.4%] 1
All ❌✅ (primary) -0.4% [-1.4%, 0.6%] 2

Cycles

Results (secondary -7.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-7.1% [-7.1%, -7.1%] 1
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 472.579s -> 470.881s (-0.36%)
Artifact size: 386.92 MiB -> 386.91 MiB (-0.00%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Nov 25, 2025
@bors
Copy link
Collaborator

bors commented Dec 10, 2025

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

@amandasystems amandasystems force-pushed the early-placeholder-errors branch from fbe2418 to a9e1a79 Compare January 12, 2026 15:03
@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

This comment has been minimized.

- coroutine/auto-trait-regions.rs: also reformulate the test to make sure
 we don't miss errors -- just duplicate ones.
- traits/trait-upcasting/higher-ranked-upcasting-ub.rs: remove duplicate
 ERROR mismatched types
- ui/associated-types/associated-types-eq-hr.rs: remove 5 duplicate errors
  for "implementation not general enough" and mismatched types"
-  ui/borrowck/opaque-types-patterns-subtyping-ice-104779.rs: two redundant higher-ranked subtype errors
@amandasystems amandasystems force-pushed the early-placeholder-errors branch from a9e1a79 to 21ddce3 Compare January 15, 2026 14:58
@rust-log-analyzer

This comment has been minimized.

…ong enough"

This error is caused as a side-effect from added `r: 'static` constraints. It
should not be necessary, but beig less aggressive with rewriting breaks
many other diagnostics, and this is closer to the original logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants