diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/data.md b/kmir/src/kmir/kdist/mir-semantics/rt/data.md
index df6203ea4..5839521b4 100644
--- a/kmir/src/kmir/kdist/mir-semantics/rt/data.md
+++ b/kmir/src/kmir/kdist/mir-semantics/rt/data.md
@@ -1921,6 +1921,9 @@ Zero-sized types can be decoded trivially into their respective representation.
// zero-sized array
rule #decodeConstant(constantKindZeroSized, _TY, typeInfoArrayType(_, _))
=> Range(.List) ...
+ // zero-sized function item (e.g., closures without captures)
+ rule #decodeConstant(constantKindZeroSized, _TY, typeInfoFunType(_))
+ => Aggregate(variantIdx(0), .List) ...
```
Allocated constants of reference type with a single provenance map entry are decoded as references
diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/types.md b/kmir/src/kmir/kdist/mir-semantics/rt/types.md
index 31ad4f915..aaf854c13 100644
--- a/kmir/src/kmir/kdist/mir-semantics/rt/types.md
+++ b/kmir/src/kmir/kdist/mir-semantics/rt/types.md
@@ -348,8 +348,9 @@ Slices, `str`s and dynamic types require it, and any `Ty` that `is_sized` does
rule #zeroSizedType(typeInfoTupleType(.Tys, _)) => true
rule #zeroSizedType(typeInfoStructType(_, _, .Tys, _)) => true
rule #zeroSizedType(typeInfoVoidType) => true
- // FIXME: Only unit tuples, empty structs, and void are recognized here; other
- // zero-sized types (e.g. single-variant enums, function or closure items,
+ rule #zeroSizedType(typeInfoFunType(_)) => true
+ // FIXME: Only unit tuples, empty structs, void, and function items are
+ // recognized here; other zero-sized types (e.g. single-variant enums,
// newtype wrappers around ZSTs) still fall through because we do not consult
// the layout metadata yet. Update once we rely on machineSize(0).
rule #zeroSizedType(_) => false [owise]
diff --git a/kmir/src/tests/integration/test_integration.py b/kmir/src/tests/integration/test_integration.py
index ba7faccec..9d2e43496 100644
--- a/kmir/src/tests/integration/test_integration.py
+++ b/kmir/src/tests/integration/test_integration.py
@@ -41,6 +41,9 @@
'iter-eq-copied-take-dereftruncate': ['repro'],
'spl-multisig-iter-eq-copied-next': ['repro'],
}
+PROVE_TERMINATE_ON_THUNK = [
+ 'closure-staged',
+]
PROVE_SHOW_SPECS = [
'local-raw-fail',
'interior-mut-fail',
@@ -87,7 +90,8 @@ def test_prove(rs_file: Path, kmir: KMIR, update_expected_output: bool) -> None:
if update_expected_output and not should_show:
pytest.skip()
- prove_opts = ProveOpts(rs_file, smir=is_smir)
+ should_terminate_on_thunk = rs_file.stem in PROVE_TERMINATE_ON_THUNK
+ prove_opts = ProveOpts(rs_file, smir=is_smir, terminate_on_thunk=should_terminate_on_thunk)
printer = PrettyPrinter(kmir.definition)
cterm_show = CTermShow(printer.print)