Ticket #669 (closed bug: invalid)
negative indentation in Text.PrettyPrint.HughesPJ
| Reported by: | waldmann@… | Owned by: | thorkilnaur |
|---|---|---|---|
| Priority: | normal | Milestone: | 6.10 branch |
| Component: | libraries/pretty | Version: | 6.4.1 |
| Keywords: | Cc: | ||
| Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
| Type of failure: | Difficulty: | Unknown | |
| Test Case: | pp1 | Blocked By: | |
| Blocking: | Related Tickets: |
Description
The pretty printing library has a long-standing bug: it sometimes creates negative indentation. Currently, the symptom is cured, but the cause is unknown.
I tried to dig a bit into the code, and here's what I found.
short summary: the law
(n6) x <> nest k y = x <> y, if x non-empty
seems broken by the implementation.
test case:
this seems OK:
*Main> text "foo" <> nest 20 ( nest 20 ( text "foo" ) $$ text "bar" )
Beside (TextBeside (Str "foo") 3 Empty) False
(Nest 40
(TextBeside (Str "foo") 3
(NilAbove (Nest -23 (TextBeside (Str "bar") 3 Empty)))))
but thes seems wrong (the Nest 40 is gone but the Nest -23 is kept, this will lead to negative indentation later on)
*Main> reduceDoc $ text "foo" <> nest 20 ( nest 20 ( text "foo" ) $$ text "bar" )
TextBeside (Str "foo") 3
(TextBeside (Str "foo") 3
(NilAbove (Nest -23 (TextBeside (Str "bar") 3 Empty))))
Now the formatter thinks that he has to indent by 3 + 3 - 23 = -17 spaces.
In the source, I found these problematic lines:
618:nilBeside g (Nest _ p) = nilBeside g p 657:sepNB g (Nest _ p) k ys = sepNB g p k ys 700:fillNB g (Nest _ p) k ys = fillNB g p k ys 862: lay2 k (Nest _ p) = lay2 k p
I think that no function (that produces a document) is allowed to ignore the nesting level because this adds to the total (relative) indentation that must be kept in a consistent state.
At least that's my guess that these numbers represent relative indentation - the source is not exactly verbose on the meaning of all these numbers (which are not in the original paper by John Hughes).

