std: deprecate cast::transmute_mut.#13934
Conversation
|
r? @alexcrichton particularly the design of the second commit. (Will rebase at some point.) |
|
It may be nice to have a writeup in the commit message about why this is undefined behavior. For example, this is undefined: let foo = 3;
unsafe {
let foo: &mut int = transmute(&foo);
*foo = 4;
}but is this also undefined? If not, why? |
|
It may be nice to have a writeup in the commit message about why this is undefined behavior. For example, this is undefined: let foo = 3;
unsafe {
let foo: &mut int = transmute(&foo);
*foo = 4;
}but is this also undefined? If not, why? let foo = 3;
unsafe {
let foo: &mut int = &mut *(&foo as *int as *mut int);
*foo = 4;
} |
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]
There was a problem hiding this comment.
Do we know / have thought about how long deprecated features should stay around? I don't want to start the discussion here but I think, given the fact that some things may be deprecated in the near future, we should start discussing this and make the removal date/time part of the deprecation message.
There was a problem hiding this comment.
Just a reasonable amount of time to allow people to get help updating, a relatively obscure function like this is probably ok to remove quicker than normal, a more common function might be left longer than normal. In any case it was mentioned briefly in the original email, specifically
we'll likely leave in #[deprecated] functions for about a month or so.
In terms of actual implementation details of removal, I personally think just using occasionally checking for things to remove & consulting the git history for timing is good enough (since we don't have so much code/#[deprecated]-churn that doing it manually with grep will be particularly hard); others may disagree with this though.
There was a problem hiding this comment.
@huonw all this sounds good to me. I think a month or so is fine for now. We'll likely need a better rule when we get nearer a 1.0 release.
Turning a `&T` into an `&mut T` is 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`.) cc #13933
… r=Veykril feat: Make unlinked_file diagnostic quickfixes work for inline modules Finally got myself to fix this, bothered me quite a bit that this never worked  (Just gotta fix up the indentation still)
fixes rust-lang#13934 I modified the part for checking if the map is used so that it can check field and index exprs. changelog: [`map_entry`]: fix FP on struct member
Turning a
&Tinto an&mut Tis undefined behaviour, and needs to bedone 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,RefCellorUnsafe.)cc #13933