Skip to content

Handling fn empty where and comments after return type #5411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 84 additions & 78 deletions Cargo.lock

Large diffs are not rendered by default.

81 changes: 57 additions & 24 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2418,30 +2418,48 @@ fn rewrite_fn_base(
result.push_str(&ret_str);
}

// Comment between return type and the end of the decl.
let snippet_lo = fd.output.span().hi();
if where_clause.predicates.is_empty() {
let snippet_hi = span.hi();
let snippet = context.snippet(mk_sp(snippet_lo, snippet_hi));
// Closure to handle a comment in a snippet
let mut snippet_comment_handling = |span_lo, span_hi, consider_force_new_line_for_brace| {
let snippet = context.snippet(mk_sp(span_lo, span_hi));
// Try to preserve the layout of the original snippet.
let original_starts_with_newline = snippet
.find(|c| c != ' ')
.map_or(false, |i| starts_with_newline(&snippet[i..]));
let original_starts_with_newline = (consider_force_new_line_for_brace
&& force_new_line_for_brace)
|| snippet
.find(|c| c != ' ')
.map_or(false, |i| starts_with_newline(&snippet[i..]));
let original_ends_with_newline = snippet
.rfind(|c| c != ' ')
.map_or(false, |i| snippet[i..].ends_with('\n'));
.map_or(false, |i| snippet[..i + 1].ends_with('\n'));
let snippet = snippet.trim();
if !snippet.is_empty() {
result.push(if original_starts_with_newline {
'\n'
if original_starts_with_newline {
result.push_str(&indent.to_string_with_newline(context.config));
} else {
' '
});
result.push(' ');
}
result.push_str(snippet);
if original_ends_with_newline {
force_new_line_for_brace = true;
} else {
force_new_line_for_brace = false;
}
}
};

// Comments between return type and the end of the decl.
if where_clause.predicates.is_empty() {
// Comment up to empty-where is exist or up to end of declaration
let snippet_hi = if where_clause.has_where_token {
where_clause.span.lo()
} else {
span.hi()
};
snippet_comment_handling(fd.output.span().hi(), snippet_hi, false);

// Comment post empty-where to end of declaration
if where_clause.has_where_token {
snippet_comment_handling(where_clause.span.hi(), span.hi(), true);
}
}
}

Expand Down Expand Up @@ -2473,21 +2491,36 @@ fn rewrite_fn_base(
pos_before_where,
option,
)?;

// Closure for recovering empty where clause
let mut recover_empty_where_span_comment = |lo, hi| match recover_missing_comment_in_span(
mk_sp(lo, hi),
shape,
context,
last_line_width(&result),
) {
Some(ref missing_comment) if !missing_comment.is_empty() => {
result.push_str(missing_comment);
force_new_line_for_brace = true;
}
_ => (),
};

// If there are neither where-clause nor return type, we may be missing comments between
// params and `{`.
if where_clause_str.is_empty() {
if let ast::FnRetTy::Default(ret_span) = fd.output {
match recover_missing_comment_in_span(
mk_sp(params_span.hi(), ret_span.hi()),
shape,
context,
last_line_width(&result),
) {
Some(ref missing_comment) if !missing_comment.is_empty() => {
result.push_str(missing_comment);
force_new_line_for_brace = true;
}
_ => (),
// Pre where clause comment
let (span_lo, span_hi) = if where_clause.has_where_token {
(params_span.hi(), where_clause.span.lo())
} else {
(params_span.hi(), ret_span.hi())
};
recover_empty_where_span_comment(span_lo, span_hi);

// Post where clause comment
if where_clause.has_where_token {
recover_empty_where_span_comment(where_clause.span.hi(), span.hi());
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions tests/source/issue-4649/one.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// rustfmt-version: One

// Original from #4649
trait Foo {
fn bar(&self)
where
// Self: Bar
// Some comment
;
}

fn foo<T>()
where
// T: Bar,
// Some comment
{
println!("foo");
}
18 changes: 18 additions & 0 deletions tests/source/issue-4649/two.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// rustfmt-version: Two

// Original from #4649
trait Foo {
fn bar(&self)
where
// Self: Bar
// Some comment
;
}

fn foo<T>()
where
// T: Bar,
// Some comment
{
println!("foo");
}
148 changes: 148 additions & 0 deletions tests/source/issue-5407/one.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// rustfmt-version: One

// Original - return-type and empty "where" - no comments
mod inner {
fn foo1() -> String
where {
String::new()
}
}

mod inner {
fn foo2() -> String
{
String::new()
}
}

// Return-type with no "where" - one comment
fn main () {
fn foo1() -> String /* same-line with ret-type and brace comment */ {
}
}

fn main () {
fn foo2() -> String /* same-line with ret-type comment - brace in new-line */
{
}
}

fn main () {
fn foo3() -> String
/* new-line comment - brace in new-line */
{
}
}

fn main () {
fn foo4() -> String // same-line with ret-type comment
{
}
}

// Return-type and empty "where" - one comment
fn main () {
fn foo1() -> String /* same-line with ret-type/where/brace brace pre-where comment */ where {
}
}

fn main () {
fn foo2() -> String /* same-line with ret-type/where pre-where comment - brace in new-line */ where
{
}
}

fn main () {
fn foo3() -> String /* same-line with ret-type pre-where comment - where in new-line */
where {
}
}

fn main () {
fn foo4() -> String
/* new-line pre-where comment - where in new-line */
where {
}
}

fn main () {
fn foo5() -> String // same-line with ret-type pre-where comment
where
{
}
}

fn main () {
fn foo6() -> String
// new-line pre-where comment
where
{
}
}

// Return-type and empty "where" - two inline comments
fn main () {
fn foo1() -> String /* pre-where same-line */ where /* post-where same line */ {
}
}

fn main () {
fn foo2() -> String
/* pre-where new-line */ where /* post-where same line */ {
}
}

fn main () {
fn foo3() -> String /* pre-where same with ret - where in new */
where /* post-where same line */ {
}
}

fn main () {
fn foo4() -> String /* pre-where same with ret - where in new */
where
/* post-where new line - brace in same */ {
}
}

fn main () {
fn foo5() -> String
/* pre-where new line - where in new */
where
/* post-where new line - brace in same */ {
}
}

fn main () {
fn foo6() -> String
/* pre-where new line - where in new */
where
/* post-where new line - brace in new */
{
}
}

// Return-type and empty "where" - two one-line comments
fn main () {
fn foo1() -> String // pre-where same with ret - where in new
where // post-where same with where - brace in new
{
}
}

fn main () {
fn foo2() -> String
// pre-where new line
where // post-where same with where - brace in new
{
}
}

// Return-type and empty "where" - more comments
fn main() {
fn foo<F>(foo2: F) -> String /* pre-where same with ret - where in new */
where /* post-where same with where - following in new" */
F: Fn() /* comment after where declaration */
{
}
}
Loading