From d56d9e3b046ce30bbffc834ceccb23446eff7ad9 Mon Sep 17 00:00:00 2001 From: ortem Date: Mon, 5 Oct 2020 14:03:26 +0300 Subject: [PATCH] Update HashMap/HashSet pretty-printers to Rust 1.47 The corresponding PRs in rustc: https://github.com/rust-lang/rust/pull/76458 https://github.com/rust-lang/rust/pull/70052 --- prettyPrinters/gdb_lookup.py | 4 ++-- prettyPrinters/gdb_providers.py | 25 ++++++++++++++++++++--- prettyPrinters/lldb_lookup.py | 2 +- prettyPrinters/lldb_providers.py | 27 +++++++++++++++++++++---- pretty_printers_tests/tests/hash_map.rs | 2 -- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/prettyPrinters/gdb_lookup.py b/prettyPrinters/gdb_lookup.py index d2da7bca3c4..422579fbbbc 100644 --- a/prettyPrinters/gdb_lookup.py +++ b/prettyPrinters/gdb_lookup.py @@ -65,9 +65,9 @@ def lookup(valobj): else: return StdOldHashMapProvider(valobj) if rust_type == RustType.STD_HASH_SET: - hash_map = valobj["map"] + hash_map = valobj[valobj.type.fields()[0]] if is_hashbrown_hashmap(hash_map): - return StdHashMapProvider(hash_map, show_values=False) + return StdHashMapProvider(valobj, show_values=False) else: return StdOldHashMapProvider(hash_map, show_values=False) diff --git a/prettyPrinters/gdb_providers.py b/prettyPrinters/gdb_providers.py index 1cdd518f55b..2b1aa7ab015 100644 --- a/prettyPrinters/gdb_providers.py +++ b/prettyPrinters/gdb_providers.py @@ -350,13 +350,18 @@ def __init__(self, valobj, show_values=True): self.valobj = valobj self.show_values = show_values - table = self.valobj["base"]["table"] + table = self.table() capacity = int(table["bucket_mask"]) + 1 ctrl = table["ctrl"]["pointer"] self.size = int(table["items"]) - self.data_ptr = table["data"]["pointer"] - self.pair_type = self.data_ptr.dereference().type + self.pair_type = table.type.template_argument(0).strip_typedefs() + + self.new_layout = not table.type.has_key("data") + if self.new_layout: + self.data_ptr = ctrl.cast(self.pair_type.pointer()) + else: + self.data_ptr = table["data"]["pointer"] self.valid_indices = [] for idx in range(capacity): @@ -366,6 +371,18 @@ def __init__(self, valobj, show_values=True): if is_presented: self.valid_indices.append(idx) + def table(self): + if self.show_values: + hashbrown_hashmap = self.valobj["base"] + elif self.valobj.type.fields()[0].name == "map": + # BACKCOMPAT: rust 1.47 + # HashSet wraps std::collections::HashMap, which wraps hashbrown::HashMap + hashbrown_hashmap = self.valobj["map"]["base"] + else: + # HashSet wraps hashbrown::HashSet, which wraps hashbrown::HashMap + hashbrown_hashmap = self.valobj["base"]["map"] + return hashbrown_hashmap["table"] + def to_string(self): return "size={}".format(self.size) @@ -374,6 +391,8 @@ def children(self): for index in range(self.size): idx = self.valid_indices[index] + if self.new_layout: + idx = -(idx + 1) element = (pairs_start + idx).dereference() if self.show_values: yield ("key{}".format(index), element[ZERO_FIELD]) diff --git a/prettyPrinters/lldb_lookup.py b/prettyPrinters/lldb_lookup.py index dd5a85be585..e3f7fa11b63 100644 --- a/prettyPrinters/lldb_lookup.py +++ b/prettyPrinters/lldb_lookup.py @@ -93,7 +93,7 @@ def synthetic_lookup(valobj, dict): if rust_type == RustType.STD_HASH_SET: hash_map = valobj.GetChildAtIndex(0) if is_hashbrown_hashmap(hash_map): - return StdHashMapSyntheticProvider(hash_map, dict, show_values=False) + return StdHashMapSyntheticProvider(valobj, dict, show_values=False) else: return StdOldHashMapSyntheticProvider(hash_map, dict, show_values=False) diff --git a/prettyPrinters/lldb_providers.py b/prettyPrinters/lldb_providers.py index 0d2bb7c7b25..77b145a8218 100644 --- a/prettyPrinters/lldb_providers.py +++ b/prettyPrinters/lldb_providers.py @@ -470,6 +470,8 @@ def get_child_at_index(self, index): # type: (int) -> SBValue pairs_start = self.data_ptr.GetValueAsUnsigned() idx = self.valid_indices[index] + if self.new_layout: + idx = -(idx + 1) address = pairs_start + idx * self.pair_type_size element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.pair_type) if self.show_values: @@ -480,26 +482,43 @@ def get_child_at_index(self, index): def update(self): # type: () -> None - table = self.valobj.GetChildMemberWithName("base").GetChildMemberWithName("table") + table = self.table() capacity = table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 ctrl = table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) self.size = table.GetChildMemberWithName("items").GetValueAsUnsigned() - self.data_ptr = table.GetChildMemberWithName("data").GetChildAtIndex(0) - self.pair_type = self.data_ptr.Dereference().GetType() + self.pair_type = table.type.template_args[0].GetTypedefedType() self.pair_type_size = self.pair_type.GetByteSize() + self.new_layout = not table.GetChildMemberWithName("data").IsValid() + if self.new_layout: + self.data_ptr = ctrl.Cast(self.pair_type.GetPointerType()) + else: + self.data_ptr = table.GetChildMemberWithName("data").GetChildAtIndex(0) + u8_type = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar) u8_type_size = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar).GetByteSize() self.valid_indices = [] for idx in range(capacity): address = ctrl.GetValueAsUnsigned() + idx * u8_type_size - value = ctrl.CreateValueFromAddress("ctrl[%s]" % idx, address, u8_type).GetValueAsUnsigned() + value = ctrl.CreateValueFromAddress("ctrl[%s]" % idx, address, + u8_type).GetValueAsUnsigned() is_present = value & 128 == 0 if is_present: self.valid_indices.append(idx) + def table(self): + # type: () -> SBValue + if self.show_values: + hashbrown_hashmap = self.valobj.GetChildMemberWithName("base") + else: + # BACKCOMPAT: rust 1.47 + # HashSet wraps either std HashMap or hashbrown::HashSet, which both + # wrap hashbrown::HashMap, so either way we "unwrap" twice. + hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0) + return hashbrown_hashmap.GetChildMemberWithName("table") + def has_children(self): # type: () -> bool return True diff --git a/pretty_printers_tests/tests/hash_map.rs b/pretty_printers_tests/tests/hash_map.rs index c4cd59a74bb..ba1f0bc0aa8 100644 --- a/pretty_printers_tests/tests/hash_map.rs +++ b/pretty_printers_tests/tests/hash_map.rs @@ -1,6 +1,4 @@ // min-version: 1.33.0 -// https://github.com/intellij-rust/intellij-rust/issues/6198 -// max-version: 1.46.0 // === LLDB TESTS ==================================================================================