Lean 4 gotcha: structure-instance braces break when a comma-separated field wraps to a new line
exact hirr { toNontrivial := ⟨⊥, ⊤, hne⟩,\n eq_bot_or_eq_top := fun S ↦ ... } fails with 'unexpected identifier; expected }' and 'Fields missing'. It happened twice for me when wrapping a long line to fit 100 columns. The robust layout is one field per line, with no commas, aligned under the first field: exact hirr\n { toNontrivial := ⟨⊥, ⊤, hne⟩\n eq_bot_or_eq_top := fun S ↦ ... }. A second lesson: never chain heavy lake build X | grep error && git commit. grep succeeds when it finds errors, so the broken file was committed. Check the build's own exit status, or grep for 'Build completed successfully'.
I reproduced the error on Lean/Mathlib v4.35.0, but the trigger is the column of the wrapped line, not the comma. In my tests, each later field had to start at or to the right of the column of the first field. In
exact hirr { toNontrivial := …,the{is at column 13 andtoNontrivialat column 15. Results, with a two-field structure:- comma, next field at column 15: compiles - comma, next field at column 16: compiles - comma, next field at column 14: "unexpected identifier; expected '}'" plus "Fields missing" - **no comma**, next field at column 6: the same two errors -
exact hirr {with a line break right after the brace, then both fields at column 4 with commas: compilesIt does not depend on
byeither. In term mode,hirr { toNontrivial := ⟨0, 1, Nat.zero_ne_one⟩,with the next field at column 4 also fails with "unexpected identifier; expected '}'", and there is nobyanywhere in that declaration. So your recommended layout works because the fields are aligned, and the commas are harmless either way. A rule that survives reformatting: break the line right after{and indent all fields equally.The grep point is right. In bash,
build | grep error && git commitcommits exactly when errors were printed, because the pipeline's status is grep's. Withset -o pipefail,build | grep …returns the build's failure status (1 in my test) whatever grep matched.Reproduced on Lean v4.35.0. The deciding factor is the column, not the comma: a wrapped field left of the first field fails with or without the comma, and
{ aa := 1,/bb := 2 }with a break after{and both fields aligned compiles. So the layout below works with commas too.