Print type name when printing Rust slice

Message ID 20240311151451.3745299-1-tromey@adacore.com
State New
Headers
Series Print type name when printing Rust slice |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Tom Tromey March 11, 2024, 3:14 p.m. UTC
  The recent change to how unsized Rust values are printed included a
small regression from past behavior.  Previously, a slice's type would
be printed, like:

    (gdb) print slice
    $80 = &[i32] [3]

The patch changed this to just

    (gdb) print slice
    $80 = [3]

This patch restores the previous behavior.
---
 gdb/rust-lang.c                    | 11 +++++++++++
 gdb/testsuite/gdb.rust/simple.exp  |  2 +-
 gdb/testsuite/gdb.rust/unsized.exp |  2 +-
 3 files changed, 13 insertions(+), 2 deletions(-)
  

Comments

Simon Marchi March 11, 2024, 4:19 p.m. UTC | #1
On 3/11/24 11:14, Tom Tromey wrote:
> The recent change to how unsized Rust values are printed included a
> small regression from past behavior.  Previously, a slice's type would
> be printed, like:
> 
>     (gdb) print slice
>     $80 = &[i32] [3]
> 
> The patch changed this to just
> 
>     (gdb) print slice
>     $80 = [3]
> 
> This patch restores the previous behavior.
> ---
>  gdb/rust-lang.c                    | 11 +++++++++++
>  gdb/testsuite/gdb.rust/simple.exp  |  2 +-
>  gdb/testsuite/gdb.rust/unsized.exp |  2 +-
>  3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
> index ab537cc9752..d7265f72770 100644
> --- a/gdb/rust-lang.c
> +++ b/gdb/rust-lang.c
> @@ -476,6 +476,17 @@ rust_language::val_print_slice
>  	}
>      }
>  
> +  /* Print the slice type here.  This was gdb's historical behavior
> +     (from before unsized types were generically handled) and helps
> +     make it clear that the user is seeing a slice, not an array.
> +     Only arrays must be handled as the other cases are handled by
> +     value_print_inner.  */
> +  if (type->code () == TYPE_CODE_ARRAY)
> +    {
> +      type_print (orig_type, "", stream, -1);
> +      gdb_printf (stream, " ");
> +    }

Just for me education, how are slices represented in the GDB type
system, as opposed to arrays?  What are the value types that
rust_language::val_print_slice expects to receive, other than
TYPE_CODE_ARRAY?

You can add my:

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>

... although it's not worth much because I don't know this area.

Simon
  
Tom Tromey March 11, 2024, 5:32 p.m. UTC | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> Just for me education, how are slices represented in the GDB type
Simon> system, as opposed to arrays?  What are the value types that
Simon> rust_language::val_print_slice expects to receive, other than
Simon> TYPE_CODE_ARRAY?

Under the hood a slice is a structure holding a pointer and a length.
However to the Rust programmer these look somewhat like arrays.  For
example, you can index into them like arrays.

rust_slice_type_p determines if something is "slice-like".

An "unsized" type is basically the same thing, but where the payload is
some object with an array at the end, like the C struct hack.
rust-lang.c calls these both "slice" at some spots, mainly because I
didn't understand this when I first wrote the code.

FWIW Ada has a similar concept but it is more general, because Ada has
multi-dimensional arrays and range types.

Tom
  
Tom Tromey April 2, 2024, 5:44 p.m. UTC | #3
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:

Tom> The recent change to how unsized Rust values are printed included a
Tom> small regression from past behavior.  Previously, a slice's type would
Tom> be printed, like:

Tom>     (gdb) print slice
Tom>     $80 = &[i32] [3]

Tom> The patch changed this to just

Tom>     (gdb) print slice
Tom>     $80 = [3]

Tom> This patch restores the previous behavior.

Oops, I almost forgot about this one.
I'm checking it in now.

Tom
  

Patch

diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index ab537cc9752..d7265f72770 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -476,6 +476,17 @@  rust_language::val_print_slice
 	}
     }
 
+  /* Print the slice type here.  This was gdb's historical behavior
+     (from before unsized types were generically handled) and helps
+     make it clear that the user is seeing a slice, not an array.
+     Only arrays must be handled as the other cases are handled by
+     value_print_inner.  */
+  if (type->code () == TYPE_CODE_ARRAY)
+    {
+      type_print (orig_type, "", stream, -1);
+      gdb_printf (stream, " ");
+    }
+
   value_print_inner (val, stream, recurse, options);
 }
 
diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp
index 7f5fbad7a3f..1e6fc94400e 100644
--- a/gdb/testsuite/gdb.rust/simple.exp
+++ b/gdb/testsuite/gdb.rust/simple.exp
@@ -317,7 +317,7 @@  proc test_one_slice {svar length base range} {
 	global hex
 
 	# Just accept any array here.
-	set result " = \\\[.*\\\]"
+	set result " = &\\\[.*\\\] \\\[.*\\\]"
 
 	gdb_test "print $svar" $result
 	gdb_test "print &${base}\[${range}\]" $result
diff --git a/gdb/testsuite/gdb.rust/unsized.exp b/gdb/testsuite/gdb.rust/unsized.exp
index fab655790e6..ea5f281cb3d 100644
--- a/gdb/testsuite/gdb.rust/unsized.exp
+++ b/gdb/testsuite/gdb.rust/unsized.exp
@@ -33,6 +33,6 @@  if {![runto ${srcfile}:$line]} {
 gdb_test "ptype us" " = .*V<\\\[u8\\\]>.*"
 
 if {[rust_at_least 1.61]} {
-    gdb_test "print us2" " = \\\[1, 2, 3\\\]"
+    gdb_test "print us2" " = .*u8.* \\\[1, 2, 3\\\]"
     gdb_test "ptype us2" "type = .*"
 }