rtic/2/api/stable_deref_trait/trait.StableDeref.html
2024-10-24 05:57:30 +00:00

59 lines
No EOL
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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="An unsafe marker trait for types that deref to a stable address, even when moved. For example, this is implemented by Box, Vec, Rc, Arc and String, among others. Even when a Box is moved, the underlying storage remains at a fixed location."><title>StableDeref in stable_deref_trait - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans-Medium-8f9a781e4970d388.woff2,SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2,SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../static.files/rustdoc-492a78a4a87dcc01.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="stable_deref_trait" data-themes="" data-resource-suffix="" data-rustdoc-version="1.82.0 (f6e511eec 2024-10-15)" data-channel="1.82.0" data-search-js="search-a99f1315e7cc5121.js" data-settings-js="settings-4313503d2e1961c2.js" ><script src="../static.files/storage-118b08c4c78b968e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-921df33f47b8780c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-3b12f09e550e0385.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc trait"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../stable_deref_trait/index.html">stable_<wbr>deref_<wbr>trait</a><span class="version">1.2.0</span></h2></div><h2 class="location"><a href="#">Stable<wbr>Deref</a></h2><div class="sidebar-elems"><section><h3><a href="#foreign-impls">Implementations on Foreign Types</a></h3><ul class="block"><li><a href="#impl-StableDeref-for-%26T">&#38;&#39;a T</a></li><li><a href="#impl-StableDeref-for-%26mut+T">&#38;&#39;a mut T</a></li><li><a href="#impl-StableDeref-for-Ref%3C'a,+T%3E">Ref&#60;&#39;a, T&#62;</a></li><li><a href="#impl-StableDeref-for-RefMut%3C'a,+T%3E">RefMut&#60;&#39;a, T&#62;</a></li></ul><h3><a href="#implementors">Implementors</a></h3></section><h2><a href="index.html">In crate stable_<wbr>deref_<wbr>trait</a></h2></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Trait <a href="index.html">stable_deref_trait</a>::<wbr><a class="trait" href="#">StableDeref</a><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><span class="out-of-band"><a class="src" href="../src/stable_deref_trait/lib.rs.html#122">source</a> · <button id="toggle-all-docs" title="collapse all docs">[<span>&#x2212;</span>]</button></span></div><pre class="rust item-decl"><code>pub unsafe trait StableDeref: <a class="trait" href="https://doc.rust-lang.org/1.82.0/core/ops/deref/trait.Deref.html" title="trait core::ops::deref::Deref">Deref</a> { }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>An unsafe marker trait for types that deref to a stable address, even when moved. For example, this is implemented by Box, Vec, Rc, Arc and String, among others. Even when a Box is moved, the underlying storage remains at a fixed location.</p>
<p>More specifically, implementors must ensure that the result of calling deref() is valid for the lifetime of the object, not just the lifetime of the borrow, and that the deref is valid even if the object is moved. Also, it must be valid even after invoking arbitrary &amp;self methods or doing anything transitively accessible from &amp;Self. If Self also implements DerefMut, the same restrictions apply to deref_mut() and it must remain valid if anything transitively accessible from the result of deref_mut() is mutated/called. Additionally, multiple calls to deref, (and deref_mut if implemented) must return the same address. No requirements are placed on &amp;mut self methods other than deref_mut() and drop(), if applicable.</p>
<p>Basically, it must be valid to convert the result of deref() to a pointer, and later dereference that pointer, as long as the original object is still live, even if it has been moved or &amp;self methods have been called on it. If DerefMut is also implemented, it must be valid to get pointers from deref() and deref_mut() and dereference them while the object is live, as long as you dont simultaneously dereference both of them.</p>
<p>Additionally, Deref and DerefMut implementations must not panic, but users of the trait are not allowed to rely on this fact (so that this restriction can be removed later without breaking backwards compatibility, should the need arise).</p>
<p>Here are some examples to help illustrate the requirements for implementing this trait:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Foo(u8);
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = u8;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target { <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0 </span>}
}</code></pre></div>
<p>Foo cannot implement StableDeref because the int will move when Foo is moved, invalidating the result of deref().</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Foo(Box&lt;u8&gt;);
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = u8;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target { <span class="kw-2">&amp;*</span><span class="self">self</span>.<span class="number">0 </span>}
}</code></pre></div>
<p>Foo can safely implement StableDeref, due to the use of Box.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(Clone)]
</span><span class="kw">struct </span>Foo(Rc&lt;u8&gt;);
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = u8;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target { <span class="kw-2">&amp;*</span><span class="self">self</span>.<span class="number">0 </span>}
}
<span class="kw">impl </span>DerefMut <span class="kw">for </span>Foo {
<span class="kw">fn </span>deref_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span><span class="self">Self</span>::Target { Rc::make_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0</span>) }
}</code></pre></div>
<p>This is a simple implementation of copy-on-write: Foos deref_mut will copy the underlying int if it is not uniquely owned, ensuring unique access at the point where deref_mut() returns. However, Foo cannot implement StableDeref because calling deref_mut(), followed by clone().deref() will result in mutable and immutable references to the same location. Note that if the DerefMut implementation were removed, Foo could safely implement StableDeref. Likewise, if the Clone implementation were removed, it would be safe to implement StableDeref, although Foo would not be very useful in that case, (without clones, the rc will always be uniquely owned).</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Foo;
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = str;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target { <span class="kw-2">&amp;</span><span class="string">"Hello" </span>}
}</code></pre></div>
<p>Foo can safely implement StableDeref. It doesnt own the data being derefed, but the data is gaurenteed to live long enough, due to it being static.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Foo(Cell&lt;bool&gt;);
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = str;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target {
<span class="kw">let </span>b = <span class="self">self</span>.<span class="number">0</span>.get();
<span class="self">self</span>.<span class="number">0</span>.set(!b);
<span class="kw">if </span>b { <span class="kw-2">&amp;</span><span class="string">"Hello" </span>} <span class="kw">else </span>{ <span class="kw-2">&amp;</span><span class="string">"World" </span>}
}
}</code></pre></div>
<p>Foo cannot safely implement StableDeref, even though every possible result of deref lives long enough. In order to safely implement StableAddress, multiple calls to deref must return the same result.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Foo(Box&lt;(u8, u8)&gt;);
<span class="kw">impl </span>Deref <span class="kw">for </span>Foo {
<span class="kw">type </span>Target = u8;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="self">Self</span>::Target { <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>.deref().<span class="number">0 </span>}
}
<span class="kw">impl </span>DerefMut <span class="kw">for </span>Foo {
<span class="kw">fn </span>deref_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span><span class="self">Self</span>::Target { <span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0</span>.deref_mut().<span class="number">1 </span>}
}</code></pre></div>
<p>Foo cannot implement StableDeref because deref and deref_mut return different addresses.</p>
</div></details><h2 id="foreign-impls" class="section-header">Implementations on Foreign Types<a href="#foreign-impls" class="anchor">§</a></h2><section id="impl-StableDeref-for-%26T" class="impl"><a class="src rightside" href="../src/stable_deref_trait/lib.rs.html#187">source</a><a href="#impl-StableDeref-for-%26T" class="anchor">§</a><h3 class="code-header">impl&lt;'a, T: ?<a class="trait" href="https://doc.rust-lang.org/1.82.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>&gt; <a class="trait" href="trait.StableDeref.html" title="trait stable_deref_trait::StableDeref">StableDeref</a> for <a class="primitive" href="https://doc.rust-lang.org/1.82.0/core/primitive.reference.html">&amp;'a T</a></h3></section><section id="impl-StableDeref-for-%26mut+T" class="impl"><a class="src rightside" href="../src/stable_deref_trait/lib.rs.html#189">source</a><a href="#impl-StableDeref-for-%26mut+T" class="anchor">§</a><h3 class="code-header">impl&lt;'a, T: ?<a class="trait" href="https://doc.rust-lang.org/1.82.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>&gt; <a class="trait" href="trait.StableDeref.html" title="trait stable_deref_trait::StableDeref">StableDeref</a> for <a class="primitive" href="https://doc.rust-lang.org/1.82.0/core/primitive.reference.html">&amp;'a mut T</a></h3></section><section id="impl-StableDeref-for-Ref%3C'a,+T%3E" class="impl"><a class="src rightside" href="../src/stable_deref_trait/lib.rs.html#178">source</a><a href="#impl-StableDeref-for-Ref%3C'a,+T%3E" class="anchor">§</a><h3 class="code-header">impl&lt;'a, T: ?<a class="trait" href="https://doc.rust-lang.org/1.82.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>&gt; <a class="trait" href="trait.StableDeref.html" title="trait stable_deref_trait::StableDeref">StableDeref</a> for <a class="struct" href="https://doc.rust-lang.org/1.82.0/core/cell/struct.Ref.html" title="struct core::cell::Ref">Ref</a>&lt;'a, T&gt;</h3></section><section id="impl-StableDeref-for-RefMut%3C'a,+T%3E" class="impl"><a class="src rightside" href="../src/stable_deref_trait/lib.rs.html#179">source</a><a href="#impl-StableDeref-for-RefMut%3C'a,+T%3E" class="anchor">§</a><h3 class="code-header">impl&lt;'a, T: ?<a class="trait" href="https://doc.rust-lang.org/1.82.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>&gt; <a class="trait" href="trait.StableDeref.html" title="trait stable_deref_trait::StableDeref">StableDeref</a> for <a class="struct" href="https://doc.rust-lang.org/1.82.0/core/cell/struct.RefMut.html" title="struct core::cell::RefMut">RefMut</a>&lt;'a, T&gt;</h3></section><h2 id="implementors" class="section-header">Implementors<a href="#implementors" class="anchor">§</a></h2><div id="implementors-list"></div><script src="../trait.impl/stable_deref_trait/trait.StableDeref.js" data-ignore-extern-crates="core" async></script></section></div></main></body></html>