Skip to content

Update Rustfmt (add let-else support) #113225

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

Merged
merged 17 commits into from
Jul 1, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add additional test cases
These test cases try to cover various edge cases. For example, comments
around the else keyword and long, unbreakable, single-line initializer
expressions, and long patterns.
ytmimi authored and calebcartwright committed Jun 20, 2023

Verified

This commit was signed with the committer’s verified signature.
renovate-bot Mend Renovate
commit e4a9892b7ac85e4c1a1ef7b63e2c9fa4a5aaa786
137 changes: 137 additions & 0 deletions tests/source/let_else.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,151 @@
fn main() {
// Although this won't compile it still parses so make sure we can format empty else blocks
let Some(x) = opt else {};

// let-else may be formatted on a single line if they are "short"
// and only contain a single expression
let Some(x) = opt else { return };

let Some(x) = opt else {
return
};

let Some(x) = opt else { return; };

let Some(x) = opt else {
// nope
return;
};

let Some(x) = opt else { let y = 1; return y };

let Some(x) = y.foo("abc", fairly_long_identifier, "def", "123456", "string", "cheese") else { bar() };

let Some(x) = abcdef().foo("abc", some_really_really_really_long_ident, "ident", "123456").bar().baz().qux("fffffffffffffffff") else { foo_bar() };
}

fn with_comments_around_else_keyword() {
let Some(x) = opt /* pre else keyword block-comment */ else { return };

let Some(x) = opt else /* post else keyword block-comment */ { return };

let Some(x) = opt /* pre else keyword block-comment */ else /* post else keyword block-comment */ { return };

let Some(x) = opt // pre else keyword line-comment
else { return };

let Some(x) = opt else
// post else keyword line-comment
{ return };

let Some(x) = opt // pre else keyword line-comment
else
// post else keyword line-comment
{ return };

}

fn unbreakable_initializer_expr_pre_formatting_let_else_length_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The formatting is left unchanged!
let Some(x) = some_really_really_really_really_really_really_really_long_name_A else { return };

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_long_name___B else {return};

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_long_name_____C else {some_divergent_function()};

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 101 (> max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_long_name__D else { return };
}

fn unbreakable_initializer_expr_pre_formatting_length_up_to_opening_brace_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init else {` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_really_long_name____E else {return};

// Pre Formatting:
// The length of `(indent)let pat = init else {` is 101 (> max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// which leads to the `{` exceeding the max width
let Some(x) = some_really_really_really_really_really_really_really_really_long_name_____F else {return};
}

fn unbreakable_initializer_expr_pre_formatting_length_through_initializer_expr_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init` is 99 (< max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// which leads to the `else {` exceeding the max width
let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name___G else {return};

// Pre Formatting:
// The length of `(indent)let pat = init` is 100 (max_width)
// Post Formatting:
// Break after the `=` and put the initializer expr on it's own line.
// Because the initializer expr is multi-lined the else is placed on it's own line.
let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name____H else {return};

// Pre Formatting:
// The length of `(indent)let pat = init` is 109 (> max_width)
// Post Formatting:
// Break after the `=` and put the initializer expr on it's own line.
// Because the initializer expr is multi-lined the else is placed on it's own line.
// The initializer expr has a length of 91, which when indented on the next line
// The `(indent)init` line has a lengh of 99. This is the max length that the `init` can be
// before we start running into max_width issues. I suspect this is becuase the shape is
// accounting for the `;` at the end of the `let-else` statement.
let Some(x) = some_really_really_really_really_really_really_really_really_really_really_long_name______I else {return};

// Pre Formatting:
// The length of `(indent)let pat = init` is 110 (> max_width)
// Post Formatting:
// Max length issues prevent us from formatting.
// The initializer expr has a length of 92, which if it would be indented on the next line
// the `(indent)init` line has a lengh of 100 which == max_width of 100.
// One might expect formatting to succeed, but I suspect the reason we hit max_width issues is
// because the Shape is accounting for the `;` at the end of the `let-else` statement.
let Some(x) = some_really_really_really_really_really_really_really_really_really_really_really_long_nameJ else {return};
}

fn long_patterns() {
let Foo {x: Bar(..), y: FooBar(..), z: Baz(..)} = opt else {
return;
};

// with version=One we don't wrap long array patterns
let [aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbb, cccccccccccccccccc, dddddddddddddddddd] = opt else {
return;
};

let ("aaaaaaaaaaaaaaaaaaa" | "bbbbbbbbbbbbbbbbb" | "cccccccccccccccccccccccc" | "dddddddddddddddd" | "eeeeeeeeeeeeeeee") = opt else {
return;
};

let Some(Ok((Message::ChangeColor(super::color::Color::Rgb(r, g, b)), Point { x, y, z }))) = opt else {
return;
};
}
191 changes: 191 additions & 0 deletions tests/target/let_else.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
fn main() {
// Although this won't compile it still parses so make sure we can format empty else blocks
let Some(x) = opt else {};

// let-else may be formatted on a single line if they are "short"
// and only contain a single expression
let Some(x) = opt else { return };

let Some(x) = opt else { return };

let Some(x) = opt else {
@@ -10,6 +17,11 @@ fn main() {
return;
};

let Some(x) = opt else {
let y = 1;
return y;
};

let Some(x) = y.foo(
"abc",
fairly_long_identifier,
@@ -35,3 +47,182 @@ fn main() {
foo_bar()
};
}

fn with_comments_around_else_keyword() {
let Some(x) = opt
/* pre else keyword block-comment */
else {
return;
};

let Some(x) = opt else
/* post else keyword block-comment */
{
return;
};

let Some(x) = opt
/* pre else keyword block-comment */
else
/* post else keyword block-comment */
{
return;
};

let Some(x) = opt
// pre else keyword line-comment
else {
return;
};

let Some(x) = opt else
// post else keyword line-comment
{
return;
};

let Some(x) = opt
// pre else keyword line-comment
else
// post else keyword line-comment
{
return;
};
}

fn unbreakable_initializer_expr_pre_formatting_let_else_length_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The formatting is left unchanged!
let Some(x) = some_really_really_really_really_really_really_really_long_name_A else { return };

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_long_name___B else {
return;
};

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_long_name_____C else {
some_divergent_function()
};

// Pre Formatting:
// The length of `(indent)let pat = init else block;` is 101 (> max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_long_name__D else {
return;
};
}

fn unbreakable_initializer_expr_pre_formatting_length_up_to_opening_brace_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init else {` is 100 (max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// and the else block is formatted over multiple lines because we can't fit the
// else block on the same line as the initializer expr.
let Some(x) = some_really_really_really_really_really_really_really_really_long_name____E else {
return;
};

// Pre Formatting:
// The length of `(indent)let pat = init else {` is 101 (> max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// which leads to the `{` exceeding the max width
let Some(x) = some_really_really_really_really_really_really_really_really_long_name_____F else {
return;
};
}

fn unbreakable_initializer_expr_pre_formatting_length_through_initializer_expr_near_max_width() {
// Pre Formatting:
// The length of `(indent)let pat = init` is 99 (< max_width)
// Post Formatting:
// The else keyword and opening brace remain on the same line as the initializer expr,
// which leads to the `else {` exceeding the max width
let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name___G else {
return;
};

// Pre Formatting:
// The length of `(indent)let pat = init` is 100 (max_width)
// Post Formatting:
// Break after the `=` and put the initializer expr on it's own line.
// Because the initializer expr is multi-lined the else is placed on it's own line.
let Some(x) =
some_really_really_really_really_really_really_really_really_really_long_name____H
else {
return;
};

// Pre Formatting:
// The length of `(indent)let pat = init` is 109 (> max_width)
// Post Formatting:
// Break after the `=` and put the initializer expr on it's own line.
// Because the initializer expr is multi-lined the else is placed on it's own line.
// The initializer expr has a length of 91, which when indented on the next line
// The `(indent)init` line has a lengh of 99. This is the max length that the `init` can be
// before we start running into max_width issues. I suspect this is becuase the shape is
// accounting for the `;` at the end of the `let-else` statement.
let Some(x) =
some_really_really_really_really_really_really_really_really_really_really_long_name______I
else {
return;
};

// Pre Formatting:
// The length of `(indent)let pat = init` is 110 (> max_width)
// Post Formatting:
// Max length issues prevent us from formatting.
// The initializer expr has a length of 92, which if it would be indented on the next line
// the `(indent)init` line has a lengh of 100 which == max_width of 100.
// One might expect formatting to succeed, but I suspect the reason we hit max_width issues is
// because the Shape is accounting for the `;` at the end of the `let-else` statement.
let Some(x) = some_really_really_really_really_really_really_really_really_really_really_really_long_nameJ else {return};
}

fn long_patterns() {
let Foo {
x: Bar(..),
y: FooBar(..),
z: Baz(..),
} = opt
else {
return;
};

// with version=One we don't wrap long array patterns
let [aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbb, cccccccccccccccccc, dddddddddddddddddd] = opt else {
return;
};

let ("aaaaaaaaaaaaaaaaaaa"
| "bbbbbbbbbbbbbbbbb"
| "cccccccccccccccccccccccc"
| "dddddddddddddddd"
| "eeeeeeeeeeeeeeee") = opt
else {
return;
};

let Some(Ok((Message::ChangeColor(super::color::Color::Rgb(r, g, b)), Point { x, y, z }))) =
opt
else {
return;
};
}