From 1dbed2138c75b82c1efb3a7cc2d731da9a5dda13 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 18 Mar 2024 13:43:53 -0700 Subject: [PATCH] Fix Rust Proto cpp-kernel map insertion behavior to better match Rust's std::HashMap and the upb-kernel behavior of "insert replaces the old value" PiperOrigin-RevId: 616934577 --- rust/cpp_kernel/cpp_api.h | 3 +++ rust/map.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/rust/cpp_kernel/cpp_api.h b/rust/cpp_kernel/cpp_api.h index 409d169b31..3d82472d54 100644 --- a/rust/cpp_kernel/cpp_api.h +++ b/rust/cpp_kernel/cpp_api.h @@ -86,6 +86,9 @@ struct PtrAndLen { bool __rust_proto_thunk__Map_##rust_key_ty##_##rust_value_ty##_insert( \ google::protobuf::Map* m, ffi_key_ty key, ffi_value_ty value) { \ auto iter_and_inserted = m->try_emplace(to_cpp_key, to_cpp_value); \ + if (!iter_and_inserted.second) { \ + iter_and_inserted.first->second = to_cpp_value; \ + } \ return iter_and_inserted.second; \ } \ bool __rust_proto_thunk__Map_##rust_key_ty##_##rust_value_ty##_get( \ diff --git a/rust/map.rs b/rust/map.rs index 53be666973..383c76b12a 100644 --- a/rust/map.rs +++ b/rust/map.rs @@ -528,6 +528,20 @@ mod tests { ); } + #[test] + fn test_overwrite_insert() { + let mut map: Map = Map::new(); + let mut map_mut = map.as_mut(); + assert!(map_mut.insert(0, "fizz")); + // insert should return false when the key is already present + assert!(!map_mut.insert(0, "buzz")); + + assert_that!( + map.as_mut().iter().collect::>(), + unordered_elements_are![eq((0, ProtoStr::from_str("buzz"))),] + ); + } + #[test] fn test_all_maps_can_be_constructed() { macro_rules! gen_proto_values {