diff --git a/soroban-env-host/src/host.rs b/soroban-env-host/src/host.rs index 32fc9b3f3..5553f3c5c 100644 --- a/soroban-env-host/src/host.rs +++ b/soroban-env-host/src/host.rs @@ -1146,20 +1146,25 @@ impl EnvBase for Host { } fn map_new_from_slices(&self, keys: &[&str], vals: &[Val]) -> Result { - Vec::::charge_bulk_init_cpy(keys.len() as u64, self)?; - // If only fallible iterators worked better in Rust, we would not need this Vec<...>. - let mut key_syms: Vec = Vec::with_capacity(keys.len()); - for k in keys.iter() { - key_syms.push(Symbol::try_from_val(self, k)?); - } - for v in vals.iter() { - self.check_val_integrity(*v)?; + if keys.len() != vals.len() { + return Err(self.err( + ScErrorType::Object, + ScErrorCode::UnexpectedSize, + "differing key and value slice lengths when creating map from slices", + &[], + )); } - let pair_iter = key_syms + Vec::<(Val, Val)>::charge_bulk_init_cpy(keys.len() as u64, self)?; + let map_vec = keys .iter() - .map(|s| s.to_val()) - .zip(vals.iter().cloned()); - let map = HostMap::from_exact_iter(pair_iter, self)?; + .zip(vals.iter().copied()) + .map(|(key_str, val)| { + let sym = Symbol::try_from_val(self, key_str)?; + self.check_val_integrity(val)?; + Ok((sym.to_val(), val)) + }) + .collect::, HostError>>()?; + let map = HostMap::from_map(map_vec, self)?; self.add_host_object(map) } @@ -1173,7 +1178,7 @@ impl EnvBase for Host { return Err(self.err( ScErrorType::Object, ScErrorCode::UnexpectedSize, - "differing key and value vector lengths when unpacking map to slice", + "differing key and value slice lengths when unpacking map to slice", &[], )); } @@ -1182,7 +1187,7 @@ impl EnvBase for Host { return Err(self.err( ScErrorType::Object, ScErrorCode::UnexpectedSize, - "differing host map and output vector lengths when unpacking map to slice", + "differing host map and output slice lengths when unpacking map to slice", &[], )); }