The documentation of wrapping_offset should clarify whether it is legal to use this function to move from one object to another. Concretely, is the following a "safe" function in the sense that it is safe to call by any safe client?
fn is_this_safe(x: &mut i32, y: &mut i32) {
let x_ptr = x as *mut _; drop({x});
let y_ptr = y as *mut _; drop({y});
let diff = x_ptr.offset_to(y_ptr).unwrap();
let x_alias = x_ptr.wrapping_offset(diff);
unsafe { *x_alias = 42; }
}
(The funny drop just make sure that the original x and y are gone, side-stepping some memory model questions.)
I see two possible options:
- We say this is safe. Then we have to change the implementation of
wrapping_offset; currently, it compiles to a getelementptr which (even without inbounds) is documented to possibly return a pointer that cannot be dereferenced even if it is equal to a valid pointer. The intention behind this is probably for getelementptr to preserve aliasing information. As a consequence, getelementptr cannot cross object boundaries.
- We say this is not safe. Then the documentation of
wrapping_offset should get a big fat warning saying so.
Given that wrapping_offset is a safe function, I think I would prefer the least surprising option, which is to make this safe. One possible implementation would be to cast the pointer to an integer, do the arithmetic there, and cast back.
Cc @eddyb @arielb1 @gankro
The documentation of
wrapping_offsetshould clarify whether it is legal to use this function to move from one object to another. Concretely, is the following a "safe" function in the sense that it is safe to call by any safe client?(The funny
dropjust make sure that the originalxandyare gone, side-stepping some memory model questions.)I see two possible options:
wrapping_offset; currently, it compiles to agetelementptrwhich (even withoutinbounds) is documented to possibly return a pointer that cannot be dereferenced even if it is equal to a valid pointer. The intention behind this is probably forgetelementptrto preserve aliasing information. As a consequence,getelementptrcannot cross object boundaries.wrapping_offsetshould get a big fat warning saying so.Given that
wrapping_offsetis a safe function, I think I would prefer the least surprising option, which is to make this safe. One possible implementation would be to cast the pointer to an integer, do the arithmetic there, and cast back.Cc @eddyb @arielb1 @gankro