[FYI] Support bare-identifier field initializers in Rust

Message ID 20180319170428.19879-1-tom@tromey.com
State New
Headers show
Series
  • [FYI] Support bare-identifier field initializers in Rust
Related show

Commit Message

Tom Tromey March 19, 2018, 5:04 p.m.
In Rust one can initialize a struct member from an identically-named
local variable by simply mentioning the member name in the
initializer, like:

    let x = 0;
    let y = Struct { x };

This initializes "Struct::x" from "x".

This patch adds this form of initializer to the Rust expression parser
and adds a test.

Tested on x86-64 Fedora 26 using rustc 1.23.

2018-03-19  Tom Tromey  <tom@tromey.com>

	* rust-exp.y (struct_expr_tail, struct_expr_list): Add plain
	"IDENT" production.

2018-03-19  Tom Tromey  <tom@tromey.com>

	* gdb.rust/simple.rs (main): Add local variables field1, field2,
	y0.
	* gdb.rust/simple.exp: Test bare identifier form of struct
	initializer.
---
 gdb/ChangeLog                     |  5 +++++
 gdb/rust-exp.y                    | 17 +++++++++++++++++
 gdb/testsuite/ChangeLog           |  7 +++++++
 gdb/testsuite/gdb.rust/simple.exp |  3 +++
 gdb/testsuite/gdb.rust/simple.rs  |  4 ++++
 5 files changed, 36 insertions(+)

-- 
2.13.6

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fe4ae9f684..ac52a9a666 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2018-03-19  Tom Tromey  <tom@tromey.com>
+
+	* rust-exp.y (struct_expr_tail, struct_expr_list): Add plain
+	"IDENT" production.
+
 2018-03-19  Pedro Alves  <palves@redhat.com>
 	    Tom Tromey  <tom@tromey.com>
 
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index f1dcecec96..b661a803e3 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -481,6 +481,14 @@  struct_expr_tail:
 		  sf.init = $3;
 		  $$ = sf;
 		}
+|	IDENT
+		{
+		  struct set_field sf;
+
+		  sf.name = $1;
+		  sf.init = ast_path ($1, NULL);
+		  $$ = sf;
+		}
 ;
 
 struct_expr_list:
@@ -503,6 +511,15 @@  struct_expr_list:
 		  $5->push_back (sf);
 		  $$ = $5;
 		}
+|	IDENT ',' struct_expr_list
+		{
+		  struct set_field sf;
+
+		  sf.name = $1;
+		  sf.init = ast_path ($1, NULL);
+		  $3->push_back (sf);
+		  $$ = $3;
+		}
 ;
 
 array_expr:
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c648fc518f..f155ffee71 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,12 @@ 
 2018-03-19  Tom Tromey  <tom@tromey.com>
 
+	* gdb.rust/simple.rs (main): Add local variables field1, field2,
+	y0.
+	* gdb.rust/simple.exp: Test bare identifier form of struct
+	initializer.
+
+2018-03-19  Tom Tromey  <tom@tromey.com>
+
 	* gdb.gdb/observer.exp: Remove.
 
 2018-03-19  Andreas Arnez  <arnez@linux.vnet.ibm.com>
diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp
index 230e6a7a88..2db596b932 100644
--- a/gdb/testsuite/gdb.rust/simple.exp
+++ b/gdb/testsuite/gdb.rust/simple.exp
@@ -166,6 +166,9 @@  gdb_test "print simple::HiBob + 5" \
 gdb_test "print nosuchsymbol" \
     "No symbol 'nosuchsymbol' in current context"
 
+gdb_test "print simple::HiBob{field1, field2}" \
+    " = simple::HiBob \\{field1: 77, field2: 88\\}"
+
 gdb_test "print e" " = simple::MoreComplicated::Two\\(73\\)"
 gdb_test "print e2" \
     " = simple::MoreComplicated::Four\\{this: true, is: 8, a: 109 'm', struct_: 100, variant: 10\\}"
diff --git a/gdb/testsuite/gdb.rust/simple.rs b/gdb/testsuite/gdb.rust/simple.rs
index 7e43cd8707..b2b5dfe0f6 100644
--- a/gdb/testsuite/gdb.rust/simple.rs
+++ b/gdb/testsuite/gdb.rust/simple.rs
@@ -112,6 +112,10 @@  fn main () {
     let y = HiBob {field1: 7, field2: 8};
     let z = ByeBob(7, 8);
 
+    let field1 = 77;
+    let field2 = 88;
+    let y0 = HiBob { field1, field2 };
+
     let univariant = Univariant::Foo {a : 1};
     let univariant_anon = UnivariantAnon::Foo(1);