diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-06 13:15:40 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-06 13:17:42 -0700 |
| commit | bff512a90facf2b0064f13737d44c716863f644d (patch) | |
| tree | 72553ae018b6ed52c06e532346b35f3608d7559d /src/libsyntax | |
| parent | 1e3143b34e66ca5157b03d3658d64d7c01563186 (diff) | |
| download | rust-bff512a90facf2b0064f13737d44c716863f644d.tar.gz rust-bff512a90facf2b0064f13737d44c716863f644d.zip | |
rustc: Implement functional record update for structs
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 3 |
5 files changed, 30 insertions, 11 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1e43ae219ba..daf3e20f469 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -347,9 +347,7 @@ enum expr_ { expr_mac(mac), // A struct literal expression. - // - // XXX: Add functional record update. - expr_struct(@path, ~[field]), + expr_struct(@path, ~[field], option<@expr>), // A vector literal constructed from one repeated element. expr_repeat(@expr /* element */, @expr /* count */, mutability) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ec6d7010aa1..71c23ff4fa6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -478,8 +478,10 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { fld.fold_expr(e)), expr_assert(e) => expr_assert(fld.fold_expr(e)), expr_mac(mac) => expr_mac(fold_mac(mac)), - expr_struct(path, fields) => { - expr_struct(fld.fold_path(path), vec::map(fields, fold_field)) + expr_struct(path, fields, maybe_expr) => { + expr_struct(fld.fold_path(path), + vec::map(fields, fold_field), + option::map(maybe_expr, |x| fld.fold_expr(x))) } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a6c4e6c4131..71bd87981bc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -912,18 +912,27 @@ class parser { self.bump(); let mut fields = ~[]; vec::push(fields, self.parse_field(token::COLON)); - while self.token != token::RBRACE { + while self.token != token::RBRACE && + !self.is_keyword(~"with") { self.expect(token::COMMA); - if self.token == token::RBRACE { + if self.token == token::RBRACE || + self.is_keyword(~"with") { // Accept an optional trailing comma. break; } vec::push(fields, self.parse_field(token::COLON)); } + let base; + if self.eat_keyword(~"with") { + base = some(self.parse_expr()); + } else { + base = none; + } + hi = pth.span.hi; self.expect(token::RBRACE); - ex = expr_struct(pth, fields); + ex = expr_struct(pth, fields, base); return self.mk_pexpr(lo, hi, ex); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c81b8b5335f..eca571b9ccd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -973,11 +973,20 @@ fn print_expr(s: ps, &&expr: @ast::expr) { } word(s.s, ~"}"); } - ast::expr_struct(path, fields) => { + ast::expr_struct(path, fields, wth) => { print_path(s, path, true); word(s.s, ~"{"); commasep_cmnt(s, consistent, fields, print_field, get_span); - word(s.s, ~","); + alt wth { + some(expr) => { + if vec::len(fields) > 0u { space(s.s); } + ibox(s, indent_unit); + word_space(s, ~"with"); + print_expr(s, expr); + end(s); + } + _ => word(s.s, ~",") + } word(s.s, ~"}"); } ast::expr_tup(exprs) => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 8d80f9663a3..1c92f26cabe 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -364,9 +364,10 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { for flds.each |f| { v.visit_expr(f.node.expr, e, v); } visit_expr_opt(base, e, v); } - expr_struct(p, flds) => { + expr_struct(p, flds, base) => { visit_path(p, e, v); for flds.each |f| { v.visit_expr(f.node.expr, e, v); } + visit_expr_opt(base, e, v); } expr_tup(elts) => for elts.each |el| { v.visit_expr(el, e, v); } expr_call(callee, args, _) => { |
