Q:

Why does F# constrain my code and remove generics?

type VBO<'T when 'T : (new : unit -> 'T) and 'T : struct and 'T :> ValueType> = 
    { Handle : int
      target : BufferTarget
      size : int
      dataSize : int
      data : 'T []
      pos : int
      usage : BufferUsageHint }

type VBO = 
    static member Create(target, size, pos, usage, (data : Vector3 [])) = 
        VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)

    // Type mismatch. Expecting Vector3 but found Vector2
    static member Create(target, size, pos, usage, (data : Vector2 [])) = 
        VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)

    // This construct causes code to be less generic than indicated by the type annotations.
    // The type variable 'T has been constrained to be type 'Vector3'.
    static member CreateImpl(target, size, pos, usage, dataSize, (data : 'T [])) = 
        let h = GL.GenBuffer()
        { Handle = h
          target = target
          size = size
          dataSize = dataSize
          data = data
          pos = pos
          usage = usage }

F# tries to constrain my code but I want it to be generic. I don't really care about what type the data is I just need it pass in the correct dataSize.
What have I done wrong?

A:

The F# compiler seems to specialise generic types if they are used at a particular instantiation in the same block of code. Try splitting up your declaration like this:
type VBO<'T when 'T : (new : unit -> 'T) and 'T : struct and 'T :> ValueType> = 
    { Handle : int
      target : BufferTarget
      size : int
      dataSize : int
      data : 'T []
      pos : int
      usage : BufferUsageHint }

type VBO = 
    static member CreateImpl(target, size, pos, usage, dataSize, (data : 'T [])) = 
        let h = GL.GenBuffer()
        { Handle = h
          target = target
          size = size
          dataSize = dataSize
          data = data
          pos = pos
          usage = usage }

type VBO with
    static member Create(target, size, pos, usage, (data : Vector3 [])) = 
        VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)

    static member Create(target, size, pos, usage, (data : Vector2 [])) = 
        VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)

A:

F#'s type inference works top-to-bottom and left-to-right, which occasionally leads to interesting corner cases.  In particular, reordering method definitions within a type can affect the inferred types.  As Ganesh has pointed out, one solution to your problem is to break your type  up into disjoint chunks, but this isn't actually necessary - just putting the generic method first should be sufficient (and note that you can also drop the type annotation on data, if desired).
You can see very similar behavior with simple let rec bindings.  Consider:
let rec f() = h 5
and g() = h "test"
and h x = x

When attempting to infer the type of f, the compiler notes that h must take an int as input, which makes g's definition invalid.  Reordering the definitions to put h first is the easiest solution (then the compiler can infer a generic type for h before looking at the bodies of f and g, so everything goes through fine).  
Alternatively, you can explicitly make h generic and add type annotations to help the compiler out:
let rec f() = h 5
and g() = h "test"
and h<'t> (x:'t) :'t = x

This can be inconvenient since it can require a significant annotation overhead, but there are circumstances where simply reordering definitions is insufficient to allow the compiler to infer the correct types, so it may sometimes be necessary.

