structf#byref

Cannot express a ref-like struct with other ref-like struct members [<IsByRefLike; Struct>]


I am experimenting with a non-allocating path segment enumerator using nested IsByRefLike struct types, but the compiler is putting up a wall of "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.". Is that the end of the road for the experiment, or is the intent possible to express?

namespace Experiment

open System
open System.Runtime.CompilerServices

[<IsByRefLike; Struct>]
type refoption<'T> =
    | RefNone
    | RefSome of value: 'T

[<IsByRefLike; Struct; RequireQualifiedAccess>]
type FilePathStepRef =
    | Drive of driveName: ReadOnlySpan<char>
    | Parent of parentName: ReadOnlySpan<char>
    | Name of name: ReadOnlySpan<char>

[<IsByRefLike; Struct>]
type FilePathStepRefEnumerator =
    internal
        { Initial: ReadOnlySpan<char>
          mutable Head: FilePathStepRef refoption // Compiler error
          mutable Tail: ReadOnlySpan<char> }

    // The remaining code is not necessary to exhibit the error.

    interface IDisposable with
        member this.Dispose() =
            this.Head <- RefNone
            this.Tail <- ReadOnlySpan.Empty

    member this.Current: FilePathStepRef refoption = this.Head

    member this.MoveNext() =
        if this.Tail.Length = 0 then
            false
        else
            // TODO
            true

    member this.GetEnumerator() = this

Since all types involves appear to be IsByRefLike, my assumption was that it would work.

Perhaps the refoption type is missing a constraint on 'T?


Solution

  • For now, at least, you can't use a ref-like struct as a generic parameter: https://github.com/dotnet/runtime/issues/65112

    Looks like this will be possible in .NET 8