From 781ac3e777a5f47bdfaba05ee17f8b79845670b1 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 4 May 2014 23:17:37 +1000 Subject: std: deprecate cast::transmute_mut. Turning a `&T` into an `&mut T` carries a large risk of undefined behaviour, and needs to be done very very carefully. Providing a convenience function for exactly this task is a bad idea, just tempting people into doing the wrong thing. The right thing is to use types like `Cell`, `RefCell` or `Unsafe`. For memory safety, Rust has that guarantee that `&mut` pointers do not alias with any other pointer, that is, if you have a `&mut T` then that is the only usable pointer to that `T`. This allows Rust to assume that writes through a `&mut T` do not affect the values of any other `&` or `&mut` references. `&` pointers have no guarantees about aliasing or not, so it's entirely possible for the same pointer to be passed into both arguments of a function like fn foo(x: &int, y: &int) { ... } Converting either of `x` or `y` to a `&mut` pointer and modifying it would affect the other value: invalid behaviour. (Similarly, it's undefined behaviour to modify the value of an immutable local, like `let x = 1;`.) At a low-level, the *only* safe way to obtain an `&mut` out of a `&` is using the `Unsafe` type (there are higher level wrappers around it, like `Cell`, `RefCell`, `Mutex` etc.). The `Unsafe` type is registered with the compiler so that it can reason a little about these `&` to `&mut` casts, but it is still up to the user to ensure that the `&mut`s obtained out of an `Unsafe` never alias. (Note that *any* conversion from `&` to `&mut` can be invalid, including a plain `transmute`, or casting `&T` -> `*T` -> `*mut T` -> `&mut T`.) [breaking-change] --- src/libnative/io/file_win32.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libnative') diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 88ba6dcbc7e..aae15a86614 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -174,7 +174,8 @@ impl rtio::RtioFileStream for FileDesc { fn tell(&self) -> Result { // This transmute is fine because our seek implementation doesn't // actually use the mutable self at all. - unsafe { cast::transmute_mut(self).seek(0, io::SeekCur) } + // FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes + unsafe { cast::transmute::<&_, &mut FileDesc>(self).seek(0, io::SeekCur) } } fn fsync(&mut self) -> Result<(), IoError> { -- cgit 1.4.1-3-g733a5