-
Notifications
You must be signed in to change notification settings - Fork 2
Description
The goal is to be able to write functions that accept a pointer, reference or a value. This is necessary in cases where you write data structures that can be either allocated by a reference, be on the stack or even allocated by another allocator (and be returned as a pointer).
To be able to encompass all of these uses the most straight forward way would be to just use a pointer. However, this requires a cast when coming from a reference and for values you need to use the address operator. Another downside is that there's no way to check if the value is used sensibly (i.e it doesn't escape the function).
Therefore it makes sense to use a new type byref T. This type would only be valid as function argument, and it would be implemented like a regular pointer. This also means that dynamic dispatch doesn't work for it, if you want that you need to use an ordinary reference. Here it works like a normal value.
type I = interface { def fun }
type S = struct {}
def foo(s: byref S) {}
// This also implicitly generates the function:
// def foo(s: &S) { foo(s !*S) }
let a: &I = {} !&S
a.foo() // Works, calls the right function
let b = {} !S
b.foo()
let c = *b
c.foo()