top | item 41440655

(no title)

yinser | 1 year ago

Is it possible for the rust compiler to statically determine if two memory regions will overlap at compile-time, especially with complex pointer arithmetic or when pointers are passed as function arguments? It would be super impressive if so.

discuss

order

saghm|1 year ago

Yes and no; the borrow checker requires that mutable references are exclusive, which combined with ownership semantics means that it isn't possible to construct references that overlap if either is mutable. This is only in "safe" Rust though; inside an a`unsafe` block (or an `unsafe` function, which can only be called in an unsafe block) certain invariants are relaxed, with the requirement that they need to hold again at the close of the block to avoid undefined behavior.

In practice, that means that when writing your own code, you can (and in the vast majority of cases should) just stick to safe Rust, and you can be sure that you won't ever make overlapping references if either one is mutable. Safe APIs can be built on top of unsafe APIs though, so you won't necessarily be able to assume your dependencies are doing the same (although there's tooling to help with that, e.g. requiring via the config to generate a build error if any dependency uses unsafe code)

yinser|1 year ago

Thank you for that explanation. In the original blog post an example is shared of reusing a buffer, and I was curious how Rust would handle that scenario. Perplexity suggested the following:

// Use a mutable slice to represent the buffer:

let mut buffer = [0u8; 16];

// Read into the buffer:

let n = socket.read(&mut buffer)?;

// To move the partial second row to the beginning, you'd use safe operations like:

let second_row_start = 7; // Index where second row starts

buffer.copy_within(second_row_start.., 0);

// Then read more data into the remaining space:

let remaining_space = &mut buffer[9..];

let additional_bytes = socket.read(remaining_space)?;

Is this idiomatic for Rust?