Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 564935689ab5527f955e5449ded02799 > files > 1370

rust-doc-1.19.0-1.mga6.armv7hl.rpm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="API documentation for the Rust `transmute` fn in crate `core`.">
    <meta name="keywords" content="rust, rustlang, rust-lang, transmute">

    <title>core::intrinsics::transmute - Rust</title>

    <link rel="stylesheet" type="text/css" href="../../normalize.css">
    <link rel="stylesheet" type="text/css" href="../../rustdoc.css">
    <link rel="stylesheet" type="text/css" href="../../main.css">
    

    <link rel="shortcut icon" href="https://doc.rust-lang.org/favicon.ico">
    
</head>
<body class="rustdoc fn">
    <!--[if lte IE 8]>
    <div class="warning">
        This old browser is unsupported and will most likely display funky
        things.
    </div>
    <![endif]-->

    

    <nav class="sidebar">
        <a href='../../core/index.html'><img src='https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png' alt='logo' width='100'></a>
        <p class='location'><a href='../index.html'>core</a>::<wbr><a href='index.html'>intrinsics</a></p><script>window.sidebarCurrent = {name: 'transmute', ty: 'fn', relpath: ''};</script><script defer src="sidebar-items.js"></script>
    </nav>

    <nav class="sub">
        <form class="search-form js-only">
            <div class="search-container">
                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
                       type="search">
            </div>
        </form>
    </nav>

    <section id='main' class="content">
<h1 class='fqn'><span class='in-band'>Function <a href='../index.html'>core</a>::<wbr><a href='index.html'>intrinsics</a>::<wbr><a class="fn" href=''>transmute</a></span><span class='out-of-band'><span class='since' title='Stable since Rust version 1.0.0'>1.0.0</span><span id='render-detail'>
                   <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
                       [<span class='inner'>&#x2212;</span>]
                   </a>
               </span><a class='srclink' href='../../src/core/intrinsics.rs.html#928' title='goto source code'>[src]</a></span></h1>
<pre class='rust fn'>pub unsafe extern &quot;rust-intrinsic&quot; fn transmute&lt;T, U&gt;(e: T) -&gt; U</pre><div class='docblock'><p>Reinterprets the bits of a value of one type as another type.</p>

<p>Both types must have the same size. Neither the original, nor the result,
may be an <a href="../../nomicon/meet-safe-and-unsafe.html">invalid value</a>.</p>

<p><code>transmute</code> is semantically equivalent to a bitwise move of one type
into another. It copies the bits from the source value into the
destination value, then forgets the original. It&#39;s equivalent to C&#39;s
<code>memcpy</code> under the hood, just like <code>transmute_copy</code>.</p>

<p><code>transmute</code> is <strong>incredibly</strong> unsafe. There are a vast number of ways to
cause <a href="../../reference/behavior-considered-undefined.html">undefined behavior</a> with this function. <code>transmute</code> should be
the absolute last resort.</p>

<p>The <a href="../../nomicon/transmutes.html">nomicon</a> has additional
documentation.</p>

<h1 id='examples' class='section-header'><a href='#examples'>Examples</a></h1>
<p>There are a few things that <code>transmute</code> is really useful for.</p>

<p>Getting the bitpattern of a floating point type (or, more generally,
type punning, when <code>T</code> and <code>U</code> aren&#39;t pointers):</p>

<pre class="rust rust-example-rendered">
<span class="kw">let</span> <span class="ident">bitpattern</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="ident">f32</span>, <span class="ident">u32</span><span class="op">&gt;</span>(<span class="number">1.0</span>)
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">bitpattern</span>, <span class="number">0x3F800000</span>);<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Alet%20bitpattern%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3Cf32%2C%20u32%3E(1.0)%0A%7D%3B%0Aassert_eq!(bitpattern%2C%200x3F800000)%3B%0A%7D">Run</a></pre>

<p>Turning a pointer into a function pointer. This is <em>not</em> portable to
machines where function pointers and data pointers have different sizes.</p>

<pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">foo</span>() <span class="op">-&gt;</span> <span class="ident">i32</span> {
    <span class="number">0</span>
}
<span class="kw">let</span> <span class="ident">pointer</span> <span class="op">=</span> <span class="ident">foo</span> <span class="kw">as</span> <span class="kw-2">*</span><span class="kw">const</span> ();
<span class="kw">let</span> <span class="ident">function</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">*</span><span class="kw">const</span> (), <span class="kw">fn</span>() <span class="op">-&gt;</span> <span class="ident">i32</span><span class="op">&gt;</span>(<span class="ident">pointer</span>)
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">function</span>(), <span class="number">0</span>);<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Afn%20foo()%20-%3E%20i32%20%7B%0A%20%20%20%200%0A%7D%0Alet%20pointer%20%3D%20foo%20as%20*const%20()%3B%0Alet%20function%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C*const%20()%2C%20fn()%20-%3E%20i32%3E(pointer)%0A%7D%3B%0Aassert_eq!(function()%2C%200)%3B%0A%7D">Run</a></pre>

<p>Extending a lifetime, or shortening an invariant lifetime. This is
advanced, very unsafe Rust!</p>

<pre class="rust rust-example-rendered">
<span class="kw">struct</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="ident">i32</span>);
<span class="kw">unsafe</span> <span class="kw">fn</span> <span class="ident">extend_lifetime</span><span class="op">&lt;</span><span class="lifetime">&#39;b</span><span class="op">&gt;</span>(<span class="ident">r</span>: <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;b</span><span class="op">&gt;</span>) <span class="op">-&gt;</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span><span class="op">&gt;</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;b</span><span class="op">&gt;</span>, <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span><span class="op">&gt;&gt;</span>(<span class="ident">r</span>)
}

<span class="kw">unsafe</span> <span class="kw">fn</span> <span class="ident">shorten_invariant_lifetime</span><span class="op">&lt;</span><span class="lifetime">&#39;b</span>, <span class="lifetime">&#39;c</span><span class="op">&gt;</span>(<span class="ident">r</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;b</span> <span class="kw-2">mut</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span><span class="op">&gt;</span>)
                                             <span class="op">-&gt;</span> <span class="kw-2">&amp;</span><span class="lifetime">&#39;b</span> <span class="kw-2">mut</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;c</span><span class="op">&gt;</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="lifetime">&#39;b</span> <span class="kw-2">mut</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span><span class="op">&gt;</span>, <span class="kw-2">&amp;</span><span class="lifetime">&#39;b</span> <span class="kw-2">mut</span> <span class="ident">R</span><span class="op">&lt;</span><span class="lifetime">&#39;c</span><span class="op">&gt;&gt;</span>(<span class="ident">r</span>)
}<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Astruct%20R%3C'a%3E(%26'a%20i32)%3B%0Aunsafe%20fn%20extend_lifetime%3C'b%3E(r%3A%20R%3C'b%3E)%20-%3E%20R%3C'static%3E%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3CR%3C'b%3E%2C%20R%3C'static%3E%3E(r)%0A%7D%0A%0Aunsafe%20fn%20shorten_invariant_lifetime%3C'b%2C%20'c%3E(r%3A%20%26'b%20mut%20R%3C'static%3E)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%3E%20%26'b%20mut%20R%3C'c%3E%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C%26'b%20mut%20R%3C'static%3E%2C%20%26'b%20mut%20R%3C'c%3E%3E(r)%0A%7D%0A%7D">Run</a></pre>

<h1 id='alternatives' class='section-header'><a href='#alternatives'>Alternatives</a></h1>
<p>Don&#39;t despair: many uses of <code>transmute</code> can be achieved through other means.
Below are common applications of <code>transmute</code> which can be replaced with safer
constructs.</p>

<p>Turning a pointer into a <code>usize</code>:</p>

<pre class="rust rust-example-rendered">
<span class="kw">let</span> <span class="ident">ptr</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="number">0</span>;
<span class="kw">let</span> <span class="ident">ptr_num_transmute</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">i32</span>, <span class="ident">usize</span><span class="op">&gt;</span>(<span class="ident">ptr</span>)
};

<span class="comment">// Use an `as` cast instead</span>
<span class="kw">let</span> <span class="ident">ptr_num_cast</span> <span class="op">=</span> <span class="ident">ptr</span> <span class="kw">as</span> <span class="kw-2">*</span><span class="kw">const</span> <span class="ident">i32</span> <span class="kw">as</span> <span class="ident">usize</span>;<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Alet%20ptr%20%3D%20%260%3B%0Alet%20ptr_num_transmute%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C%26i32%2C%20usize%3E(ptr)%0A%7D%3B%0A%0A%2F%2F%20Use%20an%20%60as%60%20cast%20instead%0Alet%20ptr_num_cast%20%3D%20ptr%20as%20*const%20i32%20as%20usize%3B%0A%7D">Run</a></pre>

<p>Turning a <code>*mut T</code> into an <code>&amp;mut T</code>:</p>

<pre class="rust rust-example-rendered">
<span class="kw">let</span> <span class="ident">ptr</span>: <span class="kw-2">*</span><span class="kw-2">mut</span> <span class="ident">i32</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="number">0</span>;
<span class="kw">let</span> <span class="ident">ref_transmuted</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">*</span><span class="kw-2">mut</span> <span class="ident">i32</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">i32</span><span class="op">&gt;</span>(<span class="ident">ptr</span>)
};

<span class="comment">// Use a reborrow instead</span>
<span class="kw">let</span> <span class="ident">ref_casted</span> <span class="op">=</span> <span class="kw">unsafe</span> { <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="kw-2">*</span><span class="ident">ptr</span> };<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Alet%20ptr%3A%20*mut%20i32%20%3D%20%26mut%200%3B%0Alet%20ref_transmuted%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C*mut%20i32%2C%20%26mut%20i32%3E(ptr)%0A%7D%3B%0A%0A%2F%2F%20Use%20a%20reborrow%20instead%0Alet%20ref_casted%20%3D%20unsafe%20%7B%20%26mut%20*ptr%20%7D%3B%0A%7D">Run</a></pre>

<p>Turning an <code>&amp;mut T</code> into an <code>&amp;mut U</code>:</p>

<pre class="rust rust-example-rendered">
<span class="kw">let</span> <span class="ident">ptr</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="number">0</span>;
<span class="kw">let</span> <span class="ident">val_transmuted</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">i32</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">u32</span><span class="op">&gt;</span>(<span class="ident">ptr</span>)
};

<span class="comment">// Now, put together `as` and reborrowing - note the chaining of `as`</span>
<span class="comment">// `as` is not transitive</span>
<span class="kw">let</span> <span class="ident">val_casts</span> <span class="op">=</span> <span class="kw">unsafe</span> { <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="kw-2">*</span>(<span class="ident">ptr</span> <span class="kw">as</span> <span class="kw-2">*</span><span class="kw-2">mut</span> <span class="ident">i32</span> <span class="kw">as</span> <span class="kw-2">*</span><span class="kw-2">mut</span> <span class="ident">u32</span>) };<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Alet%20ptr%20%3D%20%26mut%200%3B%0Alet%20val_transmuted%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C%26mut%20i32%2C%20%26mut%20u32%3E(ptr)%0A%7D%3B%0A%0A%2F%2F%20Now%2C%20put%20together%20%60as%60%20and%20reborrowing%20-%20note%20the%20chaining%20of%20%60as%60%0A%2F%2F%20%60as%60%20is%20not%20transitive%0Alet%20val_casts%20%3D%20unsafe%20%7B%20%26mut%20*(ptr%20as%20*mut%20i32%20as%20*mut%20u32)%20%7D%3B%0A%7D">Run</a></pre>

<p>Turning an <code>&amp;str</code> into an <code>&amp;[u8]</code>:</p>

<pre class="rust rust-example-rendered">
<span class="comment">// this is not a good way to do this.</span>
<span class="kw">let</span> <span class="ident">slice</span> <span class="op">=</span> <span class="kw">unsafe</span> { <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="kw-2">&amp;</span>[<span class="ident">u8</span>]<span class="op">&gt;</span>(<span class="string">&quot;Rust&quot;</span>) };
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">slice</span>, <span class="kw-2">&amp;</span>[<span class="number">82</span>, <span class="number">117</span>, <span class="number">115</span>, <span class="number">116</span>]);

<span class="comment">// You could use `str::as_bytes`</span>
<span class="kw">let</span> <span class="ident">slice</span> <span class="op">=</span> <span class="string">&quot;Rust&quot;</span>.<span class="ident">as_bytes</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">slice</span>, <span class="kw-2">&amp;</span>[<span class="number">82</span>, <span class="number">117</span>, <span class="number">115</span>, <span class="number">116</span>]);

<span class="comment">// Or, just use a byte string, if you have control over the string</span>
<span class="comment">// literal</span>
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="string">b&quot;Rust&quot;</span>, <span class="kw-2">&amp;</span>[<span class="number">82</span>, <span class="number">117</span>, <span class="number">115</span>, <span class="number">116</span>]);<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0A%2F%2F%20this%20is%20not%20a%20good%20way%20to%20do%20this.%0Alet%20slice%20%3D%20unsafe%20%7B%20std%3A%3Amem%3A%3Atransmute%3A%3A%3C%26str%2C%20%26%5Bu8%5D%3E(%22Rust%22)%20%7D%3B%0Aassert_eq!(slice%2C%20%26%5B82%2C%20117%2C%20115%2C%20116%5D)%3B%0A%0A%2F%2F%20You%20could%20use%20%60str%3A%3Aas_bytes%60%0Alet%20slice%20%3D%20%22Rust%22.as_bytes()%3B%0Aassert_eq!(slice%2C%20%26%5B82%2C%20117%2C%20115%2C%20116%5D)%3B%0A%0A%2F%2F%20Or%2C%20just%20use%20a%20byte%20string%2C%20if%20you%20have%20control%20over%20the%20string%0A%2F%2F%20literal%0Aassert_eq!(b%22Rust%22%2C%20%26%5B82%2C%20117%2C%20115%2C%20116%5D)%3B%0A%7D">Run</a></pre>

<p>Turning a <code>Vec&lt;&amp;T&gt;</code> into a <code>Vec&lt;Option&lt;&amp;T&gt;&gt;</code>:</p>

<pre class="rust rust-example-rendered">
<span class="kw">let</span> <span class="ident">store</span> <span class="op">=</span> [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">v_orig</span> <span class="op">=</span> <span class="ident">store</span>.<span class="ident">iter</span>().<span class="ident">collect</span>::<span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">i32</span><span class="op">&gt;&gt;</span>();

<span class="comment">// Using transmute: this is Undefined Behavior, and a bad idea.</span>
<span class="comment">// However, it is no-copy.</span>
<span class="kw">let</span> <span class="ident">v_transmuted</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">i32</span><span class="op">&gt;</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">i32</span><span class="op">&gt;&gt;</span><span class="op">&gt;</span>(
        <span class="ident">v_orig</span>.<span class="ident">clone</span>())
};

<span class="comment">// This is the suggested, safe way.</span>
<span class="comment">// It does copy the entire vector, though, into a new array.</span>
<span class="kw">let</span> <span class="ident">v_collected</span> <span class="op">=</span> <span class="ident">v_orig</span>.<span class="ident">clone</span>()
                        .<span class="ident">into_iter</span>()
                        .<span class="ident">map</span>(<span class="op">|</span><span class="ident">r</span><span class="op">|</span> <span class="prelude-val">Some</span>(<span class="ident">r</span>))
                        .<span class="ident">collect</span>::<span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">i32</span><span class="op">&gt;&gt;</span><span class="op">&gt;</span>();

<span class="comment">// The no-copy, unsafe way, still using transmute, but not UB.</span>
<span class="comment">// This is equivalent to the original, but safer, and reuses the</span>
<span class="comment">// same Vec internals. Therefore the new inner type must have the</span>
<span class="comment">// exact same size, and the same or lesser alignment, as the old</span>
<span class="comment">// type. The same caveats exist for this method as transmute, for</span>
<span class="comment">// the original inner type (`&amp;i32`) to the converted inner type</span>
<span class="comment">// (`Option&lt;&amp;i32&gt;`), so read the nomicon pages linked above.</span>
<span class="kw">let</span> <span class="ident">v_from_raw</span> <span class="op">=</span> <span class="kw">unsafe</span> {
    <span class="ident">Vec</span>::<span class="ident">from_raw_parts</span>(<span class="ident">v_orig</span>.<span class="ident">as_mut_ptr</span>(),
                        <span class="ident">v_orig</span>.<span class="ident">len</span>(),
                        <span class="ident">v_orig</span>.<span class="ident">capacity</span>())
};
<span class="ident">std</span>::<span class="ident">mem</span>::<span class="ident">forget</span>(<span class="ident">v_orig</span>);<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Alet%20store%20%3D%20%5B0%2C%201%2C%202%2C%203%5D%3B%0Alet%20mut%20v_orig%20%3D%20store.iter().collect%3A%3A%3CVec%3C%26i32%3E%3E()%3B%0A%0A%2F%2F%20Using%20transmute%3A%20this%20is%20Undefined%20Behavior%2C%20and%20a%20bad%20idea.%0A%2F%2F%20However%2C%20it%20is%20no-copy.%0Alet%20v_transmuted%20%3D%20unsafe%20%7B%0A%20%20%20%20std%3A%3Amem%3A%3Atransmute%3A%3A%3CVec%3C%26i32%3E%2C%20Vec%3COption%3C%26i32%3E%3E%3E(%0A%20%20%20%20%20%20%20%20v_orig.clone())%0A%7D%3B%0A%0A%2F%2F%20This%20is%20the%20suggested%2C%20safe%20way.%0A%2F%2F%20It%20does%20copy%20the%20entire%20vector%2C%20though%2C%20into%20a%20new%20array.%0Alet%20v_collected%20%3D%20v_orig.clone()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.into_iter()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.map(%7Cr%7C%20Some(r))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.collect%3A%3A%3CVec%3COption%3C%26i32%3E%3E%3E()%3B%0A%0A%2F%2F%20The%20no-copy%2C%20unsafe%20way%2C%20still%20using%20transmute%2C%20but%20not%20UB.%0A%2F%2F%20This%20is%20equivalent%20to%20the%20original%2C%20but%20safer%2C%20and%20reuses%20the%0A%2F%2F%20same%20Vec%20internals.%20Therefore%20the%20new%20inner%20type%20must%20have%20the%0A%2F%2F%20exact%20same%20size%2C%20and%20the%20same%20or%20lesser%20alignment%2C%20as%20the%20old%0A%2F%2F%20type.%20The%20same%20caveats%20exist%20for%20this%20method%20as%20transmute%2C%20for%0A%2F%2F%20the%20original%20inner%20type%20(%60%26i32%60)%20to%20the%20converted%20inner%20type%0A%2F%2F%20(%60Option%3C%26i32%3E%60)%2C%20so%20read%20the%20nomicon%20pages%20linked%20above.%0Alet%20v_from_raw%20%3D%20unsafe%20%7B%0A%20%20%20%20Vec%3A%3Afrom_raw_parts(v_orig.as_mut_ptr()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v_orig.len()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v_orig.capacity())%0A%7D%3B%0Astd%3A%3Amem%3A%3Aforget(v_orig)%3B%0A%7D">Run</a></pre>

<p>Implementing <code>split_at_mut</code>:</p>

<pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::{<span class="ident">slice</span>, <span class="ident">mem</span>};

<span class="comment">// There are multiple ways to do this; and there are multiple problems</span>
<span class="comment">// with the following, transmute, way.</span>
<span class="kw">fn</span> <span class="ident">split_at_mut_transmute</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="ident">slice</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="ident">mid</span>: <span class="ident">usize</span>)
                             <span class="op">-&gt;</span> (<span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>]) {
    <span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="ident">slice</span>.<span class="ident">len</span>();
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">mid</span> <span class="op">&lt;=</span> <span class="ident">len</span>);
    <span class="kw">unsafe</span> {
        <span class="kw">let</span> <span class="ident">slice2</span> <span class="op">=</span> <span class="ident">mem</span>::<span class="ident">transmute</span>::<span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>]<span class="op">&gt;</span>(<span class="ident">slice</span>);
        <span class="comment">// first: transmute is not typesafe; all it checks is that T and</span>
        <span class="comment">// U are of the same size. Second, right here, you have two</span>
        <span class="comment">// mutable references pointing to the same memory.</span>
        (<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">slice</span>[<span class="number">0</span>..<span class="ident">mid</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">slice2</span>[<span class="ident">mid</span>..<span class="ident">len</span>])
    }
}

<span class="comment">// This gets rid of the typesafety problems; `&amp;mut *` will *only* give</span>
<span class="comment">// you an `&amp;mut T` from an `&amp;mut T` or `*mut T`.</span>
<span class="kw">fn</span> <span class="ident">split_at_mut_casts</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="ident">slice</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="ident">mid</span>: <span class="ident">usize</span>)
                         <span class="op">-&gt;</span> (<span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>]) {
    <span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="ident">slice</span>.<span class="ident">len</span>();
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">mid</span> <span class="op">&lt;=</span> <span class="ident">len</span>);
    <span class="kw">unsafe</span> {
        <span class="kw">let</span> <span class="ident">slice2</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="kw-2">*</span>(<span class="ident">slice</span> <span class="kw">as</span> <span class="kw-2">*</span><span class="kw-2">mut</span> [<span class="ident">T</span>]);
        <span class="comment">// however, you still have two mutable references pointing to</span>
        <span class="comment">// the same memory.</span>
        (<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">slice</span>[<span class="number">0</span>..<span class="ident">mid</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">slice2</span>[<span class="ident">mid</span>..<span class="ident">len</span>])
    }
}

<span class="comment">// This is how the standard library does it. This is the best method, if</span>
<span class="comment">// you need to do something like this</span>
<span class="kw">fn</span> <span class="ident">split_at_stdlib</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="ident">slice</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="ident">mid</span>: <span class="ident">usize</span>)
                      <span class="op">-&gt;</span> (<span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>], <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">T</span>]) {
    <span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="ident">slice</span>.<span class="ident">len</span>();
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">mid</span> <span class="op">&lt;=</span> <span class="ident">len</span>);
    <span class="kw">unsafe</span> {
        <span class="kw">let</span> <span class="ident">ptr</span> <span class="op">=</span> <span class="ident">slice</span>.<span class="ident">as_mut_ptr</span>();
        <span class="comment">// This now has three mutable references pointing at the same</span>
        <span class="comment">// memory. `slice`, the rvalue ret.0, and the rvalue ret.1.</span>
        <span class="comment">// `slice` is never used after `let ptr = ...`, and so one can</span>
        <span class="comment">// treat it as &quot;dead&quot;, and therefore, you only have two real</span>
        <span class="comment">// mutable slices.</span>
        (<span class="ident">slice</span>::<span class="ident">from_raw_parts_mut</span>(<span class="ident">ptr</span>, <span class="ident">mid</span>),
         <span class="ident">slice</span>::<span class="ident">from_raw_parts_mut</span>(<span class="ident">ptr</span>.<span class="ident">offset</span>(<span class="ident">mid</span> <span class="kw">as</span> <span class="ident">isize</span>), <span class="ident">len</span> <span class="op">-</span> <span class="ident">mid</span>))
    }
}<a class="test-arrow" target="_blank" href="https://play.rust-lang.org/?code=fn%20main()%20%7B%0Ause%20std%3A%3A%7Bslice%2C%20mem%7D%3B%0A%0A%2F%2F%20There%20are%20multiple%20ways%20to%20do%20this%3B%20and%20there%20are%20multiple%20problems%0A%2F%2F%20with%20the%20following%2C%20transmute%2C%20way.%0Afn%20split_at_mut_transmute%3CT%3E(slice%3A%20%26mut%20%5BT%5D%2C%20mid%3A%20usize)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%3E%20(%26mut%20%5BT%5D%2C%20%26mut%20%5BT%5D)%20%7B%0A%20%20%20%20let%20len%20%3D%20slice.len()%3B%0A%20%20%20%20assert!(mid%20%3C%3D%20len)%3B%0A%20%20%20%20unsafe%20%7B%0A%20%20%20%20%20%20%20%20let%20slice2%20%3D%20mem%3A%3Atransmute%3A%3A%3C%26mut%20%5BT%5D%2C%20%26mut%20%5BT%5D%3E(slice)%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20first%3A%20transmute%20is%20not%20typesafe%3B%20all%20it%20checks%20is%20that%20T%20and%0A%20%20%20%20%20%20%20%20%2F%2F%20U%20are%20of%20the%20same%20size.%20Second%2C%20right%20here%2C%20you%20have%20two%0A%20%20%20%20%20%20%20%20%2F%2F%20mutable%20references%20pointing%20to%20the%20same%20memory.%0A%20%20%20%20%20%20%20%20(%26mut%20slice%5B0..mid%5D%2C%20%26mut%20slice2%5Bmid..len%5D)%0A%20%20%20%20%7D%0A%7D%0A%0A%2F%2F%20This%20gets%20rid%20of%20the%20typesafety%20problems%3B%20%60%26mut%20*%60%20will%20*only*%20give%0A%2F%2F%20you%20an%20%60%26mut%20T%60%20from%20an%20%60%26mut%20T%60%20or%20%60*mut%20T%60.%0Afn%20split_at_mut_casts%3CT%3E(slice%3A%20%26mut%20%5BT%5D%2C%20mid%3A%20usize)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%3E%20(%26mut%20%5BT%5D%2C%20%26mut%20%5BT%5D)%20%7B%0A%20%20%20%20let%20len%20%3D%20slice.len()%3B%0A%20%20%20%20assert!(mid%20%3C%3D%20len)%3B%0A%20%20%20%20unsafe%20%7B%0A%20%20%20%20%20%20%20%20let%20slice2%20%3D%20%26mut%20*(slice%20as%20*mut%20%5BT%5D)%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20however%2C%20you%20still%20have%20two%20mutable%20references%20pointing%20to%0A%20%20%20%20%20%20%20%20%2F%2F%20the%20same%20memory.%0A%20%20%20%20%20%20%20%20(%26mut%20slice%5B0..mid%5D%2C%20%26mut%20slice2%5Bmid..len%5D)%0A%20%20%20%20%7D%0A%7D%0A%0A%2F%2F%20This%20is%20how%20the%20standard%20library%20does%20it.%20This%20is%20the%20best%20method%2C%20if%0A%2F%2F%20you%20need%20to%20do%20something%20like%20this%0Afn%20split_at_stdlib%3CT%3E(slice%3A%20%26mut%20%5BT%5D%2C%20mid%3A%20usize)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%3E%20(%26mut%20%5BT%5D%2C%20%26mut%20%5BT%5D)%20%7B%0A%20%20%20%20let%20len%20%3D%20slice.len()%3B%0A%20%20%20%20assert!(mid%20%3C%3D%20len)%3B%0A%20%20%20%20unsafe%20%7B%0A%20%20%20%20%20%20%20%20let%20ptr%20%3D%20slice.as_mut_ptr()%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20This%20now%20has%20three%20mutable%20references%20pointing%20at%20the%20same%0A%20%20%20%20%20%20%20%20%2F%2F%20memory.%20%60slice%60%2C%20the%20rvalue%20ret.0%2C%20and%20the%20rvalue%20ret.1.%0A%20%20%20%20%20%20%20%20%2F%2F%20%60slice%60%20is%20never%20used%20after%20%60let%20ptr%20%3D%20...%60%2C%20and%20so%20one%20can%0A%20%20%20%20%20%20%20%20%2F%2F%20treat%20it%20as%20%22dead%22%2C%20and%20therefore%2C%20you%20only%20have%20two%20real%0A%20%20%20%20%20%20%20%20%2F%2F%20mutable%20slices.%0A%20%20%20%20%20%20%20%20(slice%3A%3Afrom_raw_parts_mut(ptr%2C%20mid)%2C%0A%20%20%20%20%20%20%20%20%20slice%3A%3Afrom_raw_parts_mut(ptr.offset(mid%20as%20isize)%2C%20len%20-%20mid))%0A%20%20%20%20%7D%0A%7D%0A%7D">Run</a></pre>
</div></section>
    <section id='search' class="content hidden"></section>

    <section class="footer"></section>

    <aside id="help" class="hidden">
        <div>
            <h1 class="hidden">Help</h1>

            <div class="shortcuts">
                <h2>Keyboard Shortcuts</h2>

                <dl>
                    <dt>?</dt>
                    <dd>Show this help dialog</dd>
                    <dt>S</dt>
                    <dd>Focus the search field</dd>
                    <dt>&larrb;</dt>
                    <dd>Move up in search results</dd>
                    <dt>&rarrb;</dt>
                    <dd>Move down in search results</dd>
                    <dt>&#9166;</dt>
                    <dd>Go to active search result</dd>
                    <dt>+</dt>
                    <dd>Collapse/expand all sections</dd>
                </dl>
            </div>

            <div class="infos">
                <h2>Search Tricks</h2>

                <p>
                    Prefix searches with a type followed by a colon (e.g.
                    <code>fn:</code>) to restrict the search to a given type.
                </p>

                <p>
                    Accepted types are: <code>fn</code>, <code>mod</code>,
                    <code>struct</code>, <code>enum</code>,
                    <code>trait</code>, <code>type</code>, <code>macro</code>,
                    and <code>const</code>.
                </p>

                <p>
                    Search functions by type signature (e.g.
                    <code>vec -> usize</code> or <code>* -> vec</code>)
                </p>
            </div>
        </div>
    </aside>

    

    <script>
        window.rootPath = "../../";
        window.currentCrate = "core";
    </script>
    <script src="../../main.js"></script>
    <script defer src="../../search-index.js"></script>
</body>
</html>