about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/etc/gdb_rust_pretty_printing.py16
-rw-r--r--src/etc/lldb_rust_formatters.py9
-rw-r--r--src/test/debuginfo/gdb-pretty-struct-and-enums.rs12
-rw-r--r--src/test/debuginfo/option-like-enum.rs9
4 files changed, 37 insertions, 9 deletions
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index 1af649f0731..7e5918ea39e 100644
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -54,13 +54,14 @@ def rust_pretty_printer_lookup_function(val):
       return RustStructPrinter(val, false)
 
     if enum_member_count == 1:
-      if enum_members[0].name == None:
+      first_variant_name = enum_members[0].name
+      if first_variant_name == None:
         # This is a singleton enum
         return rust_pretty_printer_lookup_function(val[enum_members[0]])
       else:
-        assert enum_members[0].name.startswith("RUST$ENCODED$ENUM$")
+        assert first_variant_name.startswith("RUST$ENCODED$ENUM$")
         # This is a space-optimized enum
-        last_separator_index = enum_members[0].name.rfind("$")
+        last_separator_index = first_variant_name.rfind("$")
         second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index)
         disr_field_index = first_variant_name[second_last_separator_index + 1 :
                                               last_separator_index]
@@ -68,7 +69,12 @@ def rust_pretty_printer_lookup_function(val):
 
         sole_variant_val = val[enum_members[0]]
         disr_field = get_field_at_index(sole_variant_val, disr_field_index)
-        discriminant = int(sole_variant_val[disr_field])
+        discriminant = sole_variant_val[disr_field]
+
+        # If the discriminant field is a fat pointer we have to consider the
+        # first word as the true discriminant
+        if discriminant.type.code == gdb.TYPE_CODE_STRUCT:
+            discriminant = discriminant[get_field_at_index(discriminant, 0)]
 
         if discriminant == 0:
           null_variant_name = first_variant_name[last_separator_index + 1:]
@@ -173,7 +179,7 @@ class RustCStyleEnumPrinter:
 
 class IdentityPrinter:
   def __init__(self, string):
-    self.string
+    self.string = string
 
   def to_string(self):
     return self.string
diff --git a/src/etc/lldb_rust_formatters.py b/src/etc/lldb_rust_formatters.py
index 7924d63c8e0..f4f1a5121d1 100644
--- a/src/etc/lldb_rust_formatters.py
+++ b/src/etc/lldb_rust_formatters.py
@@ -138,9 +138,14 @@ def print_enum_val(val, internal_dict):
         return "<invalid enum encoding: %s>" % first_variant_name
 
       # Read the discriminant
-      disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index).GetValueAsUnsigned()
+      disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index)
 
-      if disr_val == 0:
+      # If the discriminant field is a fat pointer we have to consider the
+      # first word as the true discriminant
+      if disr_val.GetType().GetTypeClass() == lldb.eTypeClassStruct:
+          disr_val = disr_val.GetChildAtIndex(0)
+
+      if disr_val.GetValueAsUnsigned() == 0:
         # Null case: Print the name of the null-variant
         null_variant_name = first_variant_name[last_separator_index + 1:]
         return null_variant_name
diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
index 9a42cd92fdc..76cf3c1149d 100644
--- a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
+++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
@@ -58,11 +58,17 @@
 // gdb-command: print none
 // gdb-check:$12 = None
 
+// gdb-command: print some_fat
+// gdb-check:$13 = Some = {"abc"}
+
+// gdb-command: print none_fat
+// gdb-check:$14 = None
+
 // gdb-command: print nested_variant1
-// gdb-check:$13 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
+// gdb-check:$15 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
 
 // gdb-command: print nested_variant2
-// gdb-check:$14 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}
+// gdb-check:$16 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}
 
 use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
 use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
@@ -129,6 +135,8 @@ fn main() {
 
     let some = Some(110u);
     let none: Option<int> = None;
+    let some_fat = Some("abc");
+    let none_fat: Option<&'static str> = None;
 
     let nested_variant1 = NestedVariant1(
         NestedStruct {
diff --git a/src/test/debuginfo/option-like-enum.rs b/src/test/debuginfo/option-like-enum.rs
index 11c594bac59..333a430e351 100644
--- a/src/test/debuginfo/option-like-enum.rs
+++ b/src/test/debuginfo/option-like-enum.rs
@@ -61,6 +61,12 @@
 // lldb-command:print void_droid
 // lldb-check:[...]$5 = Void
 
+// lldb-command:print some_str
+// lldb-check:[...]$6 = Some(&str { data_ptr: [...], length: 3 })
+
+// lldb-command:print none_str
+// lldb-check:[...]$7 = None
+
 
 // If a struct has exactly two variants, one of them is empty, and the other one
 // contains a non-nullable pointer, then this value is used as the discriminator.
@@ -96,6 +102,9 @@ struct NamedFieldsRepr<'a> {
 
 fn main() {
 
+    let some_str: Option<&'static str> = Some("abc");
+    let none_str: Option<&'static str> = None;
+
     let some: Option<&u32> = Some(unsafe { std::mem::transmute(0x12345678u) });
     let none: Option<&u32> = None;