rust-lang / rustfmt

Format Rust code
https://rust-lang.github.io/rustfmt/
Apache License 2.0
6.07k stars 893 forks source link

Catalog `Version=Two` formatting differences #5577

Open calebcartwright opened 2 years ago

calebcartwright commented 2 years ago

To the best of my knowledge we don't have this info captured anywhere in a single place, but it's something we should have. Unfortunately I think the only way to pull this together will be scanning through the source code and trying to reproduce associated snippets with respective constructs.

@ytmimi - if you have bandwidth and are willing to look into it that'd be most appreciated, but no worries if not

ytmimi commented 2 years ago

@calebcartwright I'm happy to help look into this 😁. Would we want to add a Version Two section to each configuration's documentation or did you have something else in mind in regards to how we'd document the V1 vs V2 formatting differences?

calebcartwright commented 2 years ago

Thanks! The most immediate need is really just an enumeration of the differences in one place, as succinctly as possible. Even something as simple as comments posted on this issue would help in the short term.

ytmimi commented 2 years ago

Sure! I'll take a look through the codebase to look for all the places where we special case the formatting for Version One or Version Two. I like the idea of compiling all the differences here, and then moving them over to the docs once we've got them mostly listed out. @jmj0502 would there be any interest on your end in helping me work on this?

jmj0502 commented 2 years ago

@ytmimi I'm up for it 🚀! Thanks for taking me into consideration. It would be cool if we can define the structure we'll use to describe each V2 feature as a starting point (the simplest that comes to mind would be title -> snippet). What do you think?

jmj0502 commented 2 years ago

hard_tabs (Indentation for generics on impl blocks)

V2

The examples are taken out of the different test cases available on the master branch (the examples of this change are applied over the generics of impl blocks at top and module levels).

impl<
    Target: FromEvent<A> + FromEvent<B>,
    A: Widget2<Ctx = C>,
    B: Widget2<Ctx = C>,
    C: for<'a> CtxFamily<'a>,
> Widget2 for WidgetEventLifter<Target, A, B>
{
    type Ctx = C;
    type Event = Vec<Target>;
}

mod foo {
    impl<
        Target: FromEvent<A> + FromEvent<B>,
        A: Widget2<Ctx = C>,
        B: Widget2<Ctx = C>,
        C: for<'a> CtxFamily<'a>,
    > Widget2 for WidgetEventLifter<Target, A, B>
    {
        type Ctx = C;
        type Event = Vec<Target>;
    }
}

Reference in code base

items.rs/format_impl_ref_and_type. https://github.com/rust-lang/rustfmt/blob/ad9fb89c3009282a55582f1c478d215d0c6005b0/src/items.rs#L830-L838

Original V1 format

impl<
        Target: FromEvent<A> + FromEvent<B>,
        A: Widget2<Ctx = C>,
        B: Widget2<Ctx = C>,
        C: for<'a> CtxFamily<'a>,
    > Widget2 for WidgetEventLifter<Target, A, B>
{
    type Ctx = C;
    type Event = Vec<Target>;
}

mod foo {
    impl<
            Target: FromEvent<A> + FromEvent<B>,
            A: Widget2<Ctx = C>,
            B: Widget2<Ctx = C>,
            C: for<'a> CtxFamily<'a>,
        > Widget2 for WidgetEventLifter<Target, A, B>
    {
        type Ctx = C;
        type Event = Vec<Target>;
    }
}

@ytmimi @calebcartwright Please, let me know if there's something else you would like me to add to this code sample (a detailed description, more code, etc.). I plan to use this sample as a template for further examples.

ytmimi commented 2 years ago

@jmj0502 I like it! This is similar to the approach that I was going to take. I think maybe the only addition that would be nice is a reference to where in the codebase we conditionally check for v2 / v1 formatting.

jmj0502 commented 2 years ago

@ytmimi Cool! That would be awesome. I'll modify the example, in order to add such reference as soon as I can!

jmj0502 commented 2 years ago

Indentation for generics on impl blocks (No additional options)

V2

The examples for this particular feature are taken out of the different test cases available on the main branch. The feature is tested on top and module level impl blocks.

impl<
    Target: FromEvent<A> + FromEvent<B>,
    A: Widget2<Ctx = C>,
    B: Widget2<Ctx = C>,
    C: for<'a> CtxFamily<'a>,
> Widget2 for WidgetEventLifter<Target, A, B>
{
    type Ctx = C;
    type Event = Vec<Target>;
}

mod foo {
    impl<
        Target: FromEvent<A> + FromEvent<B>,
        A: Widget2<Ctx = C>,
        B: Widget2<Ctx = C>,
        C: for<'a> CtxFamily<'a>,
    > Widget2 for WidgetEventLifter<Target, A, B>
    {
        type Ctx = C;
        type Event = Vec<Target>;
    }
}

Reference in codebase

items.rs/format_impl_ref_and_type. https://github.com/rust-lang/rustfmt/blob/ad9fb89c3009282a55582f1c478d215d0c6005b0/src/items.rs#L830-L838

Original V1 format

impl<
        Target: FromEvent<A> + FromEvent<B>,
        A: Widget2<Ctx = C>,
        B: Widget2<Ctx = C>,
        C: for<'a> CtxFamily<'a>,
    > Widget2 for WidgetEventLifter<Target, A, B>
{
    type Ctx = C;
    type Event = Vec<Target>;
}

mod foo {
    impl<
            Target: FromEvent<A> + FromEvent<B>,
            A: Widget2<Ctx = C>,
            B: Widget2<Ctx = C>,
            C: for<'a> CtxFamily<'a>,
        > Widget2 for WidgetEventLifter<Target, A, B>
    {
        type Ctx = C;
        type Event = Vec<Target>;
    }
}
jmj0502 commented 2 years ago

Don't align unrelated trailing comments after items or at the end of blocks

Reference in codebase

V2

The examples for this feature are taken out of different test cases available on the master branch. Such test cases contain long line comments after different const and variable declarations.

pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast
// Multicast using broadcst. add.

pub const SQ_CRETAB: u16 = 0x000e; // CREATE TABLE
pub const SQ_DRPTAB: u16 = 0x000f; // DROP TABLE
pub const SQ_CREIDX: u16 = 0x0010; // CREATE INDEX
//const SQ_DRPIDX: u16 = 0x0011;    // DROP INDEX
//const SQ_GRANT: u16 = 0x0012; // GRANT
//const SQ_REVOKE: u16 = 0x0013;    // REVOKE

fn foo() {
    let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla. Lorem.
    // Id turpis. Nam posuere lectus vitae nibh. Etiam tortor orci, sagittis
    // malesuada, rhoncus quis, hendrerit eget, libero. Quisque commodo nulla at
    // nunc. Mauris consequat, enim vitae venenatis sollicitudin, dolor orci
    // bibendum enim, a sagittis nulla nunc quis elit. Phasellus augue. Nunc
    // suscipit, magna tincidunt lacinia faucibus, lacus tellus ornare purus, a
    // pulvinar lacus orci eget nibh.  Maecenas sed nibh non lacus tempor faucibus.
    // In hac habitasse platea dictumst. Vivamus a orci at nulla tristique
    // condimentum. Donec arcu quam, dictum accumsan, convallis accumsan, cursus sit
    // amet, ipsum.  In pharetra sagittis nunc.
    let b = baz();

    let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0]
    // TODO(emilio): It may make sense to make this range [.01, 10.0], to align
    // with css-fonts-4's range of [1, 1000].
}

Original V1 format

pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast
                                                 // Multicast using broadcst. add.

pub const SQ_CRETAB: u16 = 0x000e; // CREATE TABLE
pub const SQ_DRPTAB: u16 = 0x000f; // DROP TABLE
pub const SQ_CREIDX: u16 = 0x0010; // CREATE INDEX
                                   //const SQ_DRPIDX: u16 = 0x0011;    // DROP INDEX
                                   //const SQ_GRANT: u16 = 0x0012;     // GRANT
                                   //const SQ_REVOKE: u16 = 0x0013;    // REVOKE

fn foo() {
    let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla.
                   // Lorem. Id turpis. Nam posuere lectus vitae nibh. Etiam
                   // tortor orci, sagittis malesuada, rhoncus quis, hendrerit eget, libero.
                   // Quisque commodo nulla at nunc. Mauris consequat, enim vitae venenatis
                   // sollicitudin, dolor orci bibendum enim, a sagittis nulla nunc quis elit.
                   // Phasellus augue. Nunc suscipit, magna tincidunt lacinia faucibus, lacus
                   // tellus ornare purus, a pulvinar lacus orci eget nibh.  Maecenas sed nibh non
                   // lacus tempor faucibus. In hac habitasse platea dictumst. Vivamus a orci at
                   // nulla tristique condimentum. Donec arcu quam, dictum accumsan, convallis
                   // accumsan, cursus sit amet, ipsum.  In pharetra sagittis nunc.

    let b = baz();

    let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0]
                                                                   // TODO(emilio): It may make sense to make this range [.01, 10.0], to align
                                                                   // with css-fonts-4's range of [1, 1000].
}
ytmimi commented 2 years ago

Came up with a little script to help us find all the Version::One and Version::Two uses throughout the codebase:

regex="Version::One|Version::Two"
for file in $(rg "$regex" --files-with-matches src);
do
    echo "Version Usage in $file "
    git --no-pager blame -- $file | rg "$regex" -A 3 -B 3
    echo "
    "
done

Here's the output with some annotations and references to PRs where the version gates were added. Hoping that the links to PRs can help us get some context for the version gates (and maybe some examples):

Version Usage in src/visitor.rs

Version gate added in #3833

c0e616bc1 (Seiichi Uchida      2019-07-17 23:07:12 +0900  297)
c0e616bc1 (Seiichi Uchida      2019-07-17 23:07:12 +0900  298)                     let mut comment_shape =
c0e616bc1 (Seiichi Uchida      2019-07-17 23:07:12 +0900  299)                         Shape::indented(self.block_indent, config).comment(config);
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200  300)                     if self.config.version() == Version::Two && comment_on_same_line {
c0e616bc1 (Seiichi Uchida      2019-07-17 23:07:12 +0900  301)                         self.push_str(" ");
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200  302)                         // put the first line of the comment on the same line as the
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200  303)                         // block's last line

Version Usage in src/utils.rs

Version gate added in #3326

2d718a3fc (Stéphane Campinas          2018-10-30 01:09:09 +0100 589)
813aa7956 (Stéphane Campinas          2019-02-07 00:05:05 +0100 590)             // just InString{Commented} in order to allow the start of a string to be indented
813aa7956 (Stéphane Campinas          2019-02-07 00:05:05 +0100 591)             let new_veto_trim_value = (kind == FullCodeCharKind::InString
813aa7956 (Stéphane Campinas          2019-02-07 00:05:05 +0100 592)                 || (config.version() == Version::Two
813aa7956 (Stéphane Campinas          2019-02-07 00:05:05 +0100 593)                     && kind == FullCodeCharKind::InStringCommented))
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 594)                 && !line.ends_with('\\');
baa62c609 (Stéphane Campinas          2019-01-10 14:25:07 +0100 595)             let line = if veto_trim || new_veto_trim_value {

Version gate added in #3284

baa62c609 (Stéphane Campinas          2019-01-10 14:25:07 +0100 605)             // such lines should not be taken into account when computing the minimum.
2d718a3fc (Stéphane Campinas          2018-10-30 01:09:09 +0100 606)             match kind {
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 607)                 FullCodeCharKind::InStringCommented | FullCodeCharKind::EndStringCommented
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 608)                     if config.version() == Version::Two =>
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 609)                 {
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 610)                     None
083a20fb1 (Stéphane Campinas          2019-01-16 23:06:28 +0100 611)                 }

Version gate added in #5201

8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 649)         // formatting the code block, therefore the string's indentation needs
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 650)         // to be adjusted for the code surrounding the code block.
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 651)         config.format_strings() && line.ends_with('\\')
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 652)     } else if config.version() == Version::Two {
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 653)         !kind.is_commented_string()
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 654)     } else {
8211d64c7 (Caleb Cartwright           2022-03-29 23:17:30 -0500 655)         true

Version Usage in src/missed_spans.rs

Version gate added in #3833

efb68ee21 (Seiichi Uchida      2017-12-12 13:48:24 +0900 246)             let indent_str = self.block_indent.to_string(self.config);
efb68ee21 (Seiichi Uchida      2017-12-12 13:48:24 +0900 247)             self.push_str(&indent_str);
984ac100a (topecongiro         2017-12-22 12:00:24 +0900 248)             self.block_indent
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200 249)         } else if self.config.version() == Version::Two && !snippet.starts_with('\n') {
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200 250)             // The comment appears on the same line as the previous formatted code.
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200 251)             // Assuming that comment is logically associated with that code, we want to keep it on
fb01dc857 (Stéphane Campinas   2019-10-04 17:22:01 +0200 252)             // the same level and avoid mixing it with possible other comment.

Version Usage in src/expr.rs

Version gate added in #3556

ae9ce7bcd (Seiichi Uchida      2017-06-18 22:44:56 +0900 1206)             .lines()
ff0683d66 (Shotaro Yamada      2019-03-29 17:54:29 +0900 1207)             .dropping_back(1)
ae9ce7bcd (Seiichi Uchida      2017-06-18 22:44:56 +0900 1208)             .all(|line| line.ends_with('\\'))
69c7dbcd5 (Rui                 2019-10-19 17:19:47 +0800 1209)             && context.config.version() == Version::Two
ae9ce7bcd (Seiichi Uchida      2017-06-18 22:44:56 +0900 1210)         {
69c7dbcd5 (Rui                 2019-10-19 17:19:47 +0800 1211)             return Some(string_lit.to_owned());
ae9ce7bcd (Seiichi Uchida      2017-06-18 22:44:56 +0900 1212)         } else {

Version Usage in src/items.rs

Version gate added in #3856

0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  827)     result.push_str(format_defaultness(defaultness));
0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  828)     result.push_str(format_unsafety(unsafety));
a5d7073bf (dawirstejeck                   2016-09-06 07:11:56 +0200  829)
0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  830)     let shape = if context.config.version() == Version::Two {
0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  831)         Shape::indented(offset + last_line_width(&result), context.config)
0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  832)     } else {
0167c5303 (Caleb Cartwright               2021-12-02 21:35:30 -0600  833)         generics_shape_from_config(

Version gate added in #3731

582aa4f2f (Marcus Klaas                   2015-09-08 20:56:33 +0200 1946)         match *self {
7a76ec062 (Caleb Cartwright               2020-03-26 15:26:58 -0500 1947)             ast::FnRetTy::Default(_) => Some(String::new()),
7a76ec062 (Caleb Cartwright               2020-03-26 15:26:58 -0500 1948)             ast::FnRetTy::Ty(ref ty) => {
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 1949)                 if context.config.version() == Version::One
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 1950)                     || context.config.indent_style() == IndentStyle::Visual
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 1951)                 {
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 1952)                     let inner_width = shape.width.checked_sub(3)?;

Version gate(s) added in #3294

54233acc8 (topecongiro                    2017-06-17 16:56:54 +0900 2323)             .last()
d8357484a (Seiichi Uchida                 2018-09-11 13:31:37 +0900 2324)             .map_or(false, |last_line| last_line.contains("//"));
7b996542c (rchaser53                      2019-01-25 23:40:12 +0900 2325)
f92f3e3bd (rchaser53                      2019-01-27 14:33:03 +0900 2326)         if context.config.version() == Version::Two {
233497ace (rChaser53                      2019-10-24 22:16:56 +0900 2327)             if closing_paren_overflow_max_width {
233497ace (rChaser53                      2019-10-24 22:16:56 +0900 2328)                 result.push(')');
233497ace (rChaser53                      2019-10-24 22:16:56 +0900 2329)                 result.push_str(&indent.to_string_with_newline(context.config));

Version gate(s) added in #3731

4edc6f1a4 (Erik Johnston                  2016-04-07 20:01:16 +0100 2366)             }
4edc6f1a4 (Erik Johnston                  2016-04-07 20:01:16 +0100 2367)         };
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2368)         let ret_shape = if ret_should_indent {
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2369)             if context.config.version() == Version::One
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2370)                 || context.config.indent_style() == IndentStyle::Visual
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2371)             {
9c2b375ba (Caleb Cartwright               2019-09-23 19:25:19 -0500 2372)                 let indent = if param_str.is_empty() {

Version gate(s) added (#3731) / updated (#3803 some renaming)

1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2399)                 ret_shape
1643d726e (Seiichi Uchida                 2019-08-16 11:15:28 +0900 2400)             }
1b0ae0048 (Marcus Klaas                   2015-11-22 13:45:51 +0100 2401)         } else {
f92f3e3bd (rchaser53                      2019-01-27 14:33:03 +0900 2402)             if context.config.version() == Version::Two {
9c2b375ba (Caleb Cartwright               2019-09-23 19:25:19 -0500 2403)                 if !param_str.is_empty() || !no_params_and_over_max_width {
f92f3e3bd (rchaser53                      2019-01-27 14:33:03 +0900 2404)                     result.push(' ');
f92f3e3bd (rchaser53                      2019-01-27 14:33:03 +0900 2405)                 }

Version Usage in src/chains.rs

Version gate(s) added #4503 commit 63f172d995e4419575907e84a9bd529d200d7b6c

08e282877 (Seiichi Uchida      2018-09-01 16:18:27 +0900 254)             ChainItemKind::StructField(ident) => format!(".{}", rewrite_ident(context, ident)),
08e282877 (Seiichi Uchida      2018-09-01 16:18:27 +0900 255)             ChainItemKind::TupleField(ident, nested) => format!(
08e282877 (Seiichi Uchida      2018-09-01 16:18:27 +0900 256)                 "{}.{}",
15854e5fd (Caleb Cartwright    2020-10-30 00:03:03 -0500 257)                 if nested && context.config.version() == Version::One {
15854e5fd (Caleb Cartwright    2020-10-30 00:03:03 -0500 258)                     " "
15854e5fd (Caleb Cartwright    2020-10-30 00:03:03 -0500 259)                 } else {
15854e5fd (Caleb Cartwright    2020-10-30 00:03:03 -0500 260)                     ""

Version Usage in src/matches.rs

Version gate added (#3250) / updated (#3756)

b73a602d6 (Stéphane Campinas   2018-12-14 09:48:20 +0100 425)                 } else {
b73a602d6 (Stéphane Campinas   2018-12-14 09:48:20 +0100 426)                     ""
deb329a6b (Seiichi Uchida      2019-08-28 20:50:41 +0900 427)                 };
deb329a6b (Seiichi Uchida      2019-08-28 20:50:41 +0900 428)                 let semicolon = if context.config.version() == Version::One {
deb329a6b (Seiichi Uchida      2019-08-28 20:50:41 +0900 429)                     ""
deb329a6b (Seiichi Uchida      2019-08-28 20:50:41 +0900 430)                 } else {
deb329a6b (Seiichi Uchida      2019-08-28 20:50:41 +0900 431)                     if semicolon_for_expr(context, body) {

Version Usage in src/patterns.rs

Version gate added in #4994

fe05e8883 (rChaser53            2019-07-30 14:32:38 +0900 233)                 rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
ca023ba9b (Marcus Klaas         2015-10-17 15:56:53 +0200 234)             }
428339fdc (Nick Cameron         2017-01-31 08:28:48 +1300 235)             PatKind::Lit(ref expr) => expr.rewrite(context, shape),
f0f449d6e (Patrick Walton       2021-09-17 18:56:30 -0700 236)             PatKind::Slice(ref slice_pat) if context.config.version() == Version::One => {
fe05e8883 (rChaser53            2019-07-30 14:32:38 +0900 237)                 let rw: Vec<String> = slice_pat
fe05e8883 (rChaser53            2019-07-30 14:32:38 +0900 238)                     .iter()
fe05e8883 (rChaser53            2019-07-30 14:32:38 +0900 239)                     .map(|p| {

Version Usage in src/stmt.rs

Version gate added in #3631

1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  75)
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  76) impl<'a> Rewrite for Stmt<'a> {
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  77)     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  78)         let expr_type = if context.config.version() == Version::Two && self.is_last_expr() {
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  79)             ExprType::SubExpression
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  80)         } else {
1d19a08ed (Seiichi Uchida   2019-06-17 08:53:39 +0900  81)             ExprType::Statement

Version Usage in src/overflow.rs

Version gates both added in #3298

181ca427d (topecongiro         2019-01-27 21:01:12 +0900 469)                 Some(OverflowableItem::MacroArg(MacroArg::Expr(expr)))
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 470)                     if !combine_arg_with_callee
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 471)                         && is_method_call(expr)
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 472)                         && self.context.config.version() == Version::Two =>
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 473)                 {
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 474)                     self.context.force_one_line_chain.replace(true);
181ca427d (topecongiro         2019-01-27 21:01:12 +0900 475)                 }
--
ae629abc4 (Seiichi Uchida      2018-03-07 15:40:52 +0900 659)         );
ae629abc4 (Seiichi Uchida      2018-03-07 15:40:52 +0900 660)         result.push_str(self.ident);
98c6f7b73 (Seiichi Uchida      2018-03-26 07:36:44 +0900 661)         result.push_str(prefix);
5df0a1884 (topecongiro         2019-01-27 20:50:16 +0900 662)         let force_single_line = if self.context.config.version() == Version::Two {
5df0a1884 (topecongiro         2019-01-27 20:50:16 +0900 663)             !self.context.use_block_indent() || (is_extendable && extend_width <= shape.width)
5df0a1884 (topecongiro         2019-01-27 20:50:16 +0900 664)         } else {
5df0a1884 (topecongiro         2019-01-27 20:50:16 +0900 665)             // 2 = `()`

Version Usage in src/types.rs

Version gates both added in #3731

01937061a (Marcus Klaas        2015-10-17 14:19:55 +0200  761)             // FIXME: we drop any comments here, even though it's a silly place to put
01937061a (Marcus Klaas        2015-10-17 14:19:55 +0200  762)             // comments.
589dabda2 (Kamal Marhubi       2016-03-01 17:27:19 -0500  763)             ast::TyKind::Paren(ref ty) => {
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  764)                 if context.config.version() == Version::One
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  765)                     || context.config.indent_style() == IndentStyle::Visual
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  766)                 {
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  767)                     let budget = shape.width.checked_sub(2)?;
--
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  828)                 if it.is_empty() {
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  829)                     return Some("impl".to_owned());
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  830)                 }
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  831)                 let rw = if context.config.version() == Version::One {
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  832)                     it.rewrite(context, shape)
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  833)                 } else {
1643d726e (Seiichi Uchida      2019-08-16 11:15:28 +0900  834)                     join_bounds(context, shape, it, false)

Version Usage in src/closures.rs

Version gate added in #3334

7d9a2ef96 (rchaser53           2019-02-08 21:39:11 +0900 416) fn is_block_closure_forced_inner(expr: &ast::Expr, version: Version) -> bool {
383306e5f (Seiichi Uchida      2019-10-05 23:40:24 +0900 417)     match expr.kind {
983a92c87 (Seiichi Uchida      2019-07-29 05:52:45 +0900 418)         ast::ExprKind::If(..) | ast::ExprKind::While(..) | ast::ExprKind::ForLoop(..) => true,
7d9a2ef96 (rchaser53           2019-02-08 21:39:11 +0900 419)         ast::ExprKind::Loop(..) if version == Version::Two => true,
c60416ed2 (Caleb Cartwright    2020-02-08 22:21:37 -0600 420)         ast::ExprKind::AddrOf(_, _, ref expr)
34c249902 (topecongiro         2017-11-16 16:42:07 +0900 421)         | ast::ExprKind::Box(ref expr)
34c249902 (topecongiro         2017-11-16 16:42:07 +0900 422)         | ast::ExprKind::Try(ref expr)

Version Usage in src/imports.rs

Version gates added in backport PR #5384

795efb206 (Yacin Tmimi         2022-06-13 10:53:53 -0400  890)             | (Super(ref a), Super(ref b))
795efb206 (Yacin Tmimi         2022-06-13 10:53:53 -0400  891)             | (Crate(ref a), Crate(ref b)) => match (a, b) {
5ae94cc6b (Yacin Tmimi         2022-06-13 08:34:47 -0400  892)                 (Some(sa), Some(sb)) => {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  893)                     if self.version == Version::Two {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  894)                         sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#"))
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  895)                     } else {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  896)                         a.cmp(b)
--
5ae94cc6b (Yacin Tmimi         2022-06-13 08:34:47 -0400  900)             },
795efb206 (Yacin Tmimi         2022-06-13 10:53:53 -0400  901)             (Glob, Glob) => Ordering::Equal,
795efb206 (Yacin Tmimi         2022-06-13 10:53:53 -0400  902)             (Ident(ref pia, ref aa), Ident(ref pib, ref ab)) => {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  903)                 let (ia, ib) = if self.version == Version::Two {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  904)                     (pia.trim_start_matches("r#"), pib.trim_start_matches("r#"))
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  905)                 } else {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  906)                     (pia.as_str(), pib.as_str())
--
5ae94cc6b (Yacin Tmimi         2022-06-13 08:34:47 -0400  926)                     (None, Some(_)) => Ordering::Less,
5ae94cc6b (Yacin Tmimi         2022-06-13 08:34:47 -0400  927)                     (Some(_), None) => Ordering::Greater,
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  928)                     (Some(aas), Some(abs)) => {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  929)                         if self.version == Version::Two {
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  930)                             aas.trim_start_matches("r#")
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  931)                                 .cmp(abs.trim_start_matches("r#"))
e44380b34 (Yacin Tmimi         2022-06-13 11:36:20 -0400  932)                         } else {
--
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1246)
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1247)         let mut parser = Parser {
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1248)             input: s.chars().peekable(),
795efb206 (Yacin Tmimi         2022-06-13 10:53:53 -0400 1249)             version: Version::One,
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1250)         };
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1251)         parser.parse_in_list()
01311c63e (Seiichi Uchida      2018-03-31 13:21:13 +0900 1252)     }
ytmimi commented 2 years ago

Table of what I found above. Might be useful to track which examples we've already added.

Version Usage in src/visitor.rs

Version Usage in src/utils.rs

Version Usage in src/missed_spans.rs

Version Usage in src/expr.rs

Version Usage in src/items.rs

Version Usage in src/chains.rs

Version Usage in src/matches.rs

Version Usage in src/patterns.rs

Version Usage in src/stmt.rs

Version Usage in src/overflow.rs

Version Usage in src/types.rs

Version Usage in src/closures.rs

Version Usage in src/imports.rs

ytmimi commented 2 years ago

Imports with raw identifiers reorder_imports=true (default)

Reference in codebase: impl Ord for UseSegment

V2

use websocket::r#async::futures::Stream;
use websocket::client::ClientBuilder;
use websocket::result::WebSocketError;

V1

use websocket::client::ClientBuilder;
use websocket::r#async::futures::Stream;
use websocket::result::WebSocketError;

Back to table

ytmimi commented 2 years ago

Force block closures for closures with a single loop body.

Reference in codebase: closures::is_block_closure_forced_inner

V2

loops are written with a block closures.

fn main() {
    thread::spawn(|| {
        loop {
            println!("iteration");
        }
    });
}

V1

loops are not forced to be written in a block closures.

fn main() {
    thread::spawn(|| loop {
        println!("iteration");
    });
}

Back to table

ytmimi commented 2 years ago

Use correct indent when formatting complex fn type

Reference in codebase:

V2

fn build_sorted_static_get_entry_names(
    mut entries: Vec<(u8, &'static str)>,
) -> (
    impl Fn(
        AlphabeticalTraversal,
        Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
    ) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
    + Send
    + Sync
    + 'static
) {
}

V1

fn build_sorted_static_get_entry_names(
    mut entries: Vec<(u8, &'static str)>,
) -> (impl Fn(
    AlphabeticalTraversal,
    Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
        + Send
        + Sync
        + 'static) {
}

There was some version gates that were also associated with indent_style=Visual that were added in #3731 so I thought it might be worth adding the version config in combination with indent_style=Visual.

V2 (indent_style=Visual)

fn build_sorted_static_get_entry_names(
    mut entries: Vec<(u8, &'static str)>)
    -> (impl Fn(AlphabeticalTraversal,
           Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>)
           -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
        + Send
        + Sync
        + 'static) {
}

V1 (indent_style=Visual)

fn build_sorted_static_get_entry_names(
    mut entries: Vec<(u8, &'static str)>)
    -> (impl Fn(AlphabeticalTraversal,
               Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>)
               -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
            + Send
            + Sync
            + 'static) {
}

Back to table

ytmimi commented 2 years ago

Consistency between function and macro when overflowing method calls

Reference in codebase: overflow::Context::try_overflow_last_item

V2

fn main() {
    assert!(
        HAYSTACK
            .par_iter()
            .find_any(|&&x| x[0] % 1000 == 999)
            .is_some()
    );

    assert(
        HAYSTACK
            .par_iter()
            .find_any(|&&x| x[0] % 1000 == 999)
            .is_some(),
    );
}

V1

fn main() {
    assert!(HAYSTACK
        .par_iter()
        .find_any(|&&x| x[0] % 1000 == 999)
        .is_some());

    assert(
        HAYSTACK
            .par_iter()
            .find_any(|&&x| x[0] % 1000 == 999)
            .is_some(),
    );
}

Back to table

ytmimi commented 2 years ago

Consistency between function and macro when deciding to overflow items or keep them on the same line

Reference in codebase: overflow::Context::rewrite_items

V2

Overflow rules don't take macro context into account.

macro_rules! bar {
    ($m:ident) => {
        $m!([
            a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,
        ]);
        $m!([
            a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
        ]);
    };
}

V1

Overflow rules do take macro context into account.

macro_rules! bar {
    ($m:ident) => {
        $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,]);
        $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]);
    };
}

Back to table

ytmimi commented 2 years ago

Wrap long arrays and slice patterns

Reference in codebase: impl Rewrite for Pat (PatKind::Slice) Added in PR: https://github.com/rust-lang/rustfmt/pull/4994

V2

fn main() {
    let [
        aaaaaaaaaaaaaaaaaaaaaaaaaa,
        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
        cccccccccccccccccccccccccc,
        ddddddddddddddddddddddddd,
    ] = panic!();
}

V1

fn main() {
    let [aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccc, ddddddddddddddddddddddddd] =
        panic!();
}

Back to table

ytmimi commented 2 years ago

Nested tuples access without spaces

Reference in codebase: impl Rewrite for ChainItem (ChainItemKind::TupleField)

V2

No spaces added

fn main() {
    let _ = ((1,),).0.0;
}

V1

A space is added for the nested item access.

fn main() {
    let _ = ((1,),).0 .0;
}

Back to table

ytmimi commented 2 years ago

Don't Change multi-line string literal indentation inside macro

Reference in codebase:

V2

macro_rules! moo {
    () => {
        bar! {
"
"
        }
    };
}

V1

macro_rules! moo {
    () => {
        bar! {
        "
"
        }
    };
}

Back to table

ytmimi commented 2 years ago

Don't indent strings within comments

Reference in codebase:

V2

pub fn main() {
    /*   let s = String::from(
        "
hello
world
",
    ); */

    assert_eq!(s, "\nhello\nworld\n");
}

V1

pub fn main() {
    /*   let s = String::from(
            "
    hello
    world
    ",
        ); */

    assert_eq!(s, "\nhello\nworld\n");
}

Back to table

ytmimi commented 2 years ago

Don't wrap string literals in Option with wrap_str when each line ends with line continuation (\\) and format_string=false and Version=Two.

This version gate only seems to work in some contexts where a string literal is a subexpression of another expression.

Reference in codebase: expr::rewrite_string_lit, which is only called in rewrite_literal. Then rewirte_literal is only called when rewriting ast::NestedMetaItem::Literal and ast::MetaItemKind::NameValue as well as when rewriting ast::ExprKind::Lit

Input:

// long string literal in attribute is formatted the same for `Version::One` and `Version::Two`.
#![attr(something = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")]

fn main() {
// long string literal in chains prevent formatting and are formatted the same for `Version::One` and `Version::Two`.
something.something(|| {
// ...
}).unwrap_or_else(|| "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor innderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
}

// long string literal in conditionals will prevent formatting for `Version::One`.
fn main() {
    let value = if x == "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." { 0 } else {10};
value
}

V2

// long string literal in attribute is formatted the same for `Version::One` and `Version::Two`.
#![attr(
    something = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)]

fn main() {
    // long string literal in chains prevent formatting and are formatted the same for `Version::One` and `Version::Two`.
    something.something(|| {
// ...
}).unwrap_or_else(|| "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
}

// long string literal in conditionals will prevent formatting for `Version::One`.
fn main() {
    let value = if x
        == "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    {
        0
    } else {
        10
    };
    value
}

V1

// long string literal in attribute is formatted the same for `Version::One` and `Version::Two`.
#![attr(
    something = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)]

fn main() {
    // long string literal in chains prevent formatting and are formatted the same for `Version::One` and `Version::Two`.
    something.something(|| {
// ...
}).unwrap_or_else(|| "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor innderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
}

// long string literal in conditionals will prevent formatting for `Version::One`.
fn main() {
    let value = if x == "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." { 0 } else {10};
    value
}

Back to table

ytmimi commented 1 year ago

[!NOTE] https://github.com/rust-lang/rustfmt/pull/6362 pushes those changes to style_edition=2027. They're now documented here: https://github.com/rust-lang/rustfmt/issues/6371#issuecomment-2427434682

Break function return types before -> instead of breaking between () for zero argument functions

Reference in codebase: items::rewrite_fn_base

V2

pub fn parse_conditional<'a, I: 'a>()
-> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
where
    I: Stream<Item = char>,
{
}

V1

pub fn parse_conditional<'a, I: 'a>(
) -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
where
    I: Stream<Item = char>,
{
}

Back to table

ytmimi commented 1 year ago

Trailing semicolon for return statements inside a match arm

Reference in codebase: matches::rewrite_match_body

V2

match arm 0 Includes a trailing semicolon.

fn foo() {
    match 0 {
        0 => {
            return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
        }
        1 => {
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        }
        _ => "",
    };
}

V1

match arm 0 does not includes a trailing semicolon.

fn foo() {
    match 0 {
        0 => {
            return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        }
        1 => {
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        }
        _ => "",
    };
}

Back to table

ytmimi commented 1 year ago

Format the last expression-statement as expression

Reference in codebase: impl<'a> Rewrite for Stmt<'a>

V2

fn main() {
    let toto = || {
        if true { 42 } else { 24 }
    };
    { T }
}

V1

fn main() {
    let toto = || {
        if true {
            42
        } else {
            24
        }
    };

    {
        T
    }
}

Back to table

calebcartwright commented 1 year ago

Proper indention of single generic bound with multiline formatting

Reference in codebase: types::join_bounds_inner

V2

pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    >
{
    //
}
pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    > + fmt::Write
{
    //
}

V1

pub trait PrettyPrinter<'tcx>:
    Printer<
    'tcx,
    Error = fmt::Error,
    Path = Self,
    Region = Self,
    Type = Self,
    DynExistential = Self,
    Const = Self,
>
{
    //
}
pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    > + fmt::Write
{
    //
}

Back to table

ytmimi commented 1 year ago

TODO: Document https://github.com/rust-lang/rustfmt/pull/5867

ytmimi commented 1 year ago

TODO: Document #5902

calebcartwright commented 1 year ago

TODO: Ensure #4800 is covered somewhere in a human-readable manner

ytmimi commented 11 months ago

Consistent handling of macros from the log crate.

Reference in codebase: overflow::OverflowableItem::special_cases

Added in PR #5989

V2

All of the macros are formatted consistently.

fn main() {
    trace!(
        "get some longer length in here yes yes {} {}",
        "hello", "world"
    );
    debug!(
        "get some longer length in here yes yes {} {}",
        "hello", "world"
    );
}

V1

The trace! macro is not special cased.

fn main() {
    trace!(
        "get some longer length in here yes yes {} {}",
        "hello",
        "world"
    );
    debug!(
        "get some longer length in here yes yes {} {}",
        "hello", "world"
    );
}

Back to table

ytmimi commented 11 months ago

TODO: Document https://github.com/rust-lang/rustfmt/pull/6000

ytmimi commented 10 months ago

TODO: Document https://github.com/rust-lang/rustfmt/pull/5582

ytmimi commented 8 months ago

TODO: Document #6092

ytmimi commented 7 months ago

TODO: Document #6147 / #6148

calebcartwright commented 7 months ago

Note to future selves that https://github.com/rust-lang/rustfmt/issues/5577#issuecomment-1345037570 is the one the style team decided we didn't want to keep for 2024 style edition

Edit(ytmimi): https://github.com/rust-lang/rustfmt/pull/6362 pushes those changes to style_edition=2027.

ytmimi commented 3 months ago

TODO: Document #6284 (version sort for imports)