Skip to content

Commit c546f1b

Browse files
authored
Merge pull request #1454 from topecongiro/match
Format nested mathces properly.
2 parents 2223b64 + 3d2cd68 commit c546f1b

File tree

8 files changed

+219
-52
lines changed

8 files changed

+219
-52
lines changed

src/chains.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,18 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
200200
if fits_single_line {
201201
fits_single_line = match expr.node {
202202
ref e @ ast::ExprKind::MethodCall(..) => {
203-
rewrite_method_call_with_overflow(e,
204-
&mut last[0],
205-
almost_total,
206-
total_span,
207-
context,
208-
shape)
203+
if rewrite_method_call_with_overflow(e,
204+
&mut last[0],
205+
almost_total,
206+
total_span,
207+
context,
208+
shape) {
209+
// If the first line of the last method does not fit into a single line
210+
// after the others, allow new lines.
211+
almost_total + first_line_width(&last[0]) < context.config.max_width
212+
} else {
213+
false
214+
}
209215
}
210216
_ => !last[0].contains('\n'),
211217
}

src/expr.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,8 @@ fn format_expr(expr: &ast::Expr,
176176
ast::ExprKind::Mac(ref mac) => {
177177
// Failure to rewrite a marco should not imply failure to
178178
// rewrite the expression.
179-
rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| {
180-
wrap_str(context.snippet(expr.span), context.config.max_width, shape)
181-
})
179+
rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
180+
.or_else(|| wrap_str(context.snippet(expr.span), context.config.max_width, shape))
182181
}
183182
ast::ExprKind::Ret(None) => wrap_str("return".to_owned(), context.config.max_width, shape),
184183
ast::ExprKind::Ret(Some(ref expr)) => {
@@ -582,14 +581,18 @@ fn rewrite_closure(capture: ast::CaptureBy,
582581

583582
let block_threshold = context.config.closure_block_indent_threshold;
584583
if block_threshold < 0 || rewrite.matches('\n').count() <= block_threshold as usize {
585-
return Some(format!("{} {}", prefix, rewrite));
584+
if let Some(rewrite) = wrap_str(rewrite, context.config.max_width, shape) {
585+
return Some(format!("{} {}", prefix, rewrite));
586+
}
586587
}
587588

588589
// The body of the closure is big enough to be block indented, that
589590
// means we must re-format.
590591
let block_shape = shape.block();
591592
let rewrite = try_opt!(block.rewrite(&context, block_shape));
592-
Some(format!("{} {}", prefix, rewrite))
593+
Some(format!("{} {}",
594+
prefix,
595+
try_opt!(wrap_str(rewrite, block_shape.width, block_shape))))
593596
}
594597
}
595598

@@ -1341,11 +1344,10 @@ impl Rewrite for ast::Arm {
13411344
// 4 = ` => `.len()
13421345
if shape.width > pat_width + comma.len() + 4 {
13431346
let arm_shape = shape
1344-
.shrink_left(pat_width + 4)
1347+
.offset_left(pat_width + 4)
13451348
.unwrap()
13461349
.sub_width(comma.len())
1347-
.unwrap()
1348-
.block();
1350+
.unwrap();
13491351
let rewrite = nop_block_collapse(body.rewrite(context, arm_shape), arm_shape.width);
13501352
let is_block = if let ast::ExprKind::Block(..) = body.node {
13511353
true

src/file_lines.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,8 @@ impl JsonSpan {
194194
// To allow `collect()`ing into a `MultiMap`.
195195
fn into_tuple(self) -> Result<(String, Range), String> {
196196
let (lo, hi) = self.range;
197-
let canonical = try!(canonicalize_path_string(&self.file).map_err(|_| {
198-
format!("Can't canonicalize {}", &self.file)
199-
}));
197+
let canonical = try!(canonicalize_path_string(&self.file)
198+
.map_err(|_| format!("Can't canonicalize {}", &self.file)));
200199
Ok((canonical, Range::new(lo, hi)))
201200
}
202201
}

src/items.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,12 +1300,13 @@ pub fn rewrite_associated_type(ident: ast::Ident,
13001300

13011301
let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
13021302
let bounds: &[_] = ty_param_bounds;
1303-
let bound_str = try_opt!(bounds.iter()
1304-
.map(|ty_bound| {
1305-
ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent))
1306-
})
1307-
.intersperse(Some(" + ".to_string()))
1308-
.collect::<Option<String>>());
1303+
let bound_str = try_opt!(bounds
1304+
.iter()
1305+
.map(|ty_bound| {
1306+
ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent))
1307+
})
1308+
.intersperse(Some(" + ".to_string()))
1309+
.collect::<Option<String>>());
13091310
if bounds.len() > 0 {
13101311
format!(": {}", bound_str)
13111312
} else {

src/macros.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,11 @@ pub fn rewrite_macro(mac: &ast::Mac,
146146
MacroStyle::Parens => {
147147
// Format macro invocation as function call, forcing no trailing
148148
// comma because not all macros support them.
149-
rewrite_call(context, &macro_name, &expr_vec, mac.span, shape, true).map(|rw| {
150-
match position {
151-
MacroPosition::Item => format!("{};", rw),
152-
_ => rw,
153-
}
154-
})
149+
rewrite_call(context, &macro_name, &expr_vec, mac.span, shape, true)
150+
.map(|rw| match position {
151+
MacroPosition::Item => format!("{};", rw),
152+
_ => rw,
153+
})
155154
}
156155
MacroStyle::Brackets => {
157156
// Format macro invocation as array literal.

src/types.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -587,31 +587,34 @@ impl Rewrite for ast::Ty {
587587
let mut_len = mut_str.len();
588588
Some(match *lifetime {
589589
Some(ref lifetime) => {
590-
let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len));
591-
let lt_str = try_opt!(lifetime.rewrite(context,
592-
Shape::legacy(lt_budget,
590+
let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len));
591+
let lt_str = try_opt!(lifetime.rewrite(context,
592+
Shape::legacy(lt_budget,
593+
shape.indent +
594+
2 +
595+
mut_len)));
596+
let lt_len = lt_str.len();
597+
let budget = try_opt!(shape.width.checked_sub(2 + mut_len + lt_len));
598+
format!("&{} {}{}",
599+
lt_str,
600+
mut_str,
601+
try_opt!(mt.ty
602+
.rewrite(context,
603+
Shape::legacy(budget,
593604
shape.indent + 2 +
594-
mut_len)));
595-
let lt_len = lt_str.len();
596-
let budget = try_opt!(shape.width.checked_sub(2 + mut_len + lt_len));
597-
format!("&{} {}{}",
598-
lt_str,
599-
mut_str,
600-
try_opt!(mt.ty
601-
.rewrite(context,
602-
Shape::legacy(budget,
603-
shape.indent + 2 + mut_len +
604-
lt_len))))
605-
}
605+
mut_len +
606+
lt_len))))
607+
}
606608
None => {
607-
let budget = try_opt!(shape.width.checked_sub(1 + mut_len));
608-
format!("&{}{}",
609-
mut_str,
610-
try_opt!(mt.ty
611-
.rewrite(context,
612-
Shape::legacy(budget,
613-
shape.indent + 1 + mut_len))))
614-
}
609+
let budget = try_opt!(shape.width.checked_sub(1 + mut_len));
610+
format!("&{}{}",
611+
mut_str,
612+
try_opt!(mt.ty
613+
.rewrite(context,
614+
Shape::legacy(budget,
615+
shape.indent + 1 +
616+
mut_len))))
617+
}
615618
})
616619
}
617620
// FIXME: we drop any comments here, even though it's a silly place to put

tests/source/match.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,81 @@ fn guards() {
295295
(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {}
296296
}
297297
}
298+
299+
fn issue1371() {
300+
Some(match type_ {
301+
sfEvtClosed => Closed,
302+
sfEvtResized => {
303+
let e = unsafe { *event.size.as_ref() };
304+
305+
Resized {
306+
width: e.width,
307+
height: e.height,
308+
}
309+
}
310+
sfEvtLostFocus => LostFocus,
311+
sfEvtGainedFocus => GainedFocus,
312+
sfEvtTextEntered => {
313+
TextEntered {
314+
unicode: unsafe {
315+
::std::char::from_u32((*event.text.as_ref()).unicode)
316+
.expect("Invalid unicode encountered on TextEntered event")
317+
},
318+
}
319+
}
320+
sfEvtKeyPressed => {
321+
let e = unsafe { event.key.as_ref() };
322+
323+
KeyPressed {
324+
code: unsafe { ::std::mem::transmute(e.code) },
325+
alt: e.alt.to_bool(),
326+
ctrl: e.control.to_bool(),
327+
shift: e.shift.to_bool(),
328+
system: e.system.to_bool(),
329+
}
330+
}
331+
sfEvtKeyReleased => {
332+
let e = unsafe { event.key.as_ref() };
333+
334+
KeyReleased {
335+
code: unsafe { ::std::mem::transmute(e.code) },
336+
alt: e.alt.to_bool(),
337+
ctrl: e.control.to_bool(),
338+
shift: e.shift.to_bool(),
339+
system: e.system.to_bool(),
340+
}
341+
}
342+
})
343+
}
344+
345+
fn issue1395() {
346+
let bar = Some(true);
347+
let foo = Some(true);
348+
let mut x = false;
349+
bar.and_then(|_| {
350+
match foo {
351+
None => None,
352+
Some(b) => {
353+
x = true;
354+
Some(b)
355+
}
356+
}
357+
});
358+
}
359+
360+
fn issue1456() {
361+
Ok(Recording {
362+
artists: match reader.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? {
363+
Nodeset(nodeset) => {
364+
let res: Result<Vec<ArtistRef>, ReadError> = nodeset
365+
.iter()
366+
.map(|node| {
367+
XPathNodeReader::new(node, &context).and_then(|r| ArtistRef::from_xml(&r))
368+
})
369+
.collect();
370+
res?
371+
}
372+
_ => Vec::new(),
373+
},
374+
})
375+
}

tests/target/match.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,82 @@ fn guards() {
310310
cccccccccccccccccccccccccccccccccccccccc) => {}
311311
}
312312
}
313+
314+
fn issue1371() {
315+
Some(match type_ {
316+
sfEvtClosed => Closed,
317+
sfEvtResized => {
318+
let e = unsafe { *event.size.as_ref() };
319+
320+
Resized {
321+
width: e.width,
322+
height: e.height,
323+
}
324+
}
325+
sfEvtLostFocus => LostFocus,
326+
sfEvtGainedFocus => GainedFocus,
327+
sfEvtTextEntered => {
328+
TextEntered {
329+
unicode:
330+
unsafe {
331+
::std::char::from_u32((*event.text.as_ref()).unicode)
332+
.expect("Invalid unicode encountered on TextEntered event")
333+
},
334+
}
335+
}
336+
sfEvtKeyPressed => {
337+
let e = unsafe { event.key.as_ref() };
338+
339+
KeyPressed {
340+
code: unsafe { ::std::mem::transmute(e.code) },
341+
alt: e.alt.to_bool(),
342+
ctrl: e.control.to_bool(),
343+
shift: e.shift.to_bool(),
344+
system: e.system.to_bool(),
345+
}
346+
}
347+
sfEvtKeyReleased => {
348+
let e = unsafe { event.key.as_ref() };
349+
350+
KeyReleased {
351+
code: unsafe { ::std::mem::transmute(e.code) },
352+
alt: e.alt.to_bool(),
353+
ctrl: e.control.to_bool(),
354+
shift: e.shift.to_bool(),
355+
system: e.system.to_bool(),
356+
}
357+
}
358+
})
359+
}
360+
361+
fn issue1395() {
362+
let bar = Some(true);
363+
let foo = Some(true);
364+
let mut x = false;
365+
bar.and_then(|_| match foo {
366+
None => None,
367+
Some(b) => {
368+
x = true;
369+
Some(b)
370+
}
371+
});
372+
}
373+
374+
fn issue1456() {
375+
Ok(Recording {
376+
artists: match reader
377+
.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? {
378+
Nodeset(nodeset) => {
379+
let res: Result<Vec<ArtistRef>, ReadError> = nodeset
380+
.iter()
381+
.map(|node| {
382+
XPathNodeReader::new(node, &context)
383+
.and_then(|r| ArtistRef::from_xml(&r))
384+
})
385+
.collect();
386+
res?
387+
}
388+
_ => Vec::new(),
389+
},
390+
})
391+
}

0 commit comments

Comments
 (0)