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
?
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