sway
sway copied to clipboard
Introduce a new `raw_ptr` type
For example:
struct RawVec<T> {
#[pointer]
ptr: u64,
cap: u64,
}
The immediate benefit of this is preventing RawVec<T> (and by extension Vec<T>) from being returned from a script because when we cross the script boundary, the ptr value is not meaningful.
This annotation may have future uses as well.
An alliterative is to introduce pointer/reference types (other than mut ref function parameters) but that's a rabbit hole we probably don't want to explore.
Edit: The above proposal has been voted against and the preferred way of doing this seems to be to introduce a raw_ptr type as @canndrew as described in https://github.com/FuelLabs/sway/pull/2699
This feels a bit hacky, as does a lot of our avoidance of pointers. But I really don't want to add references.
Would an alternative be an 'address' type, which is very much locked down? I.e. you can't create them from anywhere other than a heap or stack allocation. It'd be different to a reference or pointer, where you would take the address of a value. And then we limit it specifically to only do the operations we need in Vec and similar data structures. :thinking:
This feels a bit hacky, as does a lot of our avoidance of pointers. But I really don't want to add references.
Would an alternative be an 'address' type, which is very much locked down? I.e. you can't create them from anywhere other than a heap or stack allocation. It'd be different to a reference or pointer, where you would take the address of a value. And then we limit it specifically to only do the operations we need in
Vecand similar data structures. thinking
That does sound better than the #[pointer]. It kinda reminds me of C's intptr_t, which is still an integer in essence, but providing some limited type-safety, and conveying that it's really a pointer inside.
I also think an untyped pointer type is the way to go. Then, when/if we get typed pointers/references we can have conversion methods for add/removing the pointee type. eg. something like:
impl RawPtr {
unsafe fn with_type<T>(self) -> *const T;
}
impl<T> *const T {
fn strip_type(self) -> RawPtr;
}
It's also important if we ever want to start tracking provenance to have a distinction between pointers and pointer-sized ints.