Returning a voidptr option throws at runtime
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
When a function returns `Some x` where `x` is of type `voidptr`, the code compiles but throws at runtime.
**Repro steps**
Simple repro:
```f#
let check () =
let mutable tmp = IntPtr.Zero
let mutable handle = NativeInterop.NativePtr.toVoidPtr &&tmp
Some handle
[]
let main argv =
// this throws at runtime
check() |> ignore
```
A similar approach that also fails (but succeeds with `|> ignore`):
```f#
let check () =
let mutable tmp = IntPtr.Zero
let mutable handle = NativeInterop.NativePtr.toVoidPtr &&tmp
handle
[]
let main argv =
// this throws at runtime
printfn "Handle: %A" (check())
```
**Expected behavior**
Either a compile error if this is illegal, or a valid result.
**Actual behavior**
The following error is output to the console:
> Unhandled exception. System.TypeLoadException: The generic type 'Microsoft.FSharp.Core.FSharpOption`1' was used with an invalid instantiation in assembly 'FSharp.Core, Version=4.7.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
> at Program.main(String[] argv)
**Known workarounds**
None. Though using your own DU allows this to run with `|> ignore`, it doesn't allow it to deconstruct. I.e.
This doesn't throw:
```f#
type Handle = Handle of voidptr
let check () =
let mutable tmp = IntPtr.Zero
let mutable handle = NativeInterop.NativePtr.toVoidPtr &&tmp
Handle handle
[]
let main argv =
check() |> ignore
```
But this does:
```f#
let main argv =
// this throws at runtime
match check() with
| Handle x -> printfn "Handle: %A" x
```
**Related information**
Seen on any recent version of VS / F#.
Note that I don't know if `voidptr` is allowed as field. ~Probably not, which would make it understandable that this fails, though a compile-time error would be better.~ EDIT: see below, it works in several scenarios, just not with (v)options.
A possible use-case to allow this (if there're no CLS restrictions) is that returned void pointers are often NULL or valid, and options are a good way to wrap such returns.
Contributor guide
Assessment
This issue has not been assessed yet.