tweag / ormolu

A formatter for Haskell source code
https://ormolu-live.tweag.io
Other
953 stars 83 forks source link

Top level multi-line tuples/lists are formatted to unparseable code #778

Open amesgen opened 3 years ago

amesgen commented 3 years ago

Describe the bug The snippet

(a
 ,b)

[a
 ,b]

is formatted (with --unsafe) to

( a,
  b
)

[ a,
  b
]

which can not be parsed. The closing parens/brackets can't be in the first column.

Environment Ormolu 0.2.0.0

mrkkrp commented 3 years ago

But what a top-level tuple or a list mean?

amesgen commented 3 years ago
  1. People could write very weird TH.Lift instances. :grin:
  2. A bit less contrived: Consider
    test =
      (1
       ,2)

    which one might try to format via ormolu --start-line 2 (which will fail right now, even though the file can be formatted as a whole).

mrkkrp commented 3 years ago

Right, so it's mostly important in the context of region formatting.

mrkkrp commented 3 years ago

The solution here would be to identify these situations and shift the closing parenthesis or brace like we already do in certain situations.

Edit: it might actually introduce a discrepancy between the output obtained by formatting the whole file vs formatting regions of a file separately. I believe that shifting the closing parenthesis might be not necessary in this case (i.e. when the function is formatted as a whole):

test =
  ( 1,
    2
  )
buggymcbugfix commented 2 years ago

Right, so it's mostly important in the context of region formatting.

Not exactly.

But what a top-level tuple or a list mean?

This is just a pattern. Consider:

a, b :: Int
(a, b) = (1, 2)

Another example of a multiline pattern might be

a, b :: Int
Foo
  a
  b = mkFoo 42

Apparently for multiline patterns the subsequent lines must always be indented more than the first column of the first line of the pattern.

amesgen commented 2 years ago

@buggymcbugfix The cases you mention are already correctly handled by Ormolu, or am I missing something in your comment?

buggymcbugfix commented 2 years ago

I didn't check if they are correctly handled, but I assume they would be. I was merely answering @mrkkrp's question.

amesgen commented 2 years ago

Yeah, but the cases you mention are not top-level tuples/lists, but different constructs. But the asymmetry between tuple expressions and tuple patterns is indeed surprising:

a = (a
    ,a)

is valid (even with less indentation in the second line), but

(a
,a) = a

is not.