Skip to content

Simulate NLL and Polonius Alpha borrowck - #411

Merged
nikomatsakis merged 3 commits into
mainfrom
nll
Jul 24, 2026
Merged

Simulate NLL and Polonius Alpha borrowck#411
nikomatsakis merged 3 commits into
mainfrom
nll

Conversation

@jackh726

@jackh726 jackh726 commented Jul 5, 2026

Copy link
Copy Markdown
Member

Background and Motivation

As we move towards stabilization of Polonius Alpha in rustc, we want to be confident in its soundness. formality already has an existing borrow-checker, although in many ways is both closer to an "ideal" borrow checker, but is also incomplete in some areas of the language, e.g. opaque types.

In the rustc test suite, we have a number of tests that are specifically different between NLL, Polonius Alpha, and Polonius Legacy. These specifically highlight the differences between these three borrow-checking modes.

In this PR, those tests are ported to formality tests. Further, feature gating is done to match formality's borrow-checking modes to rustc's - along with a few other minor adjustments to bring consistency with rustc.

A non-goal of this work is to model any one complete borrow-checker for all language features (including those not yet modeled by formality). Specifically, the ported tests are sufficient to model the differences between the existing NLL and the soon-to-be-stabilized Polonius Alpha. It is possible that unimplemented language features interact in significant ways with the model - but the idea is that those differences are likely downstream of the differences visible under the ported tests. So, aligning with rustc for the currently-implemented language features is enough for us to reason about the soundness of Polonius Alpha.

What this PR does

  • Add PoloniusUnlocked feature gate
  • Collects all outlives constraints while borrow-checking
  • Redo borrowck with all outlives for NLL (at exists boundaries)
  • Port rustc tests where polonius alpha differs from nll or legacy
  • In nll and alpha, consider place prefix as live
  • Do not add function def places as live
  • Kill loans from dropped locals
  • Add outlives constraints for reborrows
  • Verify universal outlives constraints for all outlives in alpha
  • Make <TypeckEnv as Debug> not print Program

This is a little unfortunate on performance, because it essentially duplicates all borrow checking - because we need a first pass just to collect outlives constraints. There are a couple alternatives, I think:

  • Create a separate pass that only collects outlives constraints per-point, use this for the NLL pass
  • Do some caching or something where things are not rerun if there are no additional outlives constraints
rustc test formality test nll alpha unlocked
issue-46589 trigger_bug issue_46589_trigger_bug — (ignored, see test comments)
63908 remove_last_node_recursive issue_63908_remove_last_node_recursive ✓ pass ✓ pass ✓ pass
63908 remove_last_node_iterative issue_63908_remove_last_node_iterative ✓ error ✓ error ✓ pass
57165 no_control_flow issue_57165_no_control_flow ✓ pass ✓ pass ✓ pass
57165 conditional issue_57165_conditional ✓ error ✓ error ✓ pass
57165 conditional_with_indirection issue_57165_conditional_with_indirection ✓ pass ✓ pass ✓ pass
46859 to_refs issue_46859_to_refs ✓ pass ✓ pass ✓ pass
46859 to_refs2 issue_46859_to_refs2 ✓ pass ✓ pass ✓ pass
46859 to_refs3 (need to PR) issue_46859_to_refs3 ✓ pass ✓ pass ✓ pass
46859 Decoder::next issue_46859_decoder_next ✓ error ✓ pass ✓ pass
92985 Filter::next issue_92985_filtering_lending_iterator ✓ error ✓ pass ✓ pass
flow-sensitive-invariance use_it flow_sensitive_invariance_use_it ✓ error ✓ error ✓ pass
flow-sensitive-invariance use_it_but_its_the_same_region flow_sensitive_invariance_same_region ✓ pass ✓ pass ✓ pass
(companion, no rustc equivalent) flow_sensitive_invariance_use_both error error error
issue-70044 issue_70044_location_insensitive_constraints — (ignored, see test comments)

AI disclosure

  • I used an AI tool for rote or minor changes (e.g., refactoring, autocomplete)
  • I used an AI to author the main logic of the code

@rustbot

rustbot commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

Thanks for contributing to formality! :)
A reviewer will take a look at your PR within a week or two. If not, come talk to us on https://rust-lang.zulipchat.com/#narrow/channel/402470-t-types.2Fformality

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@jackh726 jackh726 changed the title WIP: Simulate NLL borrowck Simulate NLL and Polonius Alpha borrowck Jul 13, 2026
@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

jackh726 added 2 commits July 22, 2026 13:28
- Add PoloniusUnlocked feature gate
- Redo borrowck with all outlives for NLL
- Port rustc tests where polonius alpha differs from nll or legacy
- In nll and alpha, consider place prefix as live
- Do not add function def places as live
- Kill loans from dropped locals
- Add outlives constraints for reborrows
- Verify universal outlives constraints for all outlives in alpha
@rustbot

rustbot commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

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.

@nikomatsakis nikomatsakis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor nits but r=me

View changes since this review

Comment thread crates/formality-rust/src/check/borrow_check/nll.rs Outdated
// Prescan for locals declared in this list so that later uses of
// those names are treated as locals, not fn names. (This slightly
// over-approximates scope — a name is treated as local even before
// its `let` — which errs toward marking places live.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I---- oh, we do some kind of "simple name resolution" here, I guess?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess that's ok

@nikomatsakis
nikomatsakis added this pull request to the merge queue Jul 24, 2026
Merged via the queue into main with commit c490389 Jul 24, 2026
4 checks passed
@rustbot rustbot mentioned this pull request Jul 24, 2026
@jackh726
jackh726 deleted the nll branch July 24, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants