diff --git a/kmir/src/kmir/kdist/mir-semantics/kmir.md b/kmir/src/kmir/kdist/mir-semantics/kmir.md index b85ee0002..ea3d2e418 100644 --- a/kmir/src/kmir/kdist/mir-semantics/kmir.md +++ b/kmir/src/kmir/kdist/mir-semantics/kmir.md @@ -562,7 +562,8 @@ Therefore a heuristics is used here: _SPAN ) => - #setTupleArgs(2, getValue(LOCALS, TUPLE)) ~> #execBlock(FIRST) + #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(getValue(LOCALS, CLOSURE))) + ~> #setTupleArgs(2, getValue(LOCALS, TUPLE)) ~> #execBlock(FIRST) // arguments are tuple components, stored as _2 .. _n ... diff --git a/kmir/src/tests/integration/data/prove-rs/iter-eq-copied-take-dereftruncate.rs b/kmir/src/tests/integration/data/prove-rs/iter-eq-copied-take-dereftruncate.rs new file mode 100644 index 000000000..75e7c1b9e --- /dev/null +++ b/kmir/src/tests/integration/data/prove-rs/iter-eq-copied-take-dereftruncate.rs @@ -0,0 +1,32 @@ +fn main() { + let _keep: fn() -> bool = repro; +} + +#[inline(never)] +#[no_mangle] +pub fn repro() -> bool { + let k0 = Pubkey([1; 32]); + let k1 = Pubkey([2; 32]); + let k2 = Pubkey([3; 32]); + let n = 2usize; + + let accounts = [ + AccountInfo { key: &k0 }, + AccountInfo { key: &k1 }, + AccountInfo { key: &k2 }, + ]; + let signers = [k1, k2, k0]; + + accounts[1..] + .iter() + .map(|signer| *signer.key) + .eq(signers.iter().take(n).copied()) +} + +#[derive(Clone)] +struct AccountInfo<'a> { + key: &'a Pubkey, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct Pubkey([u8; 32]); diff --git a/kmir/src/tests/integration/test_integration.py b/kmir/src/tests/integration/test_integration.py index 3014e4b04..945002873 100644 --- a/kmir/src/tests/integration/test_integration.py +++ b/kmir/src/tests/integration/test_integration.py @@ -38,6 +38,7 @@ 'assume-cheatcode-conflict-fail': ['check_assume_conflict'], 'transmute-bytes': ['bytes_to_u64', 'u64_to_bytes'], 'test_offset_from-fail': ['testing'], + 'iter-eq-copied-take-dereftruncate': ['repro'], } PROVE_RS_SHOW_SPECS = [ 'local-raw-fail',