Skip to content

Commit a4fdec9

Browse files
committed
Keep the comment after where clause that has no predicate (rust-lang#4649)
1 parent a9876e8 commit a4fdec9

File tree

7 files changed

+83
-50
lines changed

7 files changed

+83
-50
lines changed

src/formatting/items.rs

+36-46
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::formatting::{
3434
vertical::rewrite_with_alignment,
3535
visitor::FmtVisitor,
3636
};
37+
use std::ops::Add;
3738

3839
const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
3940
kind: ast::VisibilityKind::Inherited,
@@ -2528,34 +2529,6 @@ fn rewrite_fn_base(
25282529
} else {
25292530
result.push_str(&ret_str);
25302531
}
2531-
2532-
if where_clause.predicates.is_empty() {
2533-
// Comment between return type and the end of the decl.
2534-
// Even if there are no predicates in the where clause, the "where" kw may be present,
2535-
// so start the snippet after it.
2536-
let snippet_lo = where_clause.span.hi();
2537-
let snippet_hi = span.hi();
2538-
let snippet = context.snippet(mk_sp(snippet_lo, snippet_hi));
2539-
// Try to preserve the layout of the original snippet.
2540-
let original_starts_with_newline = snippet
2541-
.find(|c| c != ' ')
2542-
.map_or(false, |i| starts_with_newline(&snippet[i..]));
2543-
let original_ends_with_newline = snippet
2544-
.rfind(|c| c != ' ')
2545-
.map_or(false, |i| snippet[i..].ends_with('\n'));
2546-
let snippet = snippet.trim();
2547-
if !snippet.is_empty() {
2548-
result.push(if original_starts_with_newline {
2549-
'\n'
2550-
} else {
2551-
' '
2552-
});
2553-
result.push_str(snippet);
2554-
if original_ends_with_newline {
2555-
force_new_line_for_brace = true;
2556-
}
2557-
}
2558-
}
25592532
}
25602533

25612534
let pos_before_where = match fd.output {
@@ -2585,27 +2558,44 @@ fn rewrite_fn_base(
25852558
pos_before_where,
25862559
option,
25872560
)?;
2588-
// If there are neither where-clause nor return type, we may be missing comments between
2589-
// params and `{`.
2590-
if where_clause_str.is_empty() {
2591-
if let ast::FnRetTy::Default(ret_span) = fd.output {
2592-
match recover_missing_comment_in_span(
2593-
mk_sp(params_span.hi(), ret_span.hi()),
2594-
shape,
2595-
context,
2596-
last_line_width(&result),
2597-
) {
2598-
Some(ref missing_comment) if !missing_comment.is_empty() => {
2599-
result.push_str(missing_comment);
2600-
force_new_line_for_brace = true;
2601-
}
2602-
_ => {}
2561+
2562+
result.push_str(&where_clause_str);
2563+
if where_clause.predicates.is_empty() {
2564+
// Comment between return type and the end of the decl.
2565+
// Even if there are no predicates in the where clause, the "where" kw may be present,
2566+
// so start the snippet after it.
2567+
let snippet_lo = where_clause.span.hi();
2568+
let snippet_hi = span.hi();
2569+
let comment_indent = match where_clause.has_where_token {
2570+
true => shape.indent.add(context.config.tab_spaces()),
2571+
false => shape.indent,
2572+
};
2573+
let mut comment_shape = shape;
2574+
comment_shape.indent = comment_indent;
2575+
let missing_comment = recover_missing_comment_in_span(
2576+
mk_sp(snippet_lo, snippet_hi),
2577+
comment_shape,
2578+
context,
2579+
comment_indent.width(),
2580+
)
2581+
.unwrap_or(String::new());
2582+
if !missing_comment.is_empty() {
2583+
// If the comment is more than one line, start it at the line after where
2584+
if where_clause.has_where_token {
2585+
result.push_str(&*format!(
2586+
"\n{}where\n{}",
2587+
(shape.indent).to_string(context.config),
2588+
missing_comment.trim_start_matches('\n'),
2589+
));
2590+
} else {
2591+
result.push_str(&*missing_comment);
26032592
}
2593+
force_new_line_for_brace = context
2594+
.snippet(mk_sp(snippet_lo, snippet_hi))
2595+
.trim_end_matches(' ')
2596+
.ends_with('\n');
26042597
}
26052598
}
2606-
2607-
result.push_str(&where_clause_str);
2608-
26092599
let ends_with_comment = last_line_contains_single_line_comment(&result);
26102600
force_new_line_for_brace |= ends_with_comment;
26112601
force_new_line_for_brace |=

tests/source/issue-4649.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Bar {
2+
fn bar(&self, a: T)
3+
where
4+
// Self: Bar
5+
// Some comment
6+
;
7+
8+
fn bar2(&self, a: T) where /* Self: Bar */ ;
9+
}

tests/source/where-clause.rs

+10
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,13 @@ pub trait AsUnindented {
6565
fn f<T: AsUnindented<
6666
Output<'static> = U>, U>() where U: AsUnindented<
6767
Output<'static> = i32> {}
68+
69+
fn foo2<T>()
70+
where T: FnOnce()
71+
// Comments
72+
{}
73+
74+
fn foo3<T, U>()
75+
where T: FnOnce(), // Comments
76+
U: FnOnce()
77+
{}

tests/target/issue-1113.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ pub fn foo() -> fmt::Result
2525
}
2626

2727
pub fn foo() -> fmt::Result /*
28-
*
29-
*
30-
*/
28+
*
29+
*
30+
*/
3131
{
3232
panic!()
3333
}

tests/target/issue-4001.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
fn unit() -> () /* comment */ {
1+
fn unit() -> ()
2+
where
3+
/* comment */ {
24
()
35
}

tests/target/issue-4649.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trait Bar {
2+
fn bar(&self, a: T)
3+
where
4+
// Self: Bar
5+
// Some comment
6+
;
7+
8+
fn bar2(&self, a: T)
9+
where
10+
/* Self: Bar */;
11+
}

tests/target/where-clause.rs

+11
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,14 @@ fn f<T: AsUnindented<Output<'static> = U>, U>()
115115
where U: AsUnindented<Output<'static> = i32>
116116
{
117117
}
118+
119+
fn foo2<T>()
120+
where T: FnOnce() // Comments
121+
{
122+
}
123+
124+
fn foo3<T, U>()
125+
where T: FnOnce(), // Comments
126+
U: FnOnce()
127+
{
128+
}

0 commit comments

Comments
 (0)