fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Specific indentation of type constraint throws error

Open CameronAavik opened this issue 6 years ago • 5 comments

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

CameronAavik avatar Jun 04 '19 09:06 CameronAavik

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.

cartermp avatar Jun 04 '19 23:06 cartermp

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.

CameronAavik avatar Jun 04 '19 23:06 CameronAavik

Yes, this is a bug in the lexfilter

dsyme avatar Aug 31 '20 15:08 dsyme

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 '('

Happypig375 avatar Jun 29 '21 07:06 Happypig375

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 = ()

Happypig375 avatar Jul 02 '21 16:07 Happypig375