# "&mut -\> \*mut" conversion vs. std::mem::transmute

**URL:** <https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530>\
**Category:** language design\
**Created:** [May 30, 2016, 12:11am UTC](https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530 "2016-05-30T00:11:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![eefriedman](https://avatars.discourse-cdn.com/v4/letter/e/ec9cab/32.png) [@eefriedman](https://internals.rust-lang.org/u/eefriedman)\
**Post date:** [May 30, 2016, 12:11am UTC](https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530/1 "2016-05-30T00:11:20Z")

</div>

Consider the following two functions:

```rust
unsafe fn f1(a: &mut u32) {
    let ptr1: *mut u32 = std::mem::transmute(a);
    *a = 1;
}

unsafe fn f2(a: &mut u32) {
    let ptr1: *mut u32 = a;
    *a = 1;
}

```

With current Rust, the first gives a borrowck error, the second doesn’t. The behavior of transmute is easy to understand: it consumes the reference, so future uses will go through the pointer instead. The conversion, on the other hand, is like transmute\_copy: it gives you a pointer, but the original reference is still valid. This seems ridiculous: why does the simpler version default to behavior equivalent to transmute\_copy?

If we changed the borrow checker to treat f1 and f2 the same way, it would make split-at-mut-via-duplication from [http://smallcultfollowing.com/babysteps/blog/2016/05/27/the-tootsie-pop-model-for-unsafe-code/](http://smallcultfollowing.com/babysteps/blog/2016/05/27/the-tootsie-pop-model-for-unsafe-code/) simply illegal, so nobody could make a mistake like that.

If you actually want the old behavior, you could still write `let ptr1 : *mut u32 = &mut *a;`.

Has something like this been discussed before?

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [June 1, 2016, 12:07am UTC](https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530/2 "2016-06-01T00:07:37Z")

</div>

This would make a lot of FFI code pretty painful to work with, I think. It’s very common to do things like `some_c_fn(p)` where `p: &mut T` but `some_c_fn` expects a `*mut T`.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [June 1, 2016, 12:08am UTC](https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530/3 "2016-06-01T00:08:03Z")

</div>

And of course, the way I initially wrote the example, it used `transmute_copy` =)

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:26am UTC](https://internals.rust-lang.org/t/mut-mut-conversion-vs-std-mem-transmute/3530/4 "2019-03-25T08:26:15Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
