Format.group does not flatten a group containing align (force := true) that fits the width
Nobody has claimed this yet.
- Dominant language
- Lean
- Stars
- 9.2k
- Forks
- 990
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 175
Description
Prerequisites
- Check that your issue is not already filed.
- Reduce the issue to a minimal, self-contained, reproducible test case.
- Test your test case against the latest nightly release.
Description
Format.group renders its contents on one line when they fit the target width. When the group contains Format.align (force := true), it is not flattened until the width is about twice what the flattened rendering needs.
Steps to Reproduce
open Std (Format)
def doc : Format :=
Format.group (Format.text "head" ++ Format.line ++ Format.text "where" ++
Format.nest 2 (Format.align (force := true) ++ Format.text "field"))
#eval IO.println (repr (Format.pretty doc 22))
#eval IO.println (repr (Format.pretty doc 23))
Expected behavior: doc renders as head where followed by field. That is 10 columns wide, so both #evals print "head where\n field".
Actual behavior:
"head\nwhere\n field"
"head where\n field"
At width 22 the line before where is broken, although not breaking it would have used 10 columns. The break happens at every width from 10 to 22.
Context
sepByIndent emits align (force := true) before its first item, so this reaches the pretty printer. A declaration whose body is where fields has where moved onto its own line at widths much larger than the line needs:
import Lean
open Lean Parser PrettyPrinter
#eval show CoreM Unit from do
let env ← getEnv
let src := "def foo (a : Nat) : Packet where\n first := a\n second := a"
let .ok stx := runParserCategory env `command src | IO.println "parse error"
let fmt ← ppCommand ⟨stx⟩
for w in [70, 71] do
IO.println s!"width {w}:"
IO.println (Format.pretty fmt w)
def foo (a : Nat) : Packet where is 32 columns. At width 71 it is printed as written; at width 70 and below it is printed as
def foo (a : Nat) : Packet
where
first := a
second := a
The width needed grows with the text in front of the align. Measured with the same snippet:
| first line | kept on one line only from width |
|---|---|
| 17 columns | 37 |
| 32 columns | 71 |
| 71 columns | 149 |
Versions
4.34.0-nightly-2026-08-05
macOS 26.5.1
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 by running the minimal Format.group reproduction at widths 22 and 23, then inspect the pretty-printer handling for Format.group, Format.align (force := true), and sepByIndent. Compare the behavior with the expected flattened rendering and the declaration example; done means both reproductions retain the preceding text on one line whenever the flattened output fits.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100