fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Codegen issue w.r.t. `DefaultAugmentation(false)`

Open vzarytovskii opened this issue 2 years ago • 1 comments

Given the following code:

open System
[<DefaultAugmentation(false)>]
type Option<'T> =
    | Some of Value: 'T
    | None
 
    member x.Value =
        match x with
        | Some x -> x
        | None -> raise (new InvalidOperationException("Option.Value"))
 
    static member None : Option<'T> = None
and 'T option = Option<'T>

When compiling or pasted to FSI, produces the following issue:

Error in pass2 for type ..., error: duplicate entry 'get_None' in method table

Removing DefaultAugmentation attribute and static member None resolves the issue.

Interestingly enough, this is roughly how FSharpOption is defined in fslib, it also fails to compile in fsi, but not in product compiler apparently.

If it's a regression, then it's a fairly old one, SharpLab shows it and they use F# 6

vzarytovskii avatar Jan 22 '24 08:01 vzarytovskii

Additionally, there are multiple issues with both method and properties, which are related to this one:

open System
[<DefaultAugmentation(false)>]
[<StructuralEquality; StructuralComparison>]
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
[<CompiledName("FSharpOption`1")>]
type Option<'T> =
    | Some of Value: 'T
    | None

    [<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
    member x.Value =
        match x with
        | Some x -> x
        | None -> raise (new InvalidOperationException("Option.Value"))

    [<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
    member x.IsNone =
        match x with
        | None -> true
        | _ -> false

    [<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
    member x.IsSome =
        match x with
        | Some _ -> true
        | _ -> false

will yield

error FS0192: internal error: Error in pass2 for type FSI_0019, error: Error in pass2 for type FSharpOption`1, error: duplicate entry 'get_Value' in method table

open System
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type Option<'T> =
    | Some of Value: 'T
    | None

    member x.Value =
        match x with
        | Some x -> x
        | None -> failwith "None"

will yield

error FS0192: internal error: Error in pass2 for type FSI_0013, error: Error in pass2 for type Option`1, error: duplicate entry 'Value' in property table

When either of the following is changed, it compiles correctly (valid for both cases):

  • member x.Value is completely removed
  • member x.Value is rewritten as member x.Value = () (this fixes is probably due to return type change)
  • Some of Value: 'T is rewritten as Some of ValueZ: 'T or Some of 'T (will generate two separate properties in ilxgen)
  • [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>] is removed (not sure how and why does it affect this specific codegen path).

vzarytovskii avatar Jan 22 '24 09:01 vzarytovskii