Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

byref return in F# 4.5

I am trying to add a F#-style interface to a type, that has a byref return method. Here's the code:

type IPool<'P, 'T when 'T: struct> =
  abstract member GetReference: ITypedPointer<'P, 'T> -> byref<'T>

let Ref<'TPool, 'P, 'T when 'TPool :> IPool<'P, 'T>> (pool: 'TPool) pointer =
  pool.GetReference pointer

Now to my surprise, a similar thing worked fine until I introduced IPool interface. Before that Ref itself contained an implementation like &pool.data.[idx], and worked fine.

I tried installing nightly build of F# Tools, cause latest release does not officially support byref returns, and PR to introduce them was recently completed: https://github.com/Microsoft/visualfsharp/pull/4888

However, I still get error FS3209: The address of the variable 'copyOfStruct' cannot be used at this point. A method or function may not return the address of this local value. in Visual Studio. Type outref<T> still does not seem to be available either. Am I missing something?

I also tried to drop the pointer parameter, and just return pool.GetReference to only get a different error message.

Addition: the ultimate goal is to be able to do

let aref = Ref pool ptr
let bref = Ref pool ptr
aref <- 42
assert(aref = bref)

e.g. give caller a direct reference to an internal memory, usually backed by an array, similar to Span<T>. I am making this for performance reasons, so it is not OK to allocate on every call to Ref.

like image 732
LOST Avatar asked Jun 25 '18 23:06

LOST


1 Answers

For some reason, reducing generalization helped to get rid of the error:

let Ref<'P, 'T when 'T: struct> (pool: IPool<'P, 'T>) pointer = pool.GetReference pointer

Solution provided by

https://github.com/Microsoft/visualfsharp/issues/5366#issuecomment-407521220

Though it does not explain why the original code does not compile.

like image 70
LOST Avatar answered Nov 20 '22 03:11

LOST