Skip to content

Enhance formatting for ConstBlock expressions #4483

Open
@calebcartwright

Description

@calebcartwright

#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

ast::ExprKind::ConstBlock(ref anon_const) => {
Some(format!("const {}", anon_const.rewrite(context, shape)?))
}

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
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    1x-backport:pendingFixed/resolved in source but not yet backported to a 1x branch and releasegood first issueIssues up for grabs, also good candidates for new rustfmt contributorshelp wanted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions