From c206d024eb31124a5d6536ce1f355c4ac0698cab Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 10 Jul 2012 10:37:05 -0700 Subject: [PATCH] accept naked exprs with commas in pattern arms pretty printing will use them, but indentation is slightly off if the expr is long --- src/libsyntax/ast_util.rs | 7 +++++++ src/libsyntax/parse/parser.rs | 21 +++++++++++++++++++-- src/libsyntax/print/pprust.rs | 20 ++++++++++++++++---- src/test/pretty/alt-naked-expr-long.rs | 17 +++++++++++++++++ src/test/pretty/alt-naked-expr-medium.rs | 10 ++++++++++ src/test/pretty/alt-naked-expr.rs | 7 +++++++ 6 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/test/pretty/alt-naked-expr-long.rs create mode 100644 src/test/pretty/alt-naked-expr-medium.rs create mode 100644 src/test/pretty/alt-naked-expr.rs diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index d065aad4f5a..461d237450c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -588,6 +588,13 @@ fn view_path_id(p: @view_path) -> node_id { } } +fn lone_block_expr(blk: blk) -> option<@ast::expr> { + if blk.node.view_items.len() != 0 { ret none; } + if blk.node.stmts.len() != 0 { ret none; } + if blk.node.rules != default_blk { ret none; } + ret blk.node.expr; +} + // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b9e5fadeb81..df8ee01bb3b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1511,8 +1511,25 @@ class parser { let pats = self.parse_pats(); let mut guard = none; if self.eat_keyword(~"if") { guard = some(self.parse_expr()); } - if self.token == token::FAT_ARROW { self.bump(); } - let blk = self.parse_block(); + let blk = if self.token != token::FAT_ARROW { + self.parse_block() + } else { + self.bump(); + if self.token == token::LBRACE { + self.parse_block() + } else { + let expr = self.parse_expr(); + if self.token != token::RBRACE { + self.expect(token::COMMA); + } + {node: {view_items: ~[], + stmts: ~[], + expr: some(expr), + id: self.get_id(), + rules: default_blk}, + span: expr.span} + } + }; vec::push(arms, {pats: pats, guard: guard, body: blk}); } let mut hi = self.span.hi; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a169c4e7256..18e3b6c0790 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -6,7 +6,7 @@ import pp::{break_offset, word, printer, inconsistent, eof}; import diagnostic; import ast::{required, provided}; -import ast_util::operator_prec; +import ast_util::{operator_prec, lone_block_expr}; import dvec::{dvec, extensions}; import parse::classify::*; import util::interner; @@ -1034,7 +1034,8 @@ fn print_expr(s: ps, &&expr: @ast::expr) { print_maybe_parens_discrim(s, expr); space(s.s); bopen(s); - for arms.each |arm| { + let len = arms.len(); + for arms.eachi |i, arm| { space(s.s); cbox(s, alt_indent_unit); ibox(s, 0u); @@ -1050,8 +1051,19 @@ fn print_expr(s: ps, &&expr: @ast::expr) { some(e) { word_space(s, ~"if"); print_expr(s, e); space(s.s); } none { } } - print_possibly_embedded_block(s, arm.body, block_normal, - alt_indent_unit); + word_space(s, ~"=>"); + alt lone_block_expr(arm.body) { + some(expr) => { + end(s); // close the ibox for the pattern + print_expr(s, expr); + if i < len - 1 { word_space(s, ~","); } + end(s); // close enclosing cbox + } + none => { + print_possibly_embedded_block(s, arm.body, block_normal, + alt_indent_unit); + } + } } bclose_(s, expr.span, alt_indent_unit); } diff --git a/src/test/pretty/alt-naked-expr-long.rs b/src/test/pretty/alt-naked-expr-long.rs new file mode 100644 index 00000000000..8504a50d5a1 --- /dev/null +++ b/src/test/pretty/alt-naked-expr-long.rs @@ -0,0 +1,17 @@ +// pretty-exact + +// actually this doesn't quite look how I want it to, but I can't +// get the prettyprinter to indent the long expr + +fn main() { + let x = some(3); + let y = + alt x { + some(_) => + "some" + "very" + "very" + "very" + "very" + "very" + "very" + + "very" + "very" + "long" + "string", + + none => "none" + }; + assert y == "some(_)"; +} diff --git a/src/test/pretty/alt-naked-expr-medium.rs b/src/test/pretty/alt-naked-expr-medium.rs new file mode 100644 index 00000000000..70099e46806 --- /dev/null +++ b/src/test/pretty/alt-naked-expr-medium.rs @@ -0,0 +1,10 @@ +// pretty-exact + +fn main() { + let x = some(3); + let _y = + alt x { + some(_) => ~[~"some(_)", ~"not", ~"SO", ~"long", ~"string"], + none => ~[~"none"] + }; +} diff --git a/src/test/pretty/alt-naked-expr.rs b/src/test/pretty/alt-naked-expr.rs new file mode 100644 index 00000000000..54ed76054e4 --- /dev/null +++ b/src/test/pretty/alt-naked-expr.rs @@ -0,0 +1,7 @@ +// pretty-exact + +fn main() { + let x = some(3); + let y = alt x { some(_) => "some(_)", none => "none" }; + assert y == "some(_)"; +}