Files
GopherGate/target/doc/zerocopy/macro.transmute_ref.html
2026-02-26 12:00:21 -05:00

85 lines
10 KiB
HTML

<!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="Safely transmutes a mutable or immutable reference of one type to an immutable reference of another type of the same size and compatible alignment."><title>transmute_ref in zerocopy - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="zerocopy" data-themes="" data-resource-suffix="" data-rustdoc-version="1.93.1 (01f6ddf75 2026-02-11) (Arch Linux rust 1:1.93.1-1)" data-channel="1.93.1" data-search-js="search-9e2438ea.js" data-stringdex-js="stringdex-a3946164.js" data-settings-js="settings-c38705f0.js" ><script src="../static.files/storage-e2aeef58.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-a410ff4d.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc macro"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">transmute_ref</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../zerocopy/index.html">zerocopy</a><span class="version">0.8.39</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">transmute_<wbr>ref</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#size-compatibility" title="Size compatibility">Size compatibility</a></li><li><a href="#errors" title="Errors">Errors</a></li><li><a href="#examples" title="Examples">Examples</a></li><li><a href="#use-in-const-contexts" title="Use in `const` contexts">Use in <code>const</code> contexts</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate zerocopy</a></h2></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">zerocopy</a></div><h1>Macro <span class="macro">transmute_<wbr>ref</span>&nbsp;<button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/zerocopy/macros.rs.html#316-381">Source</a> </span></div><pre class="rust item-decl"><code>macro_rules! transmute_ref {
($e:expr) =&gt; { ... };
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Safely transmutes a mutable or immutable reference of one type to an
immutable reference of another type of the same size and compatible
alignment.</p>
<p>This macro behaves like an invocation of this function:</p>
<div class="example-wrap ignore"><a href="#" class="tooltip" title="This example is not tested"></a><pre class="rust rust-example-rendered"><code><span class="kw">fn </span>transmute_ref&lt;<span class="lifetime">'src</span>, <span class="lifetime">'dst</span>, Src, Dst&gt;(src: <span class="kw-2">&amp;</span><span class="lifetime">'src </span>Src) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'dst </span>Dst
<span class="kw">where
</span><span class="lifetime">'src</span>: <span class="lifetime">'dst</span>,
Src: IntoBytes + Immutable + <span class="question-mark">?</span>Sized,
Dst: FromBytes + Immutable + <span class="question-mark">?</span>Sized,
align_of::&lt;Src&gt;() &gt;= align_of::&lt;Dst&gt;(),
size_compatible::&lt;Src, Dst&gt;(),
{
...
}</code></pre></div>
<p>The types <code>Src</code> and <code>Dst</code> are inferred from the calling context; they cannot
be explicitly specified in the macro invocation.</p>
<h2 id="size-compatibility"><a class="doc-anchor" href="#size-compatibility">§</a>Size compatibility</h2>
<p><code>transmute_ref!</code> supports transmuting between <code>Sized</code> types, between unsized
(i.e., <code>?Sized</code>) types, and from a <code>Sized</code> type to an unsized type. It
supports any transmutation that preserves the number of bytes of the
referent, even if doing so requires updating the metadata stored in an
unsized “fat” reference:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">let </span>src: <span class="kw-2">&amp;</span>[[u8; <span class="number">2</span>]] = <span class="kw-2">&amp;</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>dst: <span class="kw-2">&amp;</span>[u8] = <span class="macro">transmute_ref!</span>(src);
<span class="macro">assert_eq!</span>(src.len(), <span class="number">2</span>);
<span class="macro">assert_eq!</span>(dst.len(), <span class="number">4</span>);
<span class="macro">assert_eq!</span>(dst, [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);
<span class="macro">assert_eq!</span>(size_of_val(src), size_of_val(dst));</code></pre></div><h2 id="errors"><a class="doc-anchor" href="#errors">§</a>Errors</h2>
<p>Violations of the alignment and size compatibility checks are detected
<em>after</em> the compiler performs monomorphization. This has two important
consequences.</p>
<p>First, it means that generic code will <em>never</em> fail these conditions:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">fn </span>transmute_ref&lt;Src, Dst&gt;(src: <span class="kw-2">&amp;</span>Src) -&gt; <span class="kw-2">&amp;</span>Dst
<span class="kw">where
</span>Src: IntoBytes + Immutable,
Dst: FromBytes + Immutable,
{
<span class="macro">transmute_ref!</span>(src)
}</code></pre></div>
<p>Instead, failures will only be detected once generic code is instantiated
with concrete types:</p>
<div class="example-wrap compile_fail"><a href="#" class="tooltip" title="This example deliberately fails to compile"></a><pre class="rust rust-example-rendered"><code><span class="kw">let </span>src: <span class="kw-2">&amp;</span>u16 = <span class="kw-2">&amp;</span><span class="number">0</span>;
<span class="kw">let </span>dst: <span class="kw-2">&amp;</span>u8 = transmute_ref(src);</code></pre></div>
<p>Second, the fact that violations are detected after monomorphization means
that <code>cargo check</code> will usually not detect errors, even when types are
concrete. Instead, <code>cargo build</code> must be used to detect such errors.</p>
<h2 id="examples"><a class="doc-anchor" href="#examples">§</a>Examples</h2>
<p>Transmuting between <code>Sized</code> types:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">let </span>one_dimensional: [u8; <span class="number">8</span>] = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>];
<span class="kw">let </span>two_dimensional: <span class="kw-2">&amp;</span>[[u8; <span class="number">4</span>]; <span class="number">2</span>] = <span class="macro">transmute_ref!</span>(<span class="kw-2">&amp;</span>one_dimensional);
<span class="macro">assert_eq!</span>(two_dimensional, <span class="kw-2">&amp;</span>[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]]);</code></pre></div>
<p>Transmuting between unsized types:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
#[repr(C)]
</span><span class="kw">struct </span>SliceDst&lt;T, U&gt; {
t: T,
u: [U],
}
<span class="kw">type </span>Src = SliceDst&lt;u32, u16&gt;;
<span class="kw">type </span>Dst = SliceDst&lt;u16, u8&gt;;
<span class="kw">let </span>src = Src::ref_from_bytes(<span class="kw-2">&amp;</span>[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]).unwrap();
<span class="kw">let </span>dst: <span class="kw-2">&amp;</span>Dst = <span class="macro">transmute_ref!</span>(src);
<span class="macro">assert_eq!</span>(src.t.as_bytes(), [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);
<span class="macro">assert_eq!</span>(src.u.len(), <span class="number">2</span>);
<span class="macro">assert_eq!</span>(src.u.as_bytes(), [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]);
<span class="macro">assert_eq!</span>(dst.t.as_bytes(), [<span class="number">0</span>, <span class="number">1</span>]);
<span class="macro">assert_eq!</span>(dst.u, [<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]);</code></pre></div><h2 id="use-in-const-contexts"><a class="doc-anchor" href="#use-in-const-contexts">§</a>Use in <code>const</code> contexts</h2>
<p>This macro can be invoked in <code>const</code> contexts only when <code>Src: Sized</code> and
<code>Dst: Sized</code>.</p>
</div></details></section></div></main></body></html>