Skip to content

Commit 7e4ecd9

Browse files
authored
Fix array closurization just forgetting common contracts (#1678)
* Fix array closurization just forgetting common contracts * Reduce the number of iterator combinators
1 parent 97e18af commit 7e4ecd9

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

core/src/eval/operation.rs

+31-13
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
18361836

18371837
// We basically compute the intersection (`ctr_common`),
18381838
// `ctrs_left - ctr_common`, and `ctrs_right - ctr_common`.
1839-
let ctrs_left : Vec<_> =
1839+
let ctrs_left_dedup : Vec<_> =
18401840
ctrs_left
18411841
.into_iter()
18421842
.filter(|ctr| {
@@ -1851,20 +1851,38 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
18511851
initial_env: &self.initial_env,
18521852
};
18531853

1854+
// We check if there is a remaining contract in
1855+
// `ctrs_right_sieve` which matches `ctr`: in this case,
1856+
// `twin_index` will hold its index.
18541857
let twin_index = ctrs_right_sieve
18551858
.iter()
1856-
.filter_map(|ctr| ctr.as_ref())
18571859
.position(|other_ctr| {
1858-
let envs_right = EvalEnvsRef {
1859-
eval_env: &env2,
1860-
initial_env: &self.initial_env,
1861-
};
1862-
1863-
contract_eq::<EvalEnvsRef>(0, &ctr.contract, envs_left, &other_ctr.contract, envs_right)
1864-
});
1860+
other_ctr
1861+
.as_ref()
1862+
.map_or(false, |other_ctr| {
1863+
let envs_right = EvalEnvsRef {
1864+
eval_env: &env2,
1865+
initial_env: &self.initial_env,
1866+
};
1867+
1868+
contract_eq::<EvalEnvsRef>(
1869+
0,
1870+
&ctr.contract,
1871+
envs_left,
1872+
&other_ctr.contract,
1873+
envs_right,
1874+
)
1875+
})
1876+
});
18651877

18661878
if let Some(index) = twin_index {
1867-
ctrs_right_sieve[index] = None;
1879+
// unwrap(): we know that the contract at this index is
1880+
// `Some`, because all elements are initially some when
1881+
// creating `ctrs_right_sieve` and then we don't
1882+
// consider `None` values when computing a new `index`
1883+
// in the `position` above.
1884+
let common = ctrs_right_sieve[index].take().unwrap();
1885+
ctrs_common.push(common);
18681886
false
18691887
}
18701888
else {
@@ -1873,15 +1891,15 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
18731891
})
18741892
.collect();
18751893

1876-
let ctrs_right = ctrs_right_sieve.into_iter().flatten();
1894+
let ctrs_right_dedup = ctrs_right_sieve.into_iter().flatten();
18771895

18781896
ts.extend(ts1.into_iter().map(|t|
1879-
RuntimeContract::apply_all(t, ctrs_left.iter().cloned(), pos1)
1897+
RuntimeContract::apply_all(t, ctrs_left_dedup.iter().cloned(), pos1)
18801898
.closurize(&mut self.cache, &mut env, env1.clone())
18811899
));
18821900

18831901
ts.extend(ts2.into_iter().map(|t|
1884-
RuntimeContract::apply_all(t, ctrs_right.clone(), pos2)
1902+
RuntimeContract::apply_all(t, ctrs_right_dedup.clone(), pos2)
18851903
.closurize(&mut self.cache, &mut env, env2.clone())
18861904
));
18871905

0 commit comments

Comments
 (0)