`rustfmt` inconsistently formats blank lines in the beginning of blocks
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 1.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 24
Description
Description
The current implementation exhibits inconsistent behavior for blank lines in the beginning of blocks depending on the type of the block.
The formatter removes all blank lines in the beginning of enum, union, struct, impl and trait.
However, blank lines in fns are trimmed and inserted to match the number of blank lines to blank_lines_lower_bound.
In mod and extern, blank lines are clamped according to blank_lines_lower_bound and blank_lines_upper_bound.
This mismatch appears very strange with custom blank_lines_*_bound values, but even with default values it seems weird.
From the document on blank_lines_lower_bound in Configurations.md, the number of blank lines should be decided according to the blank_lines_*_bound options.
This matches to the current behavior for mod and extern.
On the other hand, some discussions in #2954 and #3382 concluded those options should not affect on it.
This matches to the current behavior for enum, union, struct, impl and trait.
#4295 tried to fix the v2 code, but it is not yet back-ported and still has some bugs like one reported in #5067.
Environment
version: rustfmt 1.4.38-nightly (3e38399e 2022-05-26)
Sample
Source
enum Enum {
Variant(i64),
}
union Union {
value: i64,
}
struct Struct {
value: i64,
}
impl Struct {
fn struct_func() {}
}
trait Trait {
fn trait_func();
}
fn toplevel_func() {
println!("");
}
mod Mod {
fn mod_func() {}
}
extern "C" {
fn extern_func();
}
Expected
enum Enum {
Variant(i64),
}
union Union {
value: i64,
}
struct Struct {
value: i64,
}
impl Struct {
fn struct_func() {}
}
trait Trait {
fn trait_func();
}
fn toplevel_func() {
println!("");
}
mod Mod {
fn mod_func() {}
}
extern "C" {
fn extern_func();
}
Actual
enum Enum {
Variant(i64),
}
union Union {
value: i64,
}
struct Struct {
value: i64,
}
impl Struct {
fn struct_func() {}
}
trait Trait {
fn trait_func();
}
fn toplevel_func() {
println!("");
}
mod Mod {
fn mod_func() {}
}
extern "C" {
fn extern_func();
}
Actual (with blank_lines_lower_bound=1,blank_lines_upper_bound=2)
enum Enum {
Variant(i64),
}
union Union {
value: i64,
}
struct Struct {
value: i64,
}
impl Struct {
fn struct_func() {}
}
trait Trait {
fn trait_func();
}
fn toplevel_func() {
println!("");
}
mod Mod {
fn mod_func() {}
}
extern "C" {
fn extern_func();
}
The extern block has an extra blank line in the end of the block, but this is a separate issue?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the sample and Configurations.md, then trace how rustfmt handles leading blank lines in enum, union, struct, impl, trait, fn, mod, and extern blocks. The discussions in #2954 and #3382, along with #4295 and #5067, are needed to determine the intended behavior before defining completion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100