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:
parent
b3e3859bc5
commit
45320ffa04
5 changed files with 48 additions and 8 deletions
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
* rust-lang.c (rust_subscript): Handle slices in
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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.
|
||||
|
||||
2017-10-02 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdb.rust/simple.exp: Test ptype of a slice.
|
||||
|
|
|
@ -64,6 +64,10 @@ gdb_test "ptype j2" " = struct simple::Unit"
|
|||
gdb_test "print simple::Unit" " = simple::Unit"
|
||||
gdb_test "print simple::Unit{}" " = simple::Unit"
|
||||
|
||||
gdb_test "print f" " = \"hi bob\""
|
||||
gdb_test "print fslice" " = \"bob\""
|
||||
gdb_test "print &f\[3..\]" " = \"bob\""
|
||||
|
||||
gdb_test "print g" " = \\(u8 \\(\\*\\)\\\[6\\\]\\) $hex b\"hi bob\""
|
||||
gdb_test "ptype g" " = u8 \\(\\*\\)\\\[6\\\]"
|
||||
|
||||
|
@ -200,13 +204,9 @@ gdb_test "ptype empty" "fn \\(\\)"
|
|||
|
||||
gdb_test "print (diff2 as fn(i32, i32) -> i32)(19, -2)" " = 21"
|
||||
|
||||
# We need the ".*" because currently we don't extract the length and
|
||||
# use it to intelligently print the string data.
|
||||
gdb_test "print \"hello rust\"" \
|
||||
" = &str \\{data_ptr: $hex \"hello rust.*\", length: 10\\}"
|
||||
gdb_test "print \"hello rust\"" " = \"hello rust.*\""
|
||||
gdb_test "print \"hello" "Unexpected EOF in string"
|
||||
gdb_test "print r##\"hello \" rust\"##" \
|
||||
" = &str \\{data_ptr: $hex \"hello \\\\\" rust.*\", length: 12\\}"
|
||||
gdb_test "print r##\"hello \" rust\"##" " = \"hello \\\\\" rust.*\""
|
||||
gdb_test "print r\"hello" "Unexpected EOF in string"
|
||||
gdb_test "print r###\"###hello\"" "Unexpected EOF in string"
|
||||
gdb_test "print r###\"###hello\"##" "Unexpected EOF in string"
|
||||
|
|
|
@ -95,6 +95,8 @@ fn main () {
|
|||
let g = b"hi bob";
|
||||
let h = b'9';
|
||||
|
||||
let fslice = &f[3..];
|
||||
|
||||
let i = ["whatever"; 8];
|
||||
|
||||
let j = Unit;
|
||||
|
|
Loading…
Add table
Reference in a new issue