@@ -1152,16 +1152,22 @@ def has_children(self) -> bool:
11521152
11531153
11541154def children_of_node (node_ptr : SBValue , height : int ):
1155- def cast_to_internal (node : SBValue ) -> SBValue :
1155+ def get_edges (node : SBValue ) -> SBValue :
11561156 # BTreeMap implementation does ad-hoc polymorphism between LeafNode and InternalNode
11571157 # with raw pointers.
11581158 # https://github.com/rust-lang/rust/issues/90520#issuecomment-2211103129
1159- internal_type_name = node .type .GetPointeeType ().name .replace (
1160- "LeafNode" , "InternalNode" , 1
1161- )
1162- target = node .GetTarget ()
1163- internal_type = target .FindFirstType (internal_type_name )
1164- return node .Cast (internal_type .GetPointerType ())
1159+ # Implementing this the same way as the GDB provider with type casting fails
1160+ # because LLDB does not find the target type for some reason.
1161+ # Therefore, we manually do the pointer arithmetic to get the edges array
1162+ # and handle it as raw pointers later instead of MaybeUninit<NonNull<LeafNode<K,V>>>.
1163+ # We can do that because InternalNode is repr(C).
1164+ leaf_ptr_type = node .GetType ()
1165+ # Array has a constant length of 2 * B
1166+ edges_arr_type = leaf_ptr_type .GetArrayType (12 )
1167+ node_addr = node .unsigned
1168+ leaf_size = leaf_ptr_type .GetPointeeType ().size
1169+ edges_addr = node_addr + leaf_size
1170+ return node .CreateValueFromAddress ("edges" , edges_addr , edges_arr_type )
11651171
11661172 def unwrap_item_from_array_of_maybe_uninit (arr : SBValue , index : int ) -> SBValue :
11671173 element = arr .GetChildAtIndex (index )
@@ -1170,20 +1176,25 @@ def unwrap_item_from_array_of_maybe_uninit(arr: SBValue, index: int) -> SBValue:
11701176 if node_ptr .type .name .startswith ("alloc::collections::btree::node::BoxedNode<" ):
11711177 # BACKCOMPAT: rust 1.49
11721178 node_ptr = node_ptr .GetChildMemberWithName ("ptr" )
1173- node_ptr = unwrap_unique_or_non_null (node_ptr )
1179+
1180+ if not node_ptr .type .IsPointerType ():
1181+ # After the first recursion, this method is called with a raw pointer type directly
1182+ # instead of NonNull<T>
1183+ node_ptr = unwrap_unique_or_non_null (node_ptr )
1184+
11741185 leaf = node_ptr .Dereference ()
11751186 keys = leaf .GetChildMemberWithName ("keys" )
11761187 vals = leaf .GetChildMemberWithName ("vals" )
11771188 length = leaf .GetChildMemberWithName ("len" ).unsigned
11781189 edges = (
1179- cast_to_internal (node_ptr ). GetChildMemberWithName ( "edges" )
1190+ get_edges (node_ptr )
11801191 if height > 0
11811192 else None
11821193 )
11831194
11841195 for i in range (length + 1 ):
11851196 if height > 0 :
1186- child_ptr = unwrap_item_from_array_of_maybe_uninit ( edges , i )
1197+ child_ptr = edges . GetChildAtIndex ( i )
11871198 yield from children_of_node (child_ptr , height - 1 )
11881199 if i < length :
11891200 # Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
@@ -1202,19 +1213,11 @@ def unwrap_item_from_array_of_maybe_uninit(arr: SBValue, index: int) -> SBValue:
12021213 yield key , val
12031214
12041215
1205- def strip_till_parentheses (text : str ) -> str :
1206- start = text .find ("(" )
1207- end = text .find (")" )
1208- if start == - 1 or end == - 1 :
1209- return text
1210- return text [start : end + 1 ]
1211-
1212-
12131216class StdBTreeMapSyntheticProvider :
12141217 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque , show_values : bool = True ):
12151218 self .valobj = valobj
12161219 self ._dict = _dict
1217- self .show_values = True
1220+ self .show_values = show_values
12181221
12191222 def num_children (self ) -> int :
12201223 return self .size
@@ -1244,20 +1247,20 @@ def update(self) -> bool:
12441247 # - Type lookup after get_template_args helper fails with codelldb for unclear reasons
12451248 # - Native `template_args[0]` from LLDB fails with codelldb and just says `T` if printed
12461249 # on console
1247- marker_type_name = self .valobj .GetChildMemberWithName ("_marker" ). GetTypeName ( )
1248- pair_type_name = strip_till_parentheses ( marker_type_name )
1249- target = self . valobj . GetTarget ( )
1250- self .pair_type = target . FindFirstType ( pair_type_name )
1250+ marker = self .valobj .GetChildMemberWithName ("_marker" )
1251+ marker_type = marker . GetType ( )
1252+ box = marker_type . GetTemplateArgumentType ( 0 )
1253+ self .pair_type = box . GetPointeeType ( )
12511254
12521255 if self .size == 0 :
12531256 return
12541257
12551258 root = self .valobj .GetChildMemberWithName ("root" )
12561259
12571260 if root .type .name .startswith ("core::option::Option<" ):
1258- target = self . valobj . GetTarget ()
1259- type_some = target . FindFirstType ( get_template_args ( root . GetTypeName ())[ 0 ] )
1260- root = root . Cast ( type_some )
1261+ synthetic_children = root . children [ 0 ]
1262+ current_variant = synthetic_children . GetChildMemberWithName ( "$variant$" )
1263+ root = current_variant . GetChildMemberWithName ( "value" ). GetChildMemberWithName ( "__0" )
12611264
12621265 height = root .GetChildMemberWithName ("height" )
12631266 node_ptr = root .GetChildMemberWithName ("node" )
0 commit comments