Take the precondition of the entry block from the signature - #226
Draft
coord-e wants to merge 1 commit into
Draft
Conversation
The entry block took a template for its precondition, which
`assert_entry` then bounded from below by the precondition of the
function. Install the precondition of the function directly, equating
each parameter with the value it has on entry, which is what the
predicate variable stood for.
The parameter types come from the signature as well, so that refinements
written in it reach the block: a refinement nested in a type
(`Vec<{ v: i32 | v > 0 }>`) or the contract of a function-typed
parameter has nowhere else to come from once `assert_entry` is gone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P7MyQbvfkfNy1h7yeN553N
This was referenced Aug 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of three, each removing one predicate variable that stood for a fact the constraints already state elsewhere. The other two build on this one: #227 (the type of a call) and #224 (the state at a join).
The entry block took a template for its precondition, which
assert_entrythen bounded from below by the precondition of the function. Nothing else constrained it, so the predicate variable stood for the precondition of the function and nothing more. It is installed directly instead, equating each parameter with the value it has on entry (BasicBlockTypeParamKind::OuterFnParam), which is what the least solution of the removed predicate variable gave.The parameter types now come from the signature as well (
install_signature_types). Onceassert_entryis gone, a refinement written in the signature has nowhere else to reach the block from: a refinement nested in a type (Vec<{ v: i32 | v > 0 }>) would be dropped, and the contract of a function-typed parameter would be replaced by a fresh, unconstrained predicate variable that a solver may read asfalse— unsound.tests/ui/pass/fn_ptr.rsandtests/ui/pass/refine_param_*.rscover both.assert_entryand what only it used (relate_sub_param_types,truncate_outer_fn_params,drop_bb_zst_params,drop_unused_expected_params) go with it.Effect
Over
tests/ui/pass(160 files), predicate variables generated: 1691 → 1293.Notes for review
Two steps carry the soundness of this change and are worth a second pair of eyes:
OuterFnParamcopy inentry_precondition— without it the postcondition of a function loses its footing on the entry values;install_signature_types, per the paragraph above; its absence fails loudly for a nested refinement but silently and unsoundly for a function-typed parameter.316 tests pass.