fix handling of nested comments in patterns and ControlFlows (#3869)

This commit is contained in:
Seiichi Uchida 2019-10-25 15:04:33 +09:00 committed by GitHub
commit 69cf48344b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 199 additions and 16 deletions

View File

@ -112,7 +112,7 @@ pub(crate) fn to_str_tuplet(&self) -> (&'a str, &'a str, &'a str) {
}
}
fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
pub(crate) fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
if !normalize_comments {
if orig.starts_with("/**") && !orig.starts_with("/**/") {
CommentStyle::DoubleBullet

View File

@ -9,8 +9,8 @@
use crate::chains::rewrite_chain;
use crate::closures;
use crate::comment::{
combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment,
rewrite_missing_comment, CharClasses, FindUncommented,
combine_strs_with_missing_comments, comment_style, contains_comment, recover_comment_removed,
rewrite_comment, rewrite_missing_comment, CharClasses, FindUncommented,
};
use crate::config::lists::*;
use crate::config::{Config, ControlBraceStyle, IndentStyle, Version};
@ -808,7 +808,7 @@ fn rewrite_pat_expr(
debug!("rewrite_pat_expr {:?} {:?} {:?}", shape, self.pat, expr);
let cond_shape = shape.offset_left(offset)?;
if !self.pat.is_none() {
if let Some(pat) = self.pat {
let matcher = if self.matcher.is_empty() {
self.matcher.to_owned()
} else {
@ -817,12 +817,41 @@ fn rewrite_pat_expr(
let pat_shape = cond_shape
.offset_left(matcher.len())?
.sub_width(self.connector.len())?;
let pat_string = if let Some(pat) = self.pat {
pat.rewrite(context, pat_shape)?
let pat_string = pat.rewrite(context, pat_shape)?;
let comments_lo = context
.snippet_provider
.span_after(self.span, self.connector.trim());
let missing_comments = if let Some(comment) =
rewrite_missing_comment(mk_sp(comments_lo, expr.span.lo()), cond_shape, context)
{
if !self.connector.is_empty() && !comment.is_empty() {
if comment_style(&comment, false).is_line_comment() || comment.contains("\n") {
let newline = &pat_shape
.indent
.block_indent(context.config)
.to_string_with_newline(context.config);
// An extra space is added when the lhs and rhs are joined
// so we need to remove one space from the end to ensure
// the comment and rhs are aligned.
let mut suffix = newline.as_ref().to_string();
if !suffix.is_empty() {
suffix.truncate(suffix.len() - 1);
}
format!("{}{}{}", newline, comment, suffix)
} else {
format!(" {}", comment)
}
} else {
comment
}
} else {
"".to_owned()
};
let result = format!("{}{}{}", matcher, pat_string, self.connector);
let result = format!(
"{}{}{}{}",
matcher, pat_string, self.connector, missing_comments
);
return rewrite_assign_rhs(context, result, expr, cond_shape);
}

View File

@ -89,26 +89,81 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape),
PatKind::Ident(binding_mode, ident, ref sub_pat) => {
let (prefix, mutability) = match binding_mode {
BindingMode::ByRef(mutability) => ("ref ", mutability),
BindingMode::ByRef(mutability) => ("ref", mutability),
BindingMode::ByValue(mutability) => ("", mutability),
};
let mut_infix = format_mutability(mutability);
let mut_infix = format_mutability(mutability).trim();
let id_str = rewrite_ident(context, ident);
let sub_pat = match *sub_pat {
Some(ref p) => {
// 3 - ` @ `.
// 2 - `@ `.
let width = shape
.width
.checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 3)?;
format!(
" @ {}",
p.rewrite(context, Shape::legacy(width, shape.indent))?
)
.checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 2)?;
let lo = context.snippet_provider.span_after(self.span, "@");
combine_strs_with_missing_comments(
context,
"@",
&p.rewrite(context, Shape::legacy(width, shape.indent))?,
mk_sp(lo, p.span.lo()),
shape,
true,
)?
}
None => "".to_owned(),
};
Some(format!("{}{}{}{}", prefix, mut_infix, id_str, sub_pat))
// combine prefix and mut
let (first_lo, first) = if !prefix.is_empty() && !mut_infix.is_empty() {
let hi = context.snippet_provider.span_before(self.span, "mut");
let lo = context.snippet_provider.span_after(self.span, "ref");
(
context.snippet_provider.span_after(self.span, "mut"),
combine_strs_with_missing_comments(
context,
prefix,
mut_infix,
mk_sp(lo, hi),
shape,
true,
)?,
)
} else if !prefix.is_empty() {
(
context.snippet_provider.span_after(self.span, "ref"),
prefix.to_owned(),
)
} else if !mut_infix.is_empty() {
(
context.snippet_provider.span_after(self.span, "mut"),
mut_infix.to_owned(),
)
} else {
(self.span.lo(), "".to_owned())
};
let next = if !sub_pat.is_empty() {
let hi = context.snippet_provider.span_before(self.span, "@");
combine_strs_with_missing_comments(
context,
id_str,
&sub_pat,
mk_sp(ident.span.hi(), hi),
shape,
true,
)?
} else {
id_str.to_owned()
};
combine_strs_with_missing_comments(
context,
&first,
&next,
mk_sp(first_lo, ident.span.lo()),
shape,
true,
)
}
PatKind::Wild => {
if 1 <= shape.width {

View File

@ -0,0 +1,52 @@
fn by_ref_with_block_before_ident() {
if let Some(ref /*def*/ state)= foo{
println!(
"asdfasdfasdf"); }
}
fn mut_block_before_ident() {
if let Some(mut /*def*/ state ) =foo{
println!(
"123" ); }
}
fn ref_and_mut_blocks_before_ident() {
if let Some(ref /*abc*/
mut /*def*/ state ) = foo {
println!(
"deefefefefefwea" ); }
}
fn sub_pattern() {
let foo @ /*foo*/
bar(f) = 42;
}
fn no_prefix_block_before_ident() {
if let Some(
/*def*/ state ) = foo {
println!(
"129387123123" ); }
}
fn issue_3853() {
if let Some(ref /*mut*/ state) = foo {
}
}
fn double_slash_comment_between_lhs_and_rhs() {
if let Some(e) =
// self.foo.bar(e, tx)
packet.transaction.state.committed
{
// body
println!(
"a2304712836123");
}
}
fn block_comment_between_lhs_and_rhs() {
if let Some(ref /*def*/ mut /*abc*/ state)= /*abc*/foo{
println!(
"asdfasdfasdf"); }
}

View File

@ -0,0 +1,47 @@
fn by_ref_with_block_before_ident() {
if let Some(ref /*def*/ state) = foo {
println!("asdfasdfasdf");
}
}
fn mut_block_before_ident() {
if let Some(mut /*def*/ state) = foo {
println!("123");
}
}
fn ref_and_mut_blocks_before_ident() {
if let Some(ref /*abc*/ mut /*def*/ state) = foo {
println!("deefefefefefwea");
}
}
fn sub_pattern() {
let foo @ /*foo*/ bar(f) = 42;
}
fn no_prefix_block_before_ident() {
if let Some(/*def*/ state) = foo {
println!("129387123123");
}
}
fn issue_3853() {
if let Some(ref /*mut*/ state) = foo {}
}
fn double_slash_comment_between_lhs_and_rhs() {
if let Some(e) =
// self.foo.bar(e, tx)
packet.transaction.state.committed
{
// body
println!("a2304712836123");
}
}
fn block_comment_between_lhs_and_rhs() {
if let Some(ref /*def*/ mut /*abc*/ state) = /*abc*/ foo {
println!("asdfasdfasdf");
}
}