Fix &str printing in Rust

Printing a string slice ("&str") in Rust would print until the
terminating \0; but that is incorrect because a slice has a length.
This fixes &str printing, and arranges to preserve the type name when
slicing a slice, so that printing a slice of an "&str" works as well.

This is PR rust/22236.

2017-10-02  Tom Tromey  <tom@tromey.com>

	PR rust/22236:
	* rust-lang.c (rust_val_print_str): New function.
	(val_print_struct): Call it.
	(rust_subscript): Preserve name of slice type.

2017-10-02  Tom Tromey  <tom@tromey.com>

	PR rust/22236:
	* gdb.rust/simple.rs (main): New variable "fslice".
	* gdb.rust/simple.exp: Add slice tests.  Update string tests.
This commit is contained in:
Tom Tromey 2017-10-02 13:55:42 -06:00
parent b3e3859bc5
commit 45320ffa04
5 changed files with 48 additions and 8 deletions

View file

@ -467,6 +467,21 @@ rust_printstr (struct ui_file *stream, struct type *type,
/* Helper function to print a string slice. */
static void
rust_val_print_str (struct ui_file *stream, struct value *val,
const struct value_print_options *options)
{
struct value *base = value_struct_elt (&val, NULL, "data_ptr", NULL,
"slice");
struct value *len = value_struct_elt (&val, NULL, "length", NULL, "slice");
val_print_string (TYPE_TARGET_TYPE (value_type (base)), "UTF-8",
value_as_address (base), value_as_long (len), stream,
options);
}
/* rust_print_type branch for structs and untagged unions. */
static void
@ -477,6 +492,13 @@ val_print_struct (struct type *type, int embedded_offset,
{
int i;
int first_field;
if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&str") == 0)
{
rust_val_print_str (stream, val, options);
return;
}
bool is_tuple = rust_tuple_type_p (type);
bool is_tuple_struct = !is_tuple && rust_tuple_struct_type_p (type);
struct value_print_options opts;
@ -1562,8 +1584,11 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
usize = language_lookup_primitive_type (exp->language_defn,
exp->gdbarch,
"usize");
slice = rust_slice_type ("&[*gdb*]", value_type (result),
usize);
const char *new_name = ((type != nullptr
&& rust_slice_type_p (type))
? TYPE_NAME (type) : "&[*gdb*]");
slice = rust_slice_type (new_name, value_type (result), usize);
addrval = value_allocate_space_in_inferior (TYPE_LENGTH (slice));
addr = value_as_long (addrval);