From 1200ad0f06fc1ecc9a5ccf320e704c95786dbfe3 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sun, 27 Jul 2014 18:05:07 -0700 Subject: [PATCH] Fix a bug pretty printing `match { 5i } { _ => { } }` This also always puts a trailing comma on the last non-block expr. --- src/libsyntax/ext/quote.rs | 2 + src/libsyntax/print/pprust.rs | 99 +++++++++++----------- src/test/pretty/match-block-expr.rs | 16 ++++ src/test/pretty/match-naked-expr-medium.rs | 2 +- src/test/pretty/match-naked-expr.rs | 2 +- 5 files changed, 71 insertions(+), 50 deletions(-) create mode 100644 src/test/pretty/match-block-expr.rs diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 5e15d6179bb54..8f236cebcf471 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -147,6 +147,7 @@ pub mod rt { impl_to_source!(Gc, stmt_to_string) impl_to_source!(Gc, expr_to_string) impl_to_source!(Gc, pat_to_string) + impl_to_source!(ast::Arm, arm_to_string) impl_to_source_slice!(ast::Ty, ", ") impl_to_source_slice!(Gc, "\n\n") @@ -240,6 +241,7 @@ pub mod rt { impl_to_tokens!(ast::Ident) impl_to_tokens!(Gc) impl_to_tokens!(Gc) + impl_to_tokens!(ast::Arm) impl_to_tokens!(Gc) impl_to_tokens_lifetime!(&'a [Gc]) impl_to_tokens!(ast::Ty) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ac8355651916e..4ab9d1b486a34 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -18,7 +18,6 @@ use attr::{AttrMetaMethods, AttributeMethods}; use codemap::{CodeMap, BytePos}; use codemap; use diagnostic; -use parse::classify::expr_is_simple_block; use parse::token; use parse::lexer::comments; use parse; @@ -151,6 +150,10 @@ pub fn pat_to_string(pat: &ast::Pat) -> String { to_string(|s| s.print_pat(pat)) } +pub fn arm_to_string(arm: &ast::Arm) -> String { + to_string(|s| s.print_arm(arm)) +} + pub fn expr_to_string(e: &ast::Expr) -> String { to_string(|s| s.print_expr(e)) } @@ -1402,53 +1405,8 @@ impl<'a> State<'a> { try!(self.print_expr(&**expr)); try!(space(&mut self.s)); try!(self.bopen()); - let len = arms.len(); - for (i, arm) in arms.iter().enumerate() { - // I have no idea why this check is necessary, but here it - // is :( - if arm.attrs.is_empty() { - try!(space(&mut self.s)); - } - try!(self.cbox(indent_unit)); - try!(self.ibox(0u)); - try!(self.print_outer_attributes(arm.attrs.as_slice())); - let mut first = true; - for p in arm.pats.iter() { - if first { - first = false; - } else { - try!(space(&mut self.s)); - try!(self.word_space("|")); - } - try!(self.print_pat(&**p)); - } - try!(space(&mut self.s)); - match arm.guard { - Some(ref e) => { - try!(self.word_space("if")); - try!(self.print_expr(&**e)); - try!(space(&mut self.s)); - } - None => () - } - try!(self.word_space("=>")); - - match arm.body.node { - ast::ExprBlock(ref blk) => { - // the block will close the pattern's ibox - try!(self.print_block_unclosed_indent(&**blk, - indent_unit)); - } - _ => { - try!(self.end()); // close the ibox for the pattern - try!(self.print_expr(&*arm.body)); - } - } - if !expr_is_simple_block(expr.clone()) - && i < len - 1 { - try!(word(&mut self.s, ",")); - } - try!(self.end()); // close enclosing cbox + for arm in arms.iter() { + try!(self.print_arm(arm)); } try!(self.bclose_(expr.span, indent_unit)); } @@ -1882,6 +1840,51 @@ impl<'a> State<'a> { self.ann.post(self, NodePat(pat)) } + fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> { + // I have no idea why this check is necessary, but here it + // is :( + if arm.attrs.is_empty() { + try!(space(&mut self.s)); + } + try!(self.cbox(indent_unit)); + try!(self.ibox(0u)); + try!(self.print_outer_attributes(arm.attrs.as_slice())); + let mut first = true; + for p in arm.pats.iter() { + if first { + first = false; + } else { + try!(space(&mut self.s)); + try!(self.word_space("|")); + } + try!(self.print_pat(&**p)); + } + try!(space(&mut self.s)); + match arm.guard { + Some(ref e) => { + try!(self.word_space("if")); + try!(self.print_expr(&**e)); + try!(space(&mut self.s)); + } + None => () + } + try!(self.word_space("=>")); + + match arm.body.node { + ast::ExprBlock(ref blk) => { + // the block will close the pattern's ibox + try!(self.print_block_unclosed_indent(&**blk, + indent_unit)); + } + _ => { + try!(self.end()); // close the ibox for the pattern + try!(self.print_expr(&*arm.body)); + try!(word(&mut self.s, ",")); + } + } + self.end() // close enclosing cbox + } + // Returns whether it printed anything fn print_explicit_self(&mut self, explicit_self: ast::ExplicitSelf_, diff --git a/src/test/pretty/match-block-expr.rs b/src/test/pretty/match-block-expr.rs new file mode 100644 index 0000000000000..44771a29bb4fd --- /dev/null +++ b/src/test/pretty/match-block-expr.rs @@ -0,0 +1,16 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pp-exact + +fn main() { + let x = match { 5i } { 1 => 5i, 2 => 6, _ => 7, }; + assert_eq!(x , 7); +} diff --git a/src/test/pretty/match-naked-expr-medium.rs b/src/test/pretty/match-naked-expr-medium.rs index c03ad49947892..d2f8157ef6213 100644 --- a/src/test/pretty/match-naked-expr-medium.rs +++ b/src/test/pretty/match-naked-expr-medium.rs @@ -19,6 +19,6 @@ fn main() { "long".to_string(), "string".to_string()], None => ["none".to_string(), "a".to_string(), "a".to_string(), - "a".to_string(), "a".to_string()] + "a".to_string(), "a".to_string()], }; } diff --git a/src/test/pretty/match-naked-expr.rs b/src/test/pretty/match-naked-expr.rs index 67c389f7e1f08..6b4f579f9c51c 100644 --- a/src/test/pretty/match-naked-expr.rs +++ b/src/test/pretty/match-naked-expr.rs @@ -15,6 +15,6 @@ fn main() { let _y = match x { Some(_) => "some(_)".to_string(), - None => "none".to_string() + None => "none".to_string(), }; }