rust-lang/rustfmt

Enhance formatting for ConstBlock expressions

Open

#4483 opened on Oct 20, 2020

View on GitHub
 (7 comments) (0 reactions) (0 assignees)Rust (4,893 stars) (760 forks)batch import
1x-backport:pendingE-help-wantedgood first issue

Description

#4478 included some initial support for the new ConstBlock expression kind variant, but there's opportunities to enhance and improve the formatting.

The relevant section of the codebase can be found in formatting/expr.rs https://github.com/rust-lang/rustfmt/blob/cbe01e47024c852e2ed852671e76f7929c4bab91/src/formatting/expr.rs#L127-L129

There are 3 core activities to completing this issue:

  1. Honor the brace_style configuration option
  2. Account for any comments between the const keyword and the block
  3. Add test cases

1. brace_style

This should be relatively easy. When brace_style is set to AlwaysNextLine (can be checked with context.config.brace_style()) then we'll want to insert a newline and start the block on the next line (the correct newline and indentation can be achieved via shape.to_string_with_newline(context.config)), otherwise there should just be a space between the keyword and block

2. comments

First step will be to determine the span between the end of the const keyword and the start of the block. Consider using context.snippet.span_after to figure out the lo for this "between" span, and for the hi you will want to use the lo of the block (anon_const.value.span.lo())

Once you have that span there are a few different options and comment utility functions for formatting the expression and ensuring comments are properly formatted. You may want to take a look at one or more of them:

  • contains_comment
  • combine_strs_with_missing_comments
  • rewrite_missing_comment
  • recover_missing_comment_in_span

3. tests

Below are a few (nonexhaustive) set of tests to cover some top of mind scenarios.

You will probably want to add a const_block_always_next_line.rs file under the configs/brace_style directory (https://github.com/rust-lang/rustfmt/tree/master/tests/source/configs/brace_style) for both tests/source and tests/target

fn foo() -> i32 {
    const {
        let x = 5 + 10;
        x / 3
    }
}

fn bar() -> i32 {
    const { 4 }
}

fn foo() -> i32 {
    const
{
        let x = 5 + 10;
        x / 3
    }
}

fn foo() -> i32 {
    const // baz
{
        let x = 5 + 10;
        x / 3
    }
}

fn foo() -> i32 {
    const /*qux */ {
        let x = 5 + 10;
        x / 3
    }
}

fn foo() -> i32 {
    const
// baz
{
        let x = 5 + 10;
        x / 3
    }
}

Contributor guide