Allow non-return ZST places to appear without proceding defs in BB#42
Allow non-return ZST places to appear without proceding defs in BB#42
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes issue #38 where optimized MIR can contain ZST locals (e.g., no-capture closures stored in struct fields) that are used in bb0 without any preceding definition, which previously caused local_def::Analyzer::assert_entry to fail during entry-type elaboration.
Changes:
- Add UI regression tests covering calling a closure stored in a struct field (pass + fail cases).
- Update
local_def::Analyzer::elaborate_unused_argsto ignore certain locals in START block parameter elaboration.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
tests/ui/pass/closure_field_1.rs |
Adds a passing regression test for closure-in-struct-field call pattern. |
tests/ui/fail/closure_field_1.rs |
Adds a failing (Unsat) counterpart regression test. |
src/analyze/local_def.rs |
Adjusts entry basic-block parameter elaboration to skip additional locals (intended for ZST-without-def cases). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/analyze/local_def.rs
Outdated
| // BBs may use locals without preceeding def when they're ZST | ||
| if param_local == mir::RETURN_PLACE || param_local > self.body.arg_count.into() { | ||
| subst.extend( |
There was a problem hiding this comment.
The condition param_local > self.body.arg_count.into() skips all non-argument locals, but the comment/PR intent says this should only apply to locals that can legally appear without a preceding definition (i.e., ZSTs like no-capture closures). As written, if a non-ZST local ever appears here, it will be treated as skippable and can break the param index substitution (later refinements may still reference that param). Consider gating this branch on an explicit ZST check (e.g., via tcx.layout_of(...).size == 0 / is_zst) in addition to param_local > arg_count (and keeping RETURN_PLACE as the special case).
3e9396f to
e00fe7f
Compare
fix #38
Closures without upvars are treated as a ZST. Given the MIR below,
_1is a ZST and is used without proceeding defs in bb0.Because
_1has no preceding definitions, bb0 has the type(_0: (), _1: (own (), )) → (), where _1 is left as a live local. However, since_1is not a function parameter in this case, local_def::Analyzer::elaborate_unused_args needs to ignore_1within the arguments of bb0.