From e00fe7fc4d5b4f0e1904ac2631a5f3ff0775b360 Mon Sep 17 00:00:00 2001 From: coord_e Date: Sun, 8 Feb 2026 01:03:46 +0900 Subject: [PATCH] Allow non-return ZST places to appear without proceding defs in BB --- src/analyze/local_def.rs | 6 +++--- tests/ui/fail/closure_field_1.rs | 14 ++++++++++++++ tests/ui/pass/closure_field_1.rs | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 tests/ui/fail/closure_field_1.rs create mode 100644 tests/ui/pass/closure_field_1.rs diff --git a/src/analyze/local_def.rs b/src/analyze/local_def.rs index 67033eb..60bffa9 100644 --- a/src/analyze/local_def.rs +++ b/src/analyze/local_def.rs @@ -720,8 +720,8 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { let mut subst = HashMap::new(); for (param_idx, param_ty) in bb_ty.as_ref().params.iter_enumerated() { if let Some(param_local) = bb_ty.local_of_param(param_idx) { - // unit return may use _0 without preceeding def - if param_local == mir::RETURN_PLACE { + // BBs may use locals without preceding def when they're ZST + if param_local == mir::RETURN_PLACE || param_local > self.body.arg_count.into() { subst.extend( bb_ty .as_ref() @@ -730,7 +730,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { .skip_while(|idx| idx.index() <= param_idx.index()) .map(|idx| (idx, idx + 1)), ); - if bb_ty.as_ref().params.len() == 1 { + if bb_ty.as_ref().params.len() - 1 == param_idx.index() { params.push(rty::RefinedType::new( rty::Type::unit(), param_ty.refinement.clone(), diff --git a/tests/ui/fail/closure_field_1.rs b/tests/ui/fail/closure_field_1.rs new file mode 100644 index 0000000..9438a9e --- /dev/null +++ b/tests/ui/fail/closure_field_1.rs @@ -0,0 +1,14 @@ +//@error-in-other-file: Unsat +//@compile-flags: -C debug-assertions=off + +struct S { + f: F, +} + +fn main() { + let s = S { + f: |x: i32| x + 1, + }; + let x = (s.f)(1); + assert!(x == 1); +} diff --git a/tests/ui/pass/closure_field_1.rs b/tests/ui/pass/closure_field_1.rs new file mode 100644 index 0000000..9b872d5 --- /dev/null +++ b/tests/ui/pass/closure_field_1.rs @@ -0,0 +1,14 @@ +//@check-pass +//@compile-flags: -C debug-assertions=off + +struct S { + f: F, +} + +fn main() { + let s = S { + f: |x: i32| x + 1, + }; + let x = (s.f)(1); + assert!(x == 2); +}