Skip to content

Commit 05547d9

Browse files
rchaser53topecongiro
authored andcommitted
leave the comment in parentheses of argumentless Fn (rust-lang#3518)
1 parent 1f61286 commit 05547d9

File tree

4 files changed

+127
-37
lines changed

4 files changed

+127
-37
lines changed

src/source_map.rs

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub trait SpanUtils {
1111
fn span_after(&self, original: Span, needle: &str) -> BytePos;
1212
fn span_after_last(&self, original: Span, needle: &str) -> BytePos;
1313
fn span_before(&self, original: Span, needle: &str) -> BytePos;
14+
fn span_before_last(&self, original: Span, needle: &str) -> BytePos;
1415
fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos>;
1516
fn opt_span_before(&self, original: Span, needle: &str) -> Option<BytePos>;
1617
}
@@ -56,6 +57,17 @@ impl<'a> SpanUtils for SnippetProvider<'a> {
5657
})
5758
}
5859

60+
fn span_before_last(&self, original: Span, needle: &str) -> BytePos {
61+
let snippet = self.span_to_snippet(original).unwrap();
62+
let mut offset = 0;
63+
64+
while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
65+
offset += additional_offset + needle.len();
66+
}
67+
68+
original.lo() + BytePos(offset as u32 - 1)
69+
}
70+
5971
fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos> {
6072
self.opt_span_before(original, needle)
6173
.map(|bytepos| bytepos + BytePos(needle.len() as u32))

src/types.rs

+64-37
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use syntax::symbol::keywords;
88
use crate::config::lists::*;
99
use crate::config::{IndentStyle, TypeDensity};
1010
use crate::expr::{format_expr, rewrite_assign_rhs, rewrite_tuple, rewrite_unary_prefix, ExprType};
11-
use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
11+
use crate::lists::{
12+
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
13+
};
1214
use crate::macros::{rewrite_macro, MacroPosition};
1315
use crate::overflow;
1416
use crate::pairs::{rewrite_pair, PairParts};
@@ -314,47 +316,56 @@ where
314316
let offset = shape.indent + 1;
315317
Shape::legacy(budget, offset)
316318
};
319+
317320
let list_lo = context.snippet_provider.span_after(span, "(");
318-
let items = itemize_list(
319-
context.snippet_provider,
320-
inputs,
321-
")",
322-
",",
323-
|arg| arg.span().lo(),
324-
|arg| arg.span().hi(),
325-
|arg| arg.rewrite(context, list_shape),
326-
list_lo,
327-
span.hi(),
328-
false,
329-
);
321+
let (list_str, tactic) = if inputs.len() == 0 {
322+
let tactic = get_tactics(&[], &output, shape);
323+
let list_hi = context.snippet_provider.span_before_last(span, ")");
324+
let comment = context
325+
.snippet_provider
326+
.span_to_snippet(mk_sp(list_lo, list_hi))?
327+
.trim();
328+
let comment = if comment.starts_with("//") {
329+
format!(
330+
"{}{}{}",
331+
&list_shape.indent.to_string_with_newline(context.config),
332+
comment,
333+
&shape.block().indent.to_string_with_newline(context.config)
334+
)
335+
} else {
336+
comment.to_string()
337+
};
338+
(comment, tactic)
339+
} else {
340+
let items = itemize_list(
341+
context.snippet_provider,
342+
inputs,
343+
")",
344+
",",
345+
|arg| arg.span().lo(),
346+
|arg| arg.span().hi(),
347+
|arg| arg.rewrite(context, list_shape),
348+
list_lo,
349+
span.hi(),
350+
false,
351+
);
330352

331-
let item_vec: Vec<_> = items.collect();
353+
let item_vec: Vec<_> = items.collect();
354+
let tactic = get_tactics(&item_vec, &output, shape);
355+
let trailing_separator = if !context.use_block_indent() || variadic {
356+
SeparatorTactic::Never
357+
} else {
358+
context.config.trailing_comma()
359+
};
332360

333-
// If the return type is multi-lined, then force to use multiple lines for
334-
// arguments as well.
335-
let tactic = if output.contains('\n') {
336-
DefinitiveListTactic::Vertical
337-
} else {
338-
definitive_tactic(
339-
&*item_vec,
340-
ListTactic::HorizontalVertical,
341-
Separator::Comma,
342-
shape.width.saturating_sub(2 + output.len()),
343-
)
344-
};
345-
let trailing_separator = if !context.use_block_indent() || variadic {
346-
SeparatorTactic::Never
347-
} else {
348-
context.config.trailing_comma()
361+
let fmt = ListFormatting::new(list_shape, context.config)
362+
.tactic(tactic)
363+
.trailing_separator(trailing_separator)
364+
.ends_with_newline(tactic.ends_with_newline(context.config.indent_style()))
365+
.preserve_newline(true);
366+
(write_list(&item_vec, &fmt)?, tactic)
349367
};
350368

351-
let fmt = ListFormatting::new(list_shape, context.config)
352-
.tactic(tactic)
353-
.trailing_separator(trailing_separator)
354-
.ends_with_newline(tactic.ends_with_newline(context.config.indent_style()))
355-
.preserve_newline(true);
356-
let list_str = write_list(&item_vec, &fmt)?;
357-
358369
let args = if tactic == DefinitiveListTactic::Horizontal || !context.use_block_indent() {
359370
format!("({})", list_str)
360371
} else {
@@ -381,6 +392,22 @@ fn type_bound_colon(context: &RewriteContext<'_>) -> &'static str {
381392
colon_spaces(context.config)
382393
}
383394

395+
// If the return type is multi-lined, then force to use multiple lines for
396+
// arguments as well.
397+
fn get_tactics(item_vec: &[ListItem], output: &str, shape: Shape) -> DefinitiveListTactic {
398+
if output.contains('\n') {
399+
DefinitiveListTactic::Vertical
400+
} else {
401+
definitive_tactic(
402+
item_vec,
403+
ListTactic::HorizontalVertical,
404+
Separator::Comma,
405+
// 2 is for the case of ',\n'
406+
shape.width.saturating_sub(2 + output.len()),
407+
)
408+
}
409+
}
410+
384411
impl Rewrite for ast::WherePredicate {
385412
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
386413
// FIXME: dead spans?

tests/source/issue-3508.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
fn foo<F>(foo2: F)
2+
where
3+
F: Fn(
4+
// this comment is deleted
5+
),
6+
{
7+
}
8+
9+
fn foo_block<F>(foo2: F)
10+
where
11+
F: Fn(
12+
/* this comment is deleted */
13+
),
14+
{
15+
}
16+
17+
fn bar(
18+
bar2: impl Fn(
19+
// this comment is deleted
20+
),
21+
) {
22+
}
23+
24+
fn bar_block(
25+
bar2: impl Fn(
26+
/* this comment is deleted */
27+
),
28+
) {
29+
}

tests/target/issue-3508.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fn foo<F>(foo2: F)
2+
where
3+
F: Fn(
4+
// this comment is deleted
5+
),
6+
{
7+
}
8+
9+
fn foo_block<F>(foo2: F)
10+
where
11+
F: Fn(/* this comment is deleted */),
12+
{
13+
}
14+
15+
fn bar(
16+
bar2: impl Fn(
17+
// this comment is deleted
18+
),
19+
) {
20+
}
21+
22+
fn bar_block(bar2: impl Fn(/* this comment is deleted */)) {}

0 commit comments

Comments
 (0)