Initial docs commit

This commit is contained in:
Uttarayan Mondal
2021-03-15 01:27:34 +05:30
commit d5ecda4c73
20211 changed files with 1370362 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
<!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="List of all items in this crate"><meta name="keywords" content="rust, rustlang, rust-lang"><title>List of all items in this crate</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="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[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='../pin_project/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><p class="location">Crate pin_project</p><div class="block version"><p>Version 1.0.5</p></div><a id="all-types" href="index.html"><p>Back to index</p></a></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<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">List of all items</span><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span>
</span>
<span class="in-band">List of all items</span></h1><h3 id="Traits">Traits</h3><ul class="traits docblock"><li><a href="trait.UnsafeUnpin.html">UnsafeUnpin</a></li></ul><h3 id="Attribute Macros">Attribute Macros</h3><ul class="attributes docblock"><li><a href="attr.pin_project.html">pin_project</a></li><li><a href="attr.pinned_drop.html">pinned_drop</a></li></ul></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="pin_project"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>
+372
View File
@@ -0,0 +1,372 @@
<!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 attribute that creates projection types covering all the fields of struct or enum."><meta name="keywords" content="rust, rustlang, rust-lang, pin_project"><title>pin_project::pin_project - 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="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc attr"><!--[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='../pin_project/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><div class="sidebar-elems"><p class="location"><a href="index.html">pin_project</a></p><div id="sidebar-vars" data-name="pin_project" data-ty="attr" data-relpath=""></div><script defer src="sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<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">Attribute Macro <a href="index.html">pin_project</a>::<wbr><a class="attr" href="">pin_project</a></span><span class="out-of-band"><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/pin_project_internal/lib.rs.html#486" title="goto source code">[src]</a></span></h1><pre class="rust attr">#[pin_project]</pre><div class="docblock"><p>An attribute that creates projection types covering all the fields of
struct or enum.</p>
<p>This attribute creates projection types according to the following rules:</p>
<ul>
<li>For the fields that use <code>#[pin]</code> attribute, create the pinned reference to
the field.</li>
<li>For the other fields, create a normal reference to the field.</li>
</ul>
<p>And the following methods are implemented on the original type:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">project</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Projection</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>;
<span class="kw">fn</span> <span class="ident">project_ref</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="self">Self</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ProjectionRef</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>;</pre></div>
<p>By passing an argument with the same name as the method to the attribute,
you can name the projection type returned from the method. This allows you
to use pattern matching on the projected types.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">project</span> <span class="op">=</span> <span class="ident">EnumProj</span>)]</span>
<span class="kw">enum</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">Variant</span>(<span class="attribute">#[<span class="ident">pin</span>]</span> <span class="ident">T</span>),
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">this</span>: <span class="ident">EnumProj</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span>, <span class="ident">T</span><span class="op">&gt;</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project</span>();
<span class="kw">match</span> <span class="ident">this</span> {
<span class="ident">EnumProj</span>::<span class="ident">Variant</span>(<span class="ident">x</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">x</span>;
}
}
}
}</pre></div>
<p>Note that the projection types returned by <code>project</code> and <code>project_ref</code> have
an additional lifetime at the beginning of generics.</p>
<pre><code class="language-text">let this: EnumProj&lt;'_, T&gt; = self.project();
^^
</code></pre>
<p>The visibility of the projected types and projection methods is based on the
original type. However, if the visibility of the original type is <code>pub</code>, the
visibility of the projected types and the projection methods is downgraded
to <code>pub(crate)</code>.</p>
<h1 id="safety" class="section-header"><a href="#safety">Safety</a></h1>
<p>This attribute is completely safe. In the absence of other <code>unsafe</code> code
<em>that you write</em>, it is impossible to cause <a href="https://doc.rust-lang.org/reference/behavior-considered-undefined.html">undefined
behavior</a> with this attribute.</p>
<p>This is accomplished by enforcing the four requirements for pin projection
stated in <a href="https://doc.rust-lang.org/nightly/core/pin/index.html#projections-and-structural-pinning">the Rust documentation</a>:</p>
<ol>
<li>
<p>The struct must only be <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> if all the structural fields are
<a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
<p>To enforce this, this attribute will automatically generate an <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>
implementation for you, which will require that all structurally pinned
fields be <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
<p>If you attempt to provide an <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl, the blanket impl will then
apply to your type, causing a compile-time error due to the conflict with
the second impl.</p>
<p>If you wish to provide a manual <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl, you can do so via the
<a href="../pin_project/attr.pin_project.html#unsafeunpin"><code>UnsafeUnpin</code></a> argument.</p>
</li>
<li>
<p>The destructor of the struct must not move structural fields out of its
argument.</p>
<p>To enforce this, this attribute will generate code like this:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">struct</span> <span class="ident">MyStruct</span> {}
<span class="kw">trait</span> <span class="ident">MyStructMustNotImplDrop</span> {}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Drop</span><span class="op">&gt;</span> <span class="ident">MyStructMustNotImplDrop</span> <span class="kw">for</span> <span class="ident">T</span> {}
<span class="kw">impl</span> <span class="ident">MyStructMustNotImplDrop</span> <span class="kw">for</span> <span class="ident">MyStruct</span> {}</pre></div>
<p>If you attempt to provide an <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl, the blanket impl will then
apply to your type, causing a compile-time error due to the conflict with
the second impl.</p>
<p>If you wish to provide a custom <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl, you can annotate an impl
with <a href="../pin_project/attr.pin_project.html#pinned_drop"><code>#[pinned_drop]</code></a>. This impl takes a pinned version of
your struct - that is, <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a><code>&lt;&amp;mut MyStruct&gt;</code> where <code>MyStruct</code> is the
type of your struct.</p>
<p>You can call <code>.project()</code> on this type as usual, along with any other
methods you have defined. Because your code is never provided with
a <code>&amp;mut MyStruct</code>, it is impossible to move out of pin-projectable
fields in safe code in your destructor.</p>
</li>
<li>
<p>You must make sure that you uphold the <a href="https://doc.rust-lang.org/nightly/core/pin/index.html#drop-guarantee"><code>Drop</code>
guarantee</a>: once your struct is pinned, the memory that
contains the content is not overwritten or deallocated without calling
the contents destructors.</p>
<p>Safe code doesnt need to worry about this - the only way to violate
this requirement is to manually deallocate memory (which is <code>unsafe</code>),
or to overwrite a field with something else.
Because your custom destructor takes <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a><code>&lt;&amp;mut MyStruct&gt;</code>, its
impossible to obtain a mutable reference to a pin-projected field in safe
code.</p>
</li>
<li>
<p>You must not offer any other operations that could lead to data being
moved out of the structural fields when your type is pinned.</p>
<p>As with requirement 3, it is impossible for safe code to violate this.
This crate ensures that safe code can never obtain a mutable reference to
<code>#[pin]</code> fields, which prevents you from ever moving out of them in safe
code.</p>
</li>
</ol>
<p>Pin projections are also incompatible with <a href="https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked"><code>#[repr(packed)]</code></a>
types. Attempting to use this attribute on a <code>#[repr(packed)]</code> type results
in a compile-time error.</p>
<h1 id="examples" class="section-header"><a href="#examples">Examples</a></h1>
<p><code>#[pin_project]</code> can be used on structs and enums.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned</span>: <span class="ident">T</span>,
<span class="ident">unpinned</span>: <span class="ident">U</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">this</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project</span>();
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">pinned</span>;
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">U</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">unpinned</span>;
}
}</pre></div>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>]</span>
<span class="kw">struct</span> <span class="ident">TupleStruct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span>(<span class="attribute">#[<span class="ident">pin</span>]</span> <span class="ident">T</span>, <span class="ident">U</span>);
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">TupleStruct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">this</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project</span>();
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">this</span>.<span class="number">0</span>;
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">U</span> <span class="op">=</span> <span class="ident">this</span>.<span class="number">1</span>;
}
}</pre></div>
<p>To use <code>#[pin_project]</code> on enums, you need to name the projection type
returned from the method.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">project</span> <span class="op">=</span> <span class="ident">EnumProj</span>)]</span>
<span class="kw">enum</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="ident">Tuple</span>(<span class="attribute">#[<span class="ident">pin</span>]</span> <span class="ident">T</span>),
<span class="ident">Struct</span> { <span class="ident">field</span>: <span class="ident">U</span> },
<span class="ident">Unit</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">project</span>() {
<span class="ident">EnumProj</span>::<span class="ident">Tuple</span>(<span class="ident">x</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">x</span>;
}
<span class="ident">EnumProj</span>::<span class="ident">Struct</span> { <span class="ident">field</span> } <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">U</span> <span class="op">=</span> <span class="ident">field</span>;
}
<span class="ident">EnumProj</span>::<span class="ident">Unit</span> <span class="op">=</span><span class="op">&gt;</span> {}
}
}
}</pre></div>
<p>When <code>#[pin_project]</code> is used on enums, only named projection types and
methods are generated because there is no way to access variants of
projected types without naming it.
For example, in the above example, only the <code>project</code> method is generated,
and the <code>project_ref</code> method is not generated.
(When <code>#[pin_project]</code> is used on structs, both methods are always generated.)</p>
<div class='information'><div class='tooltip compile_fail'></div></div><div class="example-wrap"><pre class="rust rust-example-rendered compile_fail">
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">call_project_ref</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">_this</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project_ref</span>();
<span class="comment">//~^ ERROR no method named `project_ref` found for struct `Pin&lt;&amp;Enum&lt;T, U&gt;&gt;` in the current scope</span>
}
}</pre></div>
<p>If you want to call <code>.project()</code> multiple times or later use the
original <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a> type, it needs to use <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html#method.as_mut"><code>.as_mut()</code></a> to avoid
consuming the <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">field</span>: <span class="ident">T</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">call_project_twice</span>(<span class="kw-2">mut</span> <span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="comment">// `project` consumes `self`, so reborrow the `Pin&lt;&amp;mut Self&gt;` via `as_mut`.</span>
<span class="self">self</span>.<span class="ident">as_mut</span>().<span class="ident">project</span>();
<span class="self">self</span>.<span class="ident">as_mut</span>().<span class="ident">project</span>();
}
}</pre></div>
<h1 id="unpin" class="section-header"><a href="#unpin"><code>!Unpin</code></a></h1>
<p>If you want to ensure that <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> is not implemented, use the <code>!Unpin</code>
argument to <code>#[pin_project]</code>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="op">!</span><span class="ident">Unpin</span>)]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">field</span>: <span class="ident">T</span>,
}</pre></div>
<p>This is equivalent to using <code>#[pin]</code> attribute for the <a href="https://doc.rust-lang.org/nightly/core/marker/struct.PhantomPinned.html"><code>PhantomPinned</code></a>
field.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">marker</span>::<span class="ident">PhantomPinned</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">field</span>: <span class="ident">T</span>,
<span class="attribute">#[<span class="ident">pin</span>]</span> <span class="comment">// &lt;------ This `#[pin]` is required to make `Struct` to `!Unpin`.</span>
<span class="ident">_pin</span>: <span class="ident">PhantomPinned</span>,
}</pre></div>
<p>Note that using <a href="https://doc.rust-lang.org/nightly/core/marker/struct.PhantomPinned.html"><code>PhantomPinned</code></a> without <code>#[pin]</code> attribute has no effect.</p>
<h1 id="unsafeunpin" class="section-header"><a href="#unsafeunpin"><code>UnsafeUnpin</code></a></h1>
<p>If you want to implement <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> manually, you must use the <code>UnsafeUnpin</code>
argument to <code>#[pin_project]</code>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">pin_project</span>::{<span class="ident">pin_project</span>, <span class="ident">UnsafeUnpin</span>};
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">UnsafeUnpin</span>)]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned</span>: <span class="ident">T</span>,
<span class="ident">unpinned</span>: <span class="ident">U</span>,
}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Unpin</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">UnsafeUnpin</span> <span class="kw">for</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {}</pre></div>
<p>Note the usage of the unsafe <a href="https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html"><code>UnsafeUnpin</code></a> trait, instead of the usual
<a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> trait. <a href="https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html"><code>UnsafeUnpin</code></a> behaves exactly like <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>, except that
is unsafe to implement. This unsafety comes from the fact that pin
projections are being used. If you implement <a href="https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html"><code>UnsafeUnpin</code></a>, you must
ensure that it is only implemented when all pin-projected fields implement
<a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
<p>See <a href="https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html"><code>UnsafeUnpin</code></a> trait for more details.</p>
<h1 id="pinned_drop" class="section-header"><a href="#pinned_drop"><code>#[pinned_drop]</code></a></h1>
<p>In order to correctly implement pin projections, a types <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl must
not move out of any structurally pinned fields. Unfortunately,
<a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html#tymethod.drop" title="Drop::drop"><code>Drop::drop</code></a> takes <code>&amp;mut Self</code>, not <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a><code>&lt;&amp;mut Self&gt;</code>.</p>
<p>To ensure that this requirement is upheld, the <code>#[pin_project]</code> attribute
will provide a <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl for you. This <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl will delegate to
an impl block annotated with <code>#[pinned_drop]</code> if you use the <code>PinnedDrop</code>
argument to <code>#[pin_project]</code>.</p>
<p>This impl block acts just like a normal <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl,
except for the following two:</p>
<ul>
<li><code>drop</code> method takes <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a><code>&lt;&amp;mut Self&gt;</code></li>
<li>Name of the trait is <code>PinnedDrop</code>.</li>
</ul>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">pub</span> <span class="kw">trait</span> <span class="ident">PinnedDrop</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>);
}</pre></div>
<p><code>#[pin_project]</code> implements the actual <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> trait via <code>PinnedDrop</code> you
implemented. To drop a type that implements <code>PinnedDrop</code>, use the <a href="https://doc.rust-lang.org/nightly/core/mem/fn.drop.html" title="drop"><code>drop</code></a>
function just like dropping a type that directly implements <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a>.</p>
<p>In particular, it will never be called more than once, just like
<a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html#tymethod.drop" title="Drop::drop"><code>Drop::drop</code></a>.</p>
<p>For example:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::{<span class="ident">fmt</span>::<span class="ident">Debug</span>, <span class="ident">pin</span>::<span class="ident">Pin</span>};
<span class="kw">use</span> <span class="ident">pin_project</span>::{<span class="ident">pin_project</span>, <span class="ident">pinned_drop</span>};
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">PinnedDrop</span>)]</span>
<span class="kw">struct</span> <span class="ident">PrintOnDrop</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Debug</span>, <span class="ident">U</span>: <span class="ident">Debug</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned_field</span>: <span class="ident">T</span>,
<span class="ident">unpin_field</span>: <span class="ident">U</span>,
}
<span class="attribute">#[<span class="ident">pinned_drop</span>]</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Debug</span>, <span class="ident">U</span>: <span class="ident">Debug</span><span class="op">&gt;</span> <span class="ident">PinnedDrop</span> <span class="kw">for</span> <span class="ident">PrintOnDrop</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;Dropping pinned field: {:?}&quot;</span>, <span class="self">self</span>.<span class="ident">pinned_field</span>);
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;Dropping unpin field: {:?}&quot;</span>, <span class="self">self</span>.<span class="ident">unpin_field</span>);
}
}
<span class="kw">fn</span> <span class="ident">main</span>() {
<span class="kw">let</span> <span class="ident">_x</span> <span class="op">=</span> <span class="ident">PrintOnDrop</span> { <span class="ident">pinned_field</span>: <span class="bool-val">true</span>, <span class="ident">unpin_field</span>: <span class="number">40</span> };
}</pre></div>
<p>See also <a href="../pin_project/attr.pinned_drop.html" title="pinned_drop"><code>#[pinned_drop]</code></a> attribute.</p>
<h1 id="project_replace-method" class="section-header"><a href="#project_replace-method"><code>project_replace</code> method</a></h1>
<p>In addition to the <code>project</code> and <code>project_ref</code> methods which are always
provided when you use the <code>#[pin_project]</code> attribute, there is a third
method, <code>project_replace</code> which can be useful in some situations. It is
equivalent to <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html#method.set"><code>Pin::set</code></a>, except that the unpinned fields are moved and
returned, instead of being dropped in-place.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">project_replace</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>, <span class="ident">other</span>: <span class="self">Self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ProjectionOwned</span>;</pre></div>
<p>The <code>ProjectionOwned</code> type is identical to the <code>Self</code> type, except that
all pinned fields have been replaced by equivalent <a href="https://doc.rust-lang.org/nightly/core/marker/struct.PhantomData.html"><code>PhantomData</code></a> types.</p>
<p>This method is opt-in, because it is only supported for <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="Sized"><code>Sized</code></a> types, and
because it is incompatible with the <a href="../pin_project/attr.pin_project.html#pinned_drop"><code>#[pinned_drop]</code></a>
attribute described above. It can be enabled by using
<code>#[pin_project(project_replace)]</code>.</p>
<p>For example:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::{<span class="ident">marker</span>::<span class="ident">PhantomData</span>, <span class="ident">pin</span>::<span class="ident">Pin</span>};
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">project_replace</span>)]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned_field</span>: <span class="ident">T</span>,
<span class="ident">unpinned_field</span>: <span class="ident">U</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>, <span class="ident">other</span>: <span class="self">Self</span>) {
<span class="kw">let</span> <span class="ident">this</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project_replace</span>(<span class="ident">other</span>);
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">U</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">unpinned_field</span>;
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">PhantomData</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">pinned_field</span>;
}
}</pre></div>
<p>By passing the value to the <code>project_replace</code> argument, you can name the
returned type of the <code>project_replace</code> method. This is necessary whenever
destructuring the return type of the <code>project_replace</code> method, and work in exactly
the same way as the <code>project</code> and <code>project_ref</code> arguments.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">project_replace</span> <span class="op">=</span> <span class="ident">EnumProjOwn</span>)]</span>
<span class="kw">enum</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="ident">A</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned_field</span>: <span class="ident">T</span>,
<span class="ident">unpinned_field</span>: <span class="ident">U</span>,
},
<span class="ident">B</span>,
}
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">x</span> <span class="op">=</span> <span class="ident">Box</span>::<span class="ident">pin</span>(<span class="ident">Enum</span>::<span class="ident">A</span> { <span class="ident">pinned_field</span>: <span class="number">42</span>, <span class="ident">unpinned_field</span>: <span class="string">&quot;hello&quot;</span> });
<span class="kw">match</span> <span class="ident">x</span>.<span class="ident">as_mut</span>().<span class="ident">project_replace</span>(<span class="ident">Enum</span>::<span class="ident">B</span>) {
<span class="ident">EnumProjOwn</span>::<span class="ident">A</span> { <span class="ident">unpinned_field</span>, .. } <span class="op">=</span><span class="op">&gt;</span> <span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">unpinned_field</span>, <span class="string">&quot;hello&quot;</span>),
<span class="ident">EnumProjOwn</span>::<span class="ident">B</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">unreachable</span><span class="macro">!</span>(),
}</pre></div>
</div></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="pin_project"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>
+63
View File
@@ -0,0 +1,63 @@
<!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 attribute used for custom implementations of [`Drop`]."><meta name="keywords" content="rust, rustlang, rust-lang, pinned_drop"><title>pin_project::pinned_drop - 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="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc attr"><!--[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='../pin_project/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><div class="sidebar-elems"><p class="location"><a href="index.html">pin_project</a></p><div id="sidebar-vars" data-name="pinned_drop" data-ty="attr" data-relpath=""></div><script defer src="sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<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">Attribute Macro <a href="index.html">pin_project</a>::<wbr><a class="attr" href="">pinned_drop</a></span><span class="out-of-band"><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/pin_project_internal/lib.rs.html#568" title="goto source code">[src]</a></span></h1><pre class="rust attr">#[pinned_drop]</pre><div class="docblock"><p>An attribute used for custom implementations of <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a>.</p>
<p>This attribute is used in conjunction with the <code>PinnedDrop</code> argument to
the <a href="../pin_project/attr.pin_project.html" title="pin_project"><code>#[pin_project]</code></a> attribute.</p>
<p>The impl block annotated with this attribute acts just like a normal
<a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> impl, except for the following two:</p>
<ul>
<li><code>drop</code> method takes <a href="https://doc.rust-lang.org/nightly/core/pin/struct.Pin.html"><code>Pin</code></a><code>&lt;&amp;mut Self&gt;</code></li>
<li>Name of the trait is <code>PinnedDrop</code>.</li>
</ul>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">pub</span> <span class="kw">trait</span> <span class="ident">PinnedDrop</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>);
}</pre></div>
<p><code>#[pin_project]</code> implements the actual <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> trait via <code>PinnedDrop</code> you
implemented. To drop a type that implements <code>PinnedDrop</code>, use the <a href="https://doc.rust-lang.org/nightly/core/mem/fn.drop.html" title="drop"><code>drop</code></a>
function just like dropping a type that directly implements <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a>.</p>
<p>In particular, it will never be called more than once, just like
<a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html#tymethod.drop" title="Drop::drop"><code>Drop::drop</code></a>.</p>
<h1 id="examples" class="section-header"><a href="#examples">Examples</a></h1>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::{<span class="ident">pin_project</span>, <span class="ident">pinned_drop</span>};
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">PinnedDrop</span>)]</span>
<span class="kw">struct</span> <span class="ident">PrintOnDrop</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">field</span>: <span class="ident">u8</span>,
}
<span class="attribute">#[<span class="ident">pinned_drop</span>]</span>
<span class="kw">impl</span> <span class="ident">PinnedDrop</span> <span class="kw">for</span> <span class="ident">PrintOnDrop</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;Dropping: {}&quot;</span>, <span class="self">self</span>.<span class="ident">field</span>);
}
}
<span class="kw">fn</span> <span class="ident">main</span>() {
<span class="kw">let</span> <span class="ident">_x</span> <span class="op">=</span> <span class="ident">PrintOnDrop</span> { <span class="ident">field</span>: <span class="number">50</span> };
}</pre></div>
<p>See also <a href="../pin_project/attr.pin_project.html#pinned_drop">“pinned-drop” section of <code>#[pin_project]</code> attribute</a>.</p>
<h1 id="why-pinned_drop-attribute-is-needed" class="section-header"><a href="#why-pinned_drop-attribute-is-needed">Why <code>#[pinned_drop]</code> attribute is needed?</a></h1>
<p>Implementing <code>PinnedDrop::drop</code> is safe, but calling it is not safe.
This is because destructors can be called multiple times in safe code and
<a href="https://github.com/rust-lang/rust/pull/62360">double dropping is unsound</a>.</p>
<p>Ideally, it would be desirable to be able to forbid manual calls in
the same way as <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html#tymethod.drop" title="Drop::drop"><code>Drop::drop</code></a>, but the library cannot do it. So, by using
macros and replacing them with private traits like the following,
this crate prevent users from calling <code>PinnedDrop::drop</code> in safe code.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">pub</span> <span class="kw">trait</span> <span class="ident">PinnedDrop</span> {
<span class="kw">unsafe</span> <span class="kw">fn</span> <span class="ident">drop</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>);
}</pre></div>
<p>This allows implementing <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a> safely using <code>#[pinned_drop]</code>.
Also by using the <a href="https://doc.rust-lang.org/nightly/core/mem/fn.drop.html" title="drop"><code>drop</code></a> function just like dropping a type that directly
implements <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a>, can drop safely a type that implements <code>PinnedDrop</code>.</p>
</div></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="pin_project"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>
+65
View File
@@ -0,0 +1,65 @@
<!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="A crate for safe and ergonomic pin-projection."><meta name="keywords" content="rust, rustlang, rust-lang, pin_project"><title>pin_project - 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="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[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='../pin_project/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><p class="location">Crate pin_project</p><div class="block version"><p>Version 1.0.5</p></div><div class="sidebar-elems"><a id="all-types" href="all.html"><p>See all pin_project's items</p></a><div class="block items"><ul><li><a href="#traits">Traits</a></li></ul></div><p class="location"></p><div id="sidebar-vars" data-name="pin_project" data-ty="mod" data-relpath="../"></div></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<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">Crate <a class="mod" href="">pin_project</a></span><span class="out-of-band"><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/pin_project/lib.rs.html#1-282" title="goto source code">[src]</a></span></h1><div class="docblock"><p>A crate for safe and ergonomic <a href="https://doc.rust-lang.org/nightly/core/pin/index.html#projections-and-structural-pinning">pin-projection</a>.</p>
<h1 id="examples" class="section-header"><a href="#examples">Examples</a></h1>
<p><a href="../pin_project/attr.pin_project.html" title="pin_project"><code>#[pin_project]</code></a> attribute creates projection types
covering all the fields of struct or enum.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">pinned</span>: <span class="ident">T</span>,
<span class="ident">unpinned</span>: <span class="ident">U</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">this</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">project</span>();
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">pinned</span>; <span class="comment">// Pinned reference to the field</span>
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">U</span> <span class="op">=</span> <span class="ident">this</span>.<span class="ident">unpinned</span>; <span class="comment">// Normal reference to the field</span>
}
}</pre></div>
<p><a href="https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs"><em>code like this will be generated</em></a></p>
<p>To use <code>#[pin_project]</code> on enums, you need to name the projection type
returned from the method.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">pin_project</span>::<span class="ident">pin_project</span>;
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">project</span> <span class="op">=</span> <span class="ident">EnumProj</span>)]</span>
<span class="kw">enum</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="ident">Pinned</span>(<span class="attribute">#[<span class="ident">pin</span>]</span> <span class="ident">T</span>),
<span class="ident">Unpinned</span>(<span class="ident">U</span>),
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> <span class="ident">Enum</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">U</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">method</span>(<span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>) {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">project</span>() {
<span class="ident">EnumProj</span>::<span class="ident">Pinned</span>(<span class="ident">x</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">Pin</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="op">&gt;</span> <span class="op">=</span> <span class="ident">x</span>;
}
<span class="ident">EnumProj</span>::<span class="ident">Unpinned</span>(<span class="ident">y</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">U</span> <span class="op">=</span> <span class="ident">y</span>;
}
}
}
}</pre></div>
<p><a href="https://github.com/taiki-e/pin-project/blob/master/examples/enum-default-expanded.rs"><em>code like this will be generated</em></a></p>
<p>See <a href="../pin_project/attr.pin_project.html" title="pin_project"><code>#[pin_project]</code></a> attribute for more details, and
see <a href="https://github.com/taiki-e/pin-project/blob/master/examples/README.md">examples</a> directory for more examples and generated code.</p>
</div><h2 id="traits" class="section-header"><a href="#traits">Traits</a></h2>
<table><tr class="module-item"><td><a class="trait" href="trait.UnsafeUnpin.html" title="pin_project::UnsafeUnpin trait">UnsafeUnpin</a></td><td class="docblock-short"><p>A trait used for custom implementations of <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
</td></tr></table><h2 id="attributes" class="section-header"><a href="#attributes">Attribute Macros</a></h2>
<table><tr class="module-item"><td><a class="attr" href="attr.pin_project.html" title="pin_project::pin_project attr">pin_project</a></td><td class="docblock-short"><p>An attribute that creates projection types covering all the fields of
struct or enum.</p>
</td></tr><tr class="module-item"><td><a class="attr" href="attr.pinned_drop.html" title="pin_project::pinned_drop attr">pinned_drop</a></td><td class="docblock-short"><p>An attribute used for custom implementations of <a href="https://doc.rust-lang.org/nightly/core/ops/drop/trait.Drop.html" title="Drop"><code>Drop</code></a>.</p>
</td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="pin_project"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>
+1
View File
@@ -0,0 +1 @@
initSidebarItems({"attr":[["pin_project","An attribute that creates projection types covering all the fields of struct or enum."],["pinned_drop","An attribute used for custom implementations of [`Drop`]."]],"trait":[["UnsafeUnpin","A trait used for custom implementations of [`Unpin`]."]]});
+48
View File
@@ -0,0 +1,48 @@
<!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="A trait used for custom implementations of [`Unpin`]."><meta name="keywords" content="rust, rustlang, rust-lang, UnsafeUnpin"><title>pin_project::UnsafeUnpin - 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="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc trait"><!--[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='../pin_project/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><p class="location">Trait UnsafeUnpin</p><div class="sidebar-elems"><div class="block items"><a class="sidebar-title" href="#implementors">Implementors</a></div><p class="location"><a href="index.html">pin_project</a></p><div id="sidebar-vars" data-name="UnsafeUnpin" data-ty="trait" data-relpath=""></div><script defer src="sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<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">Trait <a href="index.html">pin_project</a>::<wbr><a class="trait" href="">UnsafeUnpin</a></span><span class="out-of-band"><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/pin_project/lib.rs.html#145" title="goto source code">[src]</a></span></h1><div class="docblock type-decl hidden-by-usual-hider"><pre class="rust trait">pub unsafe trait UnsafeUnpin { }</pre></div><div class="docblock"><p>A trait used for custom implementations of <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
<p>This trait is used in conjunction with the <code>UnsafeUnpin</code> argument to
the <a href="../pin_project/attr.pin_project.html" title="pin_project"><code>#[pin_project]</code></a> attribute.</p>
<p>The Rust <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> trait is safe to implement - by itself,
implementing it cannot lead to <a href="https://doc.rust-lang.org/reference/behavior-considered-undefined.html">undefined behavior</a>.
Undefined behavior can only occur when other unsafe code is used.</p>
<p>It turns out that using pin projections, which requires unsafe code,
imposes additional requirements on an <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl. Normally, all of this
unsafety is contained within this crate, ensuring that its impossible for
you to violate any of the guarantees required by pin projection.</p>
<p>However, things change if you want to provide a custom <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl
for your <code>#[pin_project]</code> type. As stated in <a href="https://doc.rust-lang.org/nightly/core/pin/index.html#projections-and-structural-pinning">the Rust
documentation</a>, you must be sure to only implement <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>
when all of your <code>#[pin]</code> fields (i.e. structurally pinned fields) are also
<a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.</p>
<p>To help highlight this unsafety, the <code>UnsafeUnpin</code> trait is provided.
Implementing this trait is logically equivalent to implementing <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> -
this crate will generate an <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl for your type that forwards to
your <code>UnsafeUnpin</code> impl. However, this trait is <code>unsafe</code> - since your type
uses structural pinning (otherwise, you wouldnt be using this crate!),
you must be sure that your <code>UnsafeUnpin</code> impls follows all of
the requirements for an <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a> impl of a structurally-pinned type.</p>
<p>Note that if you specify <code>#[pin_project(UnsafeUnpin)]</code>, but do <em>not</em>
provide an impl of <code>UnsafeUnpin</code>, your type will never implement <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>.
This is effectively the same thing as adding a <a href="https://doc.rust-lang.org/nightly/core/marker/struct.PhantomPinned.html"><code>PhantomPinned</code></a> to your
type.</p>
<p>Since this trait is <code>unsafe</code>, impls of it will be detected by the
<code>unsafe_code</code> lint, and by tools like <a href="https://github.com/rust-secure-code/cargo-geiger"><code>cargo geiger</code></a>.</p>
<h1 id="examples" class="section-header"><a href="#examples">Examples</a></h1>
<p>An <code>UnsafeUnpin</code> impl which, in addition to requiring that structurally
pinned fields be <a href="https://doc.rust-lang.org/nightly/core/marker/trait.Unpin.html" title="Unpin"><code>Unpin</code></a>, imposes an additional requirement:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">pin_project</span>::{<span class="ident">pin_project</span>, <span class="ident">UnsafeUnpin</span>};
<span class="attribute">#[<span class="ident">pin_project</span>(<span class="ident">UnsafeUnpin</span>)]</span>
<span class="kw">struct</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">K</span>, <span class="ident">V</span><span class="op">&gt;</span> {
<span class="attribute">#[<span class="ident">pin</span>]</span>
<span class="ident">field_1</span>: <span class="ident">K</span>,
<span class="ident">field_2</span>: <span class="ident">V</span>,
}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">K</span>, <span class="ident">V</span><span class="op">&gt;</span> <span class="ident">UnsafeUnpin</span> <span class="kw">for</span> <span class="ident">Struct</span><span class="op">&lt;</span><span class="ident">K</span>, <span class="ident">V</span><span class="op">&gt;</span> <span class="kw">where</span> <span class="ident">K</span>: <span class="ident">Unpin</span> <span class="op">+</span> <span class="ident">Clone</span> {}</pre></div>
</div><h2 id="implementors" class="small-section-header">Implementors<a href="#implementors" class="anchor"></a></h2><div class="item-list" id="implementors-list"></div><span class="loading-content">Loading content...</span><script type="text/javascript" src="../implementors/pin_project/trait.UnsafeUnpin.js" async></script></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="pin_project"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>