Skip to content

Object expression in struct generates byref field in a class #19068

@IS4Code

Description

@IS4Code

Using an object expression in a struct that depends on this or primary constructor parameters in the arguments to the object's constructor results in a class being emitted with a byref field.

Repro steps

type Class(test : obj) = class end

[<Struct>]
type Struct(test : obj) =
  member _.Test() = {
    new Class(test) with
    member _.ToString() = ""
  }

Expected behavior

Struct should be compiled into a valid type that does what the code expresses.

Actual behavior

The type of the anonymous class created in Test has a byref<Struct>, resulting in a TypeLoadException at runtime.

It seems that when the "closure" type that is generated here depends on the containing type, it is always generated with a byref _ field that stores a reference to the original struct, even if that reference is never used.

Normally, situations like this result in FS0406 (The byref-typed variable '_' is used in an invalid way.), however here the instance is not referenced in any of the members of the anonymous class.

Even the constructor itself is kinda strange:

public Test@5(ref Struct _)
{
    Unsafe.As<Struct, ref Struct>(ref this._) = ref _;
    base..ctor(((Struct)Unsafe.As<Struct, ref Struct>(ref this._)).test);
}

No idea what the intention here was, but calling base(_.test) instead would have worked quite fine.

Known workarounds

If the constructor's arguments are first bound to variables, everything is fine.

Related information

Environment: .NET 9.0.303, sharplab.io

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions