1
Fork 0

Fix a bug pretty printing match { 5i } { _ => { } }

This also always puts a trailing comma on the last non-block expr.
This commit is contained in:
Erick Tryzelaar 2014-07-27 18:05:07 -07:00
parent a46463d179
commit 1200ad0f06
5 changed files with 71 additions and 50 deletions

View file

@ -147,6 +147,7 @@ pub mod rt {
impl_to_source!(Gc<ast::Stmt>, stmt_to_string)
impl_to_source!(Gc<ast::Expr>, expr_to_string)
impl_to_source!(Gc<ast::Pat>, pat_to_string)
impl_to_source!(ast::Arm, arm_to_string)
impl_to_source_slice!(ast::Ty, ", ")
impl_to_source_slice!(Gc<ast::Item>, "\n\n")
@ -240,6 +241,7 @@ pub mod rt {
impl_to_tokens!(ast::Ident)
impl_to_tokens!(Gc<ast::Item>)
impl_to_tokens!(Gc<ast::Pat>)
impl_to_tokens!(ast::Arm)
impl_to_tokens!(Gc<ast::Method>)
impl_to_tokens_lifetime!(&'a [Gc<ast::Item>])
impl_to_tokens!(ast::Ty)

View file

@ -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_,

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}

View file

@ -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()],
};
}

View file

@ -15,6 +15,6 @@ fn main() {
let _y =
match x {
Some(_) => "some(_)".to_string(),
None => "none".to_string()
None => "none".to_string(),
};
}