Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 4e2dbb669434a7691662cb2f0ad38972 > files > 13629

rust-doc-1.28.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 `std`."><meta name="keywords" content="rust, rustlang, rust-lang, transmute"><title>std::mem::transmute - Rust</title><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../dark.css"><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><script src="../../storage.js"></script><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"><div class="sidebar-menu">&#9776;</div><a href='../../std/index.html'><img src='https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png' alt='logo' width='100'></a><div class="sidebar-elems"><p class='location'><a href='../index.html'>std</a>::<wbr><a href='index.html'>mem</a></p><script>window.sidebarCurrent = {name: 'transmute', ty: 'fn', relpath: ''};</script><script defer src="sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></div></div><script src="../../theme.js"></script><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"><a id="settings-menu" href="../../settings.html"><img src="../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class='fqn'><span class='in-band'>Function <a href='../index.html'>std</a>::<wbr><a href='index.html'>mem</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#926' 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/what-unsafe-does.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's equivalent to C'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'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=%23!%5Ballow(unused)%5D%0Afn%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=%23!%5Ballow(unused)%5D%0Afn%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=%23!%5Ballow(unused)%5D%0Afn%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'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=%23!%5Ballow(unused)%5D%0Afn%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=%23!%5Ballow(unused)%5D%0Afn%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=%23!%5Ballow(unused)%5D%0Afn%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=%23!%5Ballow(unused)%5D%0Afn%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 alignment, as the old type.</span>
<span class="comment">// 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="kw">as</span> <span class="kw-2">*</span><span class="kw-2">mut</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;</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=%23!%5Ballow(unused)%5D%0Afn%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%20alignment%2C%20as%20the%20old%20type.%0A%2F%2F%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()%20as%20*mut%20Option%3C%26i32%3E%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=%23!%5Ballow(unused)%5D%0Afn%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><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd>↑</kbd></dt><dd>Move up in search results</dd><dt><kbd>↓</kbd></dt><dd>Move down in search results</dd><dt><kbd>↹</kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse 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><p>Search multiple things at once by splitting your query with comma (e.g. <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../";window.currentCrate = "std";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>