menu
412 tokens

Unsafe

Raw pointers are inert.

Unsafe

Safe Destack code can create and carry raw pointers, because there is nothing directly unsafe about just looking at pointers. Raw pointers are inert: they do not keep storage alive, do not participate in borrow checking, and do not prove exclusivity.

Converting a borrow to a raw pointer is still safe because it does not touch the pointed-to memory:

1class User {}2 3let user = new User();4 5let borrow: &User = &user;6let pointer: *User = borrow; // OK: this only creates a raw pointer value

Unsafe begins when code relies on a memory invariant the compiler cannot prove:

Operation Example Safe? Why
create or carry raw pointer values
let pointer: *User = &user, pointer == other
yes
does not touch memory
reinterpret raw pointer values
pointer as *uint8, 0x1000 as *uint8
yes
makes no validity claim
wrapping address arithmetic
raw.wrappingOffset(pointer, 4)
yes
makes no allocation claim
allocation-relative pointer math
raw.offset(pointer, 4), raw.offsetFrom(pointer, origin)
no
claims same live allocation
access memory through a pointer
raw.asReference(pointer), raw.read(pointer), raw.write(pointer, value)
no
bypasses borrow checking
build a raw slice descriptor from raw parts
sliceFromRaw<T>(pointer, length)
no
claims a valid region of T
raw bytes and layout tricks
raw.copyBytes(dst, src, n), raw.readVolatile(pointer), raw.transmute<T, U>(value)
no
touches or reinterprets unchecked memory

The compiler rejects unsafe operations, like raw pointer dereferencing, outside explicit @unsafe / @safe contexts.