Input (reduced via creduce, so no longer valid Rust code, but it was at one point in time):
impl a {
fn b() {
{
{
self.filter(|base| {
ctx.resolve_type(base.ty).has_vtable(ctx)
})
.c > e = d
}
}
}
}
With this rustfmt.toml:
max_width = 80
format_strings = false
fn_brace_style = "SameLineWhere"
item_brace_style = "SameLineWhere"
struct_lit_multiline_style = "ForceMulti"
where_trailing_comma = true
reorder_imports = true
reorder_imported_names = true
normalize_comments = false
write_mode = "Overwrite"
Steps to reproduce:
$ cargo new tempcrate
$ cp $TESTCASE tempcrate/src/lib.rs
$ cp $RUSTFMT_TOML tempcrate/rustfmt.toml
$ cd tempcrate
$ git add .
$ git commit -m "Initial commit"
$ cargo fmt
$ git commit -am "Running cargo fmt once reformatted"
$ cargo fmt
$ git commit -am "Running cargo fmt a second time ALSO reformatted"
$ git diff HEAD^^ # No diff! Reformatted back to the initial commit! Infinite loop, no fixpoint of formatting
cc @nrc
Let me try and re-reduce while keeping the reduced file valid Rust
Here is a valid Rust file that exhibits the same behavior:
struct Base {
ty: Ty
}
#[derive(Copy, Clone)]
struct Ty;
impl Ty {
fn has_vtable(&self, ctx: &CodeGenContext) -> bool {
unimplemented!()
}
}
struct BaseMembers;
impl BaseMembers {
fn base_members(&self) -> Vec<Base> {
unimplemented!()
}
}
struct CodeGenContext;
impl CodeGenContext {
fn resolve_type(&self, t: Ty) -> Ty {
t
}
}
trait CodeGenerator {
fn codegen(&self, ctx: &CodeGenContext);
}
impl CodeGenerator for BaseMembers {
fn codegen(&self, ctx: &CodeGenContext) {
if false {
if false {
let some_variable = self.base_members()
.iter()
.filter(|base| {
ctx.resolve_type(base.ty).has_vtable(ctx)
})
.count() > 1;
}
}
}
}
Also, it seems like it would be a good idea for the extant tests (or test runner) to try reformatting again after formatting the initial time, and assert that there is no diff.
@fitzgen Also seems like a cool (potential) use of a fuzzer (cc @frewsxcv @Manishearth @nagisa).
@eddyb this is actually derived from rust-bindgen, not generated by a fuzzer. I figured a multiple thousands of lines test case wouldn't be appreciated, hence creduce to take the large test case and make it into a smaller test case :)
(potential)
Ah ok -- yes, it would be great to start fuzzing rustfmt :)
At least some part of the config seems necessary, I can't repro with the default settings.
I suspect it is a combination of the column width and maybe some of the others. I did not creduce the rustfmt.toml :-P
This should be fixed by https://github.com/rust-lang-nursery/rustfmt/commit/c7a33062e25e1d80545ae6094d3faa99348c79e1Please re-open if not.
Most helpful comment
Also, it seems like it would be a good idea for the extant tests (or test runner) to try reformatting again after formatting the initial time, and assert that there is no diff.