Type abbreviation is wrongly formatted
Issue created from fantomas-online
Code
type GetParseResultsForFile = string<LocalPath> -> FSharp.Compiler.Text.Position -> Async<ResultOrString<ParseAndCheckResults * string * FSharp.Compiler.Text.ISourceText>>
Result
type GetParseResultsForFile =
string<LocalPath>
-> FSharp.Compiler.Text.Position
-> Async<ResultOrString<ParseAndCheckResults * string * FSharp.Compiler.Text.ISourceText>>
Problem description
Given the recent guidance of the style guide, I would expect that the result should be:
type GetParseResultsForFile =
string<LocalPath> ->
FSharp.Compiler.Text.Position ->
Async<ResultOrString<ParseAndCheckResults * string * FSharp.Compiler.Text.ISourceText>>
However, this leads to invalid code: example
@dsyme any idea why this is happening?
Extra information
- [ ] The formatted result breaks by code.
- [ ] The formatted result gives compiler warnings.
- [ ] I or my company would be willing to help fix this.
Options
Fantomas 4.6 branch at 1/1/1990
Default Fantomas configuration
Did you know that you can ignore files when formatting from fantomas-tool or the FAKE targets by using a .fantomasignore file?
Hmmm I see. We only tested val declarations, e.g.
val F:
A ->
B ->
C
and not type abbreviations:
type X =
A ->
B ->
C
It seems value signatures can use end-of-line -> without indentation of the next line, but types themselves can't
(Note, the thing on the right of a val or member declaration is a value signature, parsed with different parsing rules to a type)
I'm having trouble determining exactly which types this applies to.
- The restriction does apply to types inside value signatures, e.g. this will produce an error
// Gives an error
val GetParseResultsForFile :
(A ->
B ->
C)
- The restriction does not apply to outermost types in record declarations
// Does not give an error
type R =
{ F: A ->
B ->
C }
but does apply to inner types:
// Gives an error
type R =
{ F: (A ->
B ->
C) }
- The restriction does not apply to the right hand side of function types, e.g. only the outer most position of type abbreviations or parenthesized types:
/// Does not give an error
type X =
A ->
B ->
C ->
D
/// Does not give an error
val F :
(A ->
B ->
C ->
D)
I think the safest assumption is to make indent happen for the B part of a multi-line "A -> B" when
A. the type occurs on the right of a type abbreviation, OR B. the type occurs in parentheses
However I guess we should systematically test all other locations where types can occur in the grammar. I'm not actually sure of the problem, I guess it must be a missing rule in the grammar to deal with the offside thing inserted after the ->, but one that is only kicking in for types in very specific locations.