fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Private constructor requires attribute

Open nojaf opened this issue 2 years ago • 4 comments

When generating a signature file the result is somewhat unexpected.

Repro steps

module Telplin

type A private () = 
    member a.Foo () = ()

leads to


module Telplin

type A =
  
  member Foo: unit -> unit

Expected behaviour

This should have [<Class>] attribute.

Actual behaviour

Missing attribute does not compile.

Related information

FCS: FSharpCheckFileResults.GenerateSignature

nojaf avatar Jan 16 '24 11:01 nojaf

@nojaf Are you sure it's specifically about private constructors? I can reproduce it without adding the type to implementation file, so neither constructor nor its visibility change anything. I think the compiler wants to say that it can't decide which representation to use, based on the single property member in the signature file.

Expected behaviour

This should have [<Class>] attribute.

I think the rules are a bit more complicated than this. Consider this, for example:

[<Struct>]
type A private (i: int) =
    member a.Foo = 1

The compiler suggests to use Class, Struct, or Sealed, so we need to choose the attribute accordingly.

auduchinok avatar Jan 16 '24 11:01 auduchinok

Adding private new: unit -> A to the signature removes the need to add the attribute. Whether the attribute should be Class does indeed depend on what the actual type is. However, I do believe structs are generated correctly.

nojaf avatar Jan 16 '24 11:01 nojaf

Btw, what is generated for private type representations?

type U1 =
    private
        | A of int

    member this.P = 1

type U2 =
    private
        | A of int

Something like this?

[<Sealed>]
type U1 =
    member P: int

type U2

auduchinok avatar Jan 16 '24 12:01 auduchinok

Btw, what is generated for private type representations?

Run the compiler with --allsigs flag and you will know 😉.

nojaf avatar Jan 16 '24 13:01 nojaf