Close non-last parameter types of function templates - #236
Merged
Conversation
`FunctionTemplateTypeBuilder::build` gave a non-last parameter's type the scope of the parameters before it. Nothing in that type carries a template except an enum's type arguments, which `TemplateTypeBuilder::build` refines via `build_refined`; for a parameter whose type contains a generic enum the scope therefore leaked into the resulting type and left it open. `BasicBlockType::params` holds the enclosing function's arguments, and `analyze::basic_block` instantiates each of them against the caller's variable through `assert_closed`. A generic enum in any parameter but the last one thus aborted with "unexpected variable" as soon as the body had a block needing its own precondition. Build such a parameter without the scope, as the last parameter's own type is already built inside `build_refined`. Fixes #235 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3XpZ2MXjgs3JoodCr8iA9
Contributor
There was a problem hiding this comment.
Pull request overview
Closes generic-enum refinements in non-last function parameters, preventing assert_closed panics during branching analysis.
Changes:
- Builds non-last parameter types without leaking the function-template scope.
- Adds paired UI tests covering successful and unsatisfiable
Optionparameter cases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/refine/template.rs |
Builds nested templates with an empty scope and converts the resulting closed type. |
tests/ui/pass/option_param_order.rs |
Verifies correct branching with a non-last Option parameter. |
tests/ui/fail/option_param_order.rs |
Confirms an invalid assertion remains rejected. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Fixes #235.
FunctionTemplateTypeBuilder::buildgave a non-last parameter's type the scope of the parameters before it. Nothing in that type carries a template except an enum's type arguments, whichTemplateTypeBuilder::buildrefines viabuild_refined, so for a parameter whose type contains a generic enum the scope leaked into the resulting type and left it open.BasicBlockType::paramsholds the enclosing function's arguments, andanalyze::basic_blockinstantiates each of them against the caller's variable throughassert_closed. A generic enum in any parameter but the last one therefore aborted withunexpected variableas soon as the body had a block needing its own precondition:This builds such a parameter without the scope. The last parameter's own type is already built that way inside
build_refined— only its refinement is scoped — so the two paths now agree.The alternative repair sketched in the issue (carrying the enum-argument templates through the basic-block parameter instead of calling
assert_closed) is not taken here: the scope only ever reached enum type arguments, incidentally, and it never reached the last parameter's type at all, so dropping it is the smaller and more consistent change.Testing
tests/ui/{pass,fail}/option_param_order.rs: theget_orshape above, with thefailfile breaking only theNone-case assertion. Both ICE (exit 101) onmainand pass here.safe, including the&self-method shape, and the three soundness spot-checks it lists are still rejected asUnsat.cargo test: 326 UI tests, 2 doc-tests passing;cargo fmt --checkclean.Generated by Claude Code