Specific indentation of type constraint throws error
When the when in a type constraint is directly under the apostrophe of the generic type, it throws a compiler error. If the type constraint is one space to the left or one space to the right it compiles successfully.
Repro steps
Compile the following:
type A<'T
when 'T : comparison>() = // this is fine
class end
type B<'T
when 'T : comparison>() = // this is fine
class end
type C<'T
when 'T : comparison>() = // error
class end
Note that in A the when starts under the <, in B the when starts under the T and in C the when starts under the '
Expected behavior
All three cases compile
Actual behavior
I get the following error:
error FS0010: Incomplete structured construct at or before this point in type name. Expected '>' or other token
Known workarounds
You can move the indentation of the type constraint forwards or backwards by one space.
Related information
- F#: 4.6
- IDE: Visual Studio 2019
- OS: Windows 10
This seems like a bug in the parser. Generally people don do this kind of alignment so I suppose that's why it hasn't come up yet.
I ran into this because I was trying to align it like the following when I had a lot of type parameters and a long type constraint
type C<'T,
'U,
'V
when 'T : comparison>()
class end
It kinda felt a little awkward having all the type parameters aligned but the type constraint to have a different alignment.
Yes, this is a bug in the lexfilter
Related:
match 1 with
| (_
| _) -> ()
error FS0010: Incomplete structured construct at or before this point in pattern. Expected ')' or other token.
error FS0583: Unmatched '('
error FS0010: Incomplete structured construct at or before this point in pattern. Expected ')' or other token.
error FS0583: Unmatched '('
Related:
type TypeWithALongName< ^a
when ^a:(static member(+):'a * 'a -> 'a )
and ^a:(static member(-):'a * 'a -> 'a )
and ^a:(static member(*):'a * 'a -> 'a )
and ^a:(static member(/):'a * 'a -> 'a )
> =
static member inline X = ()
error FS0010: Incomplete structured construct at or before this point in type name. Expected '>' or other token.
But these are okay:
type TypeWithALongName< ^a
when ^a:(static member(+):'a * 'a -> 'a )
and ^a:(static member(-):'a * 'a -> 'a )
and ^a:(static member(*):'a * 'a -> 'a )
and ^a:(static member(/):'a * 'a -> 'a )
> =
static member inline X = ()
type TypeWithALongName< ^a
when ^a:(static member(+):'a * 'a -> 'a )
and ^a:(static member(-):'a * 'a -> 'a )
and ^a:(static member(*):'a * 'a -> 'a )
and ^a:(static member(/):'a * 'a -> 'a )
> =
static member inline X = ()