question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Measure-generic structs wrongly can't be treated as unmanaged

See original GitHub issue

This issue is described here. Given this type definition:

[<Struct>] 
type vec3<[<Measure>] 'u> = 
   val mutable X: float<'u> 
   val mutable Y: float<'u> 
   val mutable Z: float<'u>

the F# compiler won’t allow vec3<_> to satisfy the unmanaged type constraint because it’s “generic”, even though it isn’t really generic in the CLR sense (since measure type arguments are erased at runtime):

 // error FS0001: A generic construct requires that the type 'vec3<1>' is an unmanaged type
 let ptr = NativeInterop.NativePtr.ofNativeInt<vec3<1>> 0n

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
zpodlovicscommented, Sep 30, 2015

Similar but non measure generic case for struct with measurement fields: #276 which was fixed in #289

open System.Runtime.InteropServices

[<Measure>]
type Version

[<Struct>]
type S =
  val X: int

[<Struct>]
type SM =
  val X: int<Version> 

[<Struct>]
type SMG<[<Measure>] 'u> =
  val X: int<'u> 

[<Struct; StructLayout(LayoutKind.Sequential, Pack=1)>]
type SS =
  val X: int

[<Struct; StructLayout(LayoutKind.Sequential, Pack=1)>]
type SMS =
  val X: int<Version> 

[<Struct; StructLayout(LayoutKind.Sequential, Pack=1)>]
type SMGS<[<Measure>] 'u> =
  val X: int<'u> 

let f (x : 'T when 'T: unmanaged and 'T: struct) = printfn "%A" x

f (S())
f (SM())
//f (SMG()) // FS0001: A generic construct requires that the type 'SMG<'u>' is an unmanaged type
//f (SMG<Version>()) // FS0001: A generic construct requires that the type 'SMG<Version>' is an unmanaged type
f (SS())
f (SMS())
//f (SMGS()) // FS0001: A generic construct requires that the type 'SMGS<'u>' is an unmanaged type
//f (SMGS<Version>()) // FS0001: A generic construct requires that the type 'SMGS<Version>' is an unmanaged type

printf "is SMG<Version> a generic type: %A\n" (typeof<SMG<Version>>.IsGenericType)
printf "is SMG<Version> a value type: %A\n" (typeof<SMG<Version>>.IsValueType)

Note if you use it for native interop: Blittable types are a subset of unmanaged types where the type have same managed and unmanaged representation.

Ecma 355 II.10.1.2 Type layout attributes

“[Rationale: The default auto layout should provide the best layout for the platform on which the code is executing. sequential layout is intended to instruct the CLI to match layout rules commonly followed by languages like C and C++ on an individual platform, where this is possible while still guaranteeing verifiable layout. explicit layout allows the CIL generator to specify the precise layout semantics. end rationale]”

0reactions
kbattocchicommented, Oct 5, 2015

@zpodlovics See issue #654, which is being fixed by #656.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why generic structs cannot be unmanaged?
This is how the workaround might look like: public unsafe class ArrayOfGenericStructs<TStruct> : IDisposable where TStruct:struct { private ...
Read more >
generic constraint: where T : ref struct · Issue #1148
Today it's not possible to use a ref struct as a type argument to a generic method or method of a generic type....
Read more >
Default Marshalling Behavior - .NET Framework
The interop marshaller always attempts to free memory allocated by unmanaged code. This behavior complies with COM memory management rules, ...
Read more >
Code quality rules overview - .NET
A class that declares an IDisposable field indirectly owns an unmanaged resource and should implement the IDisposable interface.
Read more >
Components | Entities | 0.50.1-preview.2
IComponentData marks a struct as an unmanaged component type. These are the most common kind of components. The fields of an IComponentData ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found