Skip to content

Unable to create a byref-like DU holding a ref type #18512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lovelace08 opened this issue Apr 27, 2025 · 3 comments
Open

Unable to create a byref-like DU holding a ref type #18512

lovelace08 opened this issue Apr 27, 2025 · 3 comments
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Feature Improvement
Milestone

Comments

@lovelace08
Copy link

Please provide a succinct description of the issue.

Try to create a byref-like discriminated union holding a byref type (ex. Span)

Provide the steps required to reproduce the problem:

open System
open System.Runtime.CompilerServices

[<Struct; IsByRefLike>]
type Record = { inner: ReadOnlySpan<byte> }

[<Struct; IsByRefLike>]
type Discrim = | Case of ReadOnlySpan<byte>

let record (x: ReadOnlySpan<byte>) = { inner = x } // Works!
let discrim (x: ReadOnlySpan<byte>) = Case(x) // Does not :(

Expected behavior

No errors

Actual behavior

error FS0418: The byref typed value 'x' cannot be used at this point

Known workarounds

None so far.

Related information

Provide any related information (optional):

  • Operating system
  • .NET Runtime kind (.NET Core, .NET Framework, Mono)
  • Editing Tools (e.g. Visual Studio Version, Visual Studio)
@github-actions github-actions bot added this to the Backlog milestone Apr 27, 2025
@lovelace08 lovelace08 changed the title Unable to create Unable to create a byref-like DU holding a ref type Apr 27, 2025
@T-Gro
Copy link
Member

T-Gro commented Apr 28, 2025

I looked into this, I had no idea this was ever supported.

The RFC FS-1053 https://github.com/fsharp/fslang-design/blob/main/FSharp-4.5/FS-1053-span.md uses the term "struct types" when mentioning features like IsByRefLike support. All the examples and test cases work with regular (non record, non DU) explicitly declared struct types.

Putting aside the need to make DUs work, I think this fits the need of the FS-1053 and could be treated like a bugfix.

There are however things which will not work, neither for DUs nor for records.
One example is printing (ToString()) the type. Compilation will suceed, but there will be an error at runtime https://sharplab.io/#v2:DYLgZgzgNALiBOBXAdlAJiA1AHwPYAcBTZAAgGUBPCGQgWwFgAoA48qm2gOgCUUYBLWoU4BhXLXz9gheGRkA3fgGNCEJkwDaAHjIwkSmAG4SASQgAhCt0JgAMvwDWhAHwBdJjApES1pbnhoJAC8JADeJPzIyDIgPoQAhmgA8sjAFGT48chaAEYUNM4kAL5M0jAk8IR+ASQAFAAesdaJKWkZWbn5LgCUwWERUTJ99cUkAPRjJADq/g4QAIRM+PCRMGCkAEQApBAbdbWV1YG1zcmp6ZmkGtgAjACsiBTYrt3dnAAquLoryADmta8gA .

I assume the biggest amount of work will be checking and verifying if the codegen for lowering records/DUs into IL violates the byref rules or not. And if yes, what to do about those violations.
(in the case of ToString(), it would have to be a different codegen for ToString, e.g. the default one from .NET)

@lovelace08
Copy link
Author

How does a function like ToString() violate byref rules?

@T-Gro
Copy link
Member

T-Gro commented Apr 28, 2025

The decompiled version for ToString looks like this - it passes this to a printing function, which can then box it (cast it to obj directly, or store it somewhere) for it's own internal working:

        [CompilerGenerated]
        public override string ToString()
        {
            return ExtraTopLevelOperators.PrintFormatToString(new PrintfFormat<FSharpFunc<Record, string>, Unit, string, string, Record>("%+A")).Invoke(this);
        }

@abonie abonie added Feature Improvement Area-Compiler-Checking Type checking, attributes and all aspects of logic checking and removed Bug Needs-Triage labels Apr 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Feature Improvement
Projects
Status: New
Development

No branches or pull requests

3 participants