X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmatches.rs;h=85d9c5d2b9bbf4f3e80ec3371cc733d9dea157ea;hb=ce301d92f12658edf6fe410d39de445270d1420e;hp=954db40ae524a13989a7632696f93ab2f010a1f8;hpb=9f53665f91be16c9aa7afd83f7c79357fec9152b;p=rust.git diff --git a/src/matches.rs b/src/matches.rs index 954db40ae52..85d9c5d2b9b 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -2,12 +2,12 @@ use std::iter::repeat; +use rustc_ast::{ast, ptr}; use rustc_span::{BytePos, Span}; -use syntax::{ast, ptr}; use crate::comment::{combine_strs_with_missing_comments, rewrite_comment}; use crate::config::lists::*; -use crate::config::{Config, ControlBraceStyle, IndentStyle, Version}; +use crate::config::{Config, ControlBraceStyle, IndentStyle, MatchArmLeadingPipe, Version}; use crate::expr::{ format_expr, is_empty_block, is_simple_block, is_unsafe_block, prefer_next_line, rewrite_cond, ExprType, RhsTactics, @@ -45,6 +45,7 @@ fn new(arm: &'a ast::Arm, is_last: bool, beginning_vert: Option) -> Arm impl<'a> Spanned for ArmWrapper<'a> { fn span(&self) -> Span { if let Some(lo) = self.beginning_vert { + let lo = std::cmp::min(lo, self.arm.span().lo()); mk_sp(lo, self.arm.span().hi()) } else { self.arm.span() @@ -54,7 +55,13 @@ fn span(&self) -> Span { impl<'a> Rewrite for ArmWrapper<'a> { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - rewrite_match_arm(context, self.arm, shape, self.is_last) + rewrite_match_arm( + context, + self.arm, + shape, + self.is_last, + self.beginning_vert.is_some(), + ) } } @@ -156,17 +163,15 @@ fn arm_comma(config: &Config, body: &ast::Expr, is_last: bool) -> &'static str { fn collect_beginning_verts( context: &RewriteContext<'_>, arms: &[ast::Arm], - span: Span, ) -> Vec> { - let mut beginning_verts = Vec::with_capacity(arms.len()); - let mut lo = context.snippet_provider.span_after(span, "{"); - for arm in arms { - let hi = arm.pat.span.lo(); - let missing_span = mk_sp(lo, hi); - beginning_verts.push(context.snippet_provider.opt_span_before(missing_span, "|")); - lo = arm.span().hi(); - } - beginning_verts + arms.iter() + .map(|a| { + context + .snippet(a.pat.span) + .starts_with('|') + .then(|| a.pat.span().lo()) + }) + .collect() } fn rewrite_match_arms( @@ -184,7 +189,7 @@ fn rewrite_match_arms( let is_last_iter = repeat(false) .take(arm_len.saturating_sub(1)) .chain(repeat(true)); - let beginning_verts = collect_beginning_verts(context, arms, span); + let beginning_verts = collect_beginning_verts(context, arms); let items = itemize_list( context.snippet_provider, arms.iter() @@ -214,6 +219,7 @@ fn rewrite_match_arm( arm: &ast::Arm, shape: Shape, is_last: bool, + has_leading_pipe: bool, ) -> Option { let (missing_span, attrs_str) = if !arm.attrs.is_empty() { if contains_skip(&arm.attrs) { @@ -231,9 +237,17 @@ fn rewrite_match_arm( (mk_sp(arm.span().lo(), arm.span().lo()), String::new()) }; + // Leading pipe offset + // 2 = `| ` + let (pipe_offset, pipe_str) = match context.config.match_arm_leading_pipes() { + MatchArmLeadingPipe::Never => (0, ""), + MatchArmLeadingPipe::Preserve if !has_leading_pipe => (0, ""), + MatchArmLeadingPipe::Preserve | MatchArmLeadingPipe::Always => (2, "| "), + }; + // Patterns // 5 = ` => {` - let pat_shape = shape.sub_width(5)?; + let pat_shape = shape.sub_width(5)?.offset_left(pipe_offset)?; let pats_str = arm.pat.rewrite(context, pat_shape)?; // Guard @@ -250,7 +264,7 @@ fn rewrite_match_arm( let lhs_str = combine_strs_with_missing_comments( context, &attrs_str, - &format!("{}{}", pats_str, guard_str), + &format!("{}{}{}", pipe_str, pats_str, guard_str), missing_span, shape, false, @@ -268,6 +282,15 @@ fn rewrite_match_arm( ) } +fn stmt_is_expr_mac(stmt: &ast::Stmt) -> bool { + if let ast::StmtKind::Expr(expr) = &stmt.kind { + if let ast::ExprKind::MacCall(_) = &expr.kind { + return true; + } + } + false +} + fn block_can_be_flattened<'a>( context: &RewriteContext<'_>, expr: &'a ast::Expr, @@ -276,7 +299,8 @@ fn block_can_be_flattened<'a>( ast::ExprKind::Block(ref block, _) if !is_unsafe_block(block) && !context.inside_macro() - && is_simple_block(block, Some(&expr.attrs), context.source_map) => + && is_simple_block(context, block, Some(&expr.attrs)) + && !stmt_is_expr_mac(&block.stmts[0]) => { Some(&*block) } @@ -295,10 +319,14 @@ fn flatten_arm_body<'a>( let can_extend = |expr| !context.config.force_multiline_blocks() && can_flatten_block_around_this(expr); - if let Some(ref block) = block_can_be_flattened(context, body) { + if let Some(block) = block_can_be_flattened(context, body) { if let ast::StmtKind::Expr(ref expr) = block.stmts[0].kind { if let ast::ExprKind::Block(..) = expr.kind { - flatten_arm_body(context, expr, None) + if expr.attrs.is_empty() { + flatten_arm_body(context, expr, None) + } else { + (true, body) + } } else { let cond_becomes_muti_line = opt_shape .and_then(|shape| rewrite_cond(context, expr, shape)) @@ -332,10 +360,7 @@ fn rewrite_match_body( shape.offset_left(extra_offset(pats_str, shape) + 4), ); let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block, _) = body.kind { - ( - true, - is_empty_block(block, Some(&body.attrs), context.source_map), - ) + (true, is_empty_block(context, block, Some(&body.attrs))) } else { (false, false) }; @@ -372,7 +397,7 @@ fn rewrite_match_body( if comment_str.is_empty() { String::new() } else { - rewrite_comment(comment_str, false, shape, &context.config)? + rewrite_comment(comment_str, false, shape, context.config)? } }; @@ -387,7 +412,8 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&nested_indent_str); - result.push_str(&body_str); + result.push_str(body_str); + result.push_str(comma); return Some(result); } @@ -429,7 +455,7 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&block_sep); - result.push_str(&body_str); + result.push_str(body_str); result.push_str(&body_suffix); Some(result) }; @@ -562,7 +588,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool { | ast::ExprKind::Array(..) | ast::ExprKind::Call(..) | ast::ExprKind::MethodCall(..) - | ast::ExprKind::Mac(..) + | ast::ExprKind::MacCall(..) | ast::ExprKind::Struct(..) | ast::ExprKind::Tup(..) => true, ast::ExprKind::AddrOf(_, _, ref expr)