Files
phy/self_cell/index.html
Orion Kindel 0ce894e6b0 doc
2025-03-18 10:30:23 -05:00

136 lines
12 KiB
HTML
Raw Permalink 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="Overview"><title>self_cell - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="self_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.0 (9fc6b4312 2025-01-07)" data-channel="1.84.0" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../static.files/storage-59e33391.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[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="../self_cell/index.html">self_<wbr>cell</a><span class="version">1.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#overview" title="Overview">Overview</a><ul><li><a href="#fast-compile-times" title="Fast compile times">Fast compile times</a></li><li><a href="#a-motivating-use-case" title="A motivating use case">A motivating use case</a></li><li><a href="#min-required-rustc-version" title="Min required rustc version">Min required rustc version</a></li></ul></li></ul><h3><a href="#macros">Crate Items</a></h3><ul class="block"><li><a href="#macros" title="Macros">Macros</a></li><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></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>Crate <span>self_cell</span><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/self_cell/lib.rs.html#1-677">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><h2 id="overview"><a class="doc-anchor" href="#overview">§</a>Overview</h2>
<p><code>self_cell</code> provides one macro-rules macro: <a href="macro.self_cell.html" title="macro self_cell::self_cell"><code>self_cell</code></a>. With this macro
you can create self-referential structs that are safe-to-use in stable Rust,
without leaking the struct internal lifetime.</p>
<p>In a nutshell, the API looks <em>roughly</em> like this:</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="comment">// User code:
</span><span class="macro">self_cell!</span>(
<span class="kw">struct </span>NewStructName {
owner: Owner,
<span class="attr">#[covariant]
</span>dependent: Dependent,
}
<span class="kw">impl </span>{Debug}
);
<span class="comment">// Generated by macro:
</span><span class="kw">struct </span>NewStructName(...);
<span class="kw">impl </span>NewStructName {
<span class="kw">fn </span>new(
owner: Owner,
dependent_builder: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span>Owner) -&gt; Dependent&lt;<span class="lifetime">'a</span>&gt;
) -&gt; NewStructName { ... }
<span class="kw">fn </span>borrow_owner&lt;<span class="lifetime">'a</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'a </span>Owner { ... }
<span class="kw">fn </span>borrow_dependent&lt;<span class="lifetime">'a</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'a </span>Dependent&lt;<span class="lifetime">'a</span>&gt; { ... }
[...]
<span class="comment">// See the macro level documentation for a list of all generated functions,
// section "Generated API".
</span>}
<span class="kw">impl </span>Debug <span class="kw">for </span>NewStructName { ... }</code></pre></div>
<p>Self-referential structs are currently not supported with safe vanilla Rust.
The only reasonable safe alternative is to have the user juggle 2 separate
data structures which is a mess. The library solution ouroboros is expensive
to compile due to its use of procedural macros.</p>
<p>This alternative is <code>no_std</code>, uses no proc-macros, some self contained
unsafe and works on stable Rust, and is miri tested. With a total of less
than 300 lines of implementation code, which consists mostly of type and
trait implementations, this crate aims to be a good minimal solution to the
problem of self-referential structs.</p>
<p>It has undergone <a href="https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775">community code
review</a>
from experienced Rust users.</p>
<h4 id="fast-compile-times"><a class="doc-anchor" href="#fast-compile-times">§</a>Fast compile times</h4><div class="example-wrap"><pre class="language-txt"><code>$ rm -rf target &amp;&amp; cargo +nightly build -Z timings
Compiling self_cell v0.7.0
Completed self_cell v0.7.0 in 0.2s</code></pre></div>
<p>Because it does <strong>not</strong> use proc-macros, and has 0 dependencies
compile-times are fast.</p>
<p>Measurements done on a slow laptop.</p>
<h4 id="a-motivating-use-case"><a class="doc-anchor" href="#a-motivating-use-case">§</a>A motivating use case</h4>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>self_cell::self_cell;
<span class="attr">#[derive(Debug, Eq, PartialEq)]
</span><span class="kw">struct </span>Ast&lt;<span class="lifetime">'a</span>&gt;(<span class="kw">pub </span>Vec&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt;);
<span class="macro">self_cell!</span>(
<span class="kw">struct </span>AstCell {
owner: String,
<span class="attr">#[covariant]
</span>dependent: Ast,
}
<span class="kw">impl </span>{Debug, Eq, PartialEq}
);
<span class="kw">fn </span>build_ast_cell(code: <span class="kw-2">&amp;</span>str) -&gt; AstCell {
<span class="comment">// Create owning String on stack.
</span><span class="kw">let </span>pre_processed_code = code.trim().to_string();
<span class="comment">// Move String into AstCell, then build Ast inplace.
</span>AstCell::new(
pre_processed_code,
|code| Ast(code.split(<span class="string">' '</span>).filter(|word| word.len() &gt; <span class="number">1</span>).collect())
)
}
<span class="kw">fn </span>main() {
<span class="kw">let </span>ast_cell = build_ast_cell(<span class="string">"fox = cat + dog"</span>);
<span class="macro">println!</span>(<span class="string">"ast_cell -&gt; {:?}"</span>, <span class="kw-2">&amp;</span>ast_cell);
<span class="macro">println!</span>(<span class="string">"ast_cell.borrow_owner() -&gt; {:?}"</span>, ast_cell.borrow_owner());
<span class="macro">println!</span>(<span class="string">"ast_cell.borrow_dependent().0[1] -&gt; {:?}"</span>, ast_cell.borrow_dependent().<span class="number">0</span>[<span class="number">1</span>]);
}</code></pre></div>
<div class="example-wrap"><pre class="language-txt"><code>$ cargo run
ast_cell -&gt; AstCell { owner: &quot;fox = cat + dog&quot;, dependent: Ast([&quot;fox&quot;, &quot;cat&quot;, &quot;dog&quot;]) }
ast_cell.borrow_owner() -&gt; &quot;fox = cat + dog&quot;
ast_cell.borrow_dependent().0[1] -&gt; &quot;cat&quot;</code></pre></div>
<p>There is no way in safe Rust to have an API like <code>build_ast_cell</code>, as soon
as <code>Ast</code> depends on stack variables like <code>pre_processed_code</code> you cant
return the value out of the function anymore. You could move the
pre-processing into the caller but that gets ugly quickly because you cant
encapsulate things anymore. Note this is a somewhat niche use case,
self-referential structs should only be used when there is no good
alternative.</p>
<p>Under the hood, it heap allocates a struct which it initializes first by
moving the owner value to it and then using the reference to this now
Pin/Immovable owner to construct the dependent inplace next to it. This
makes it safe to move the generated SelfCell but you have to pay for the
heap allocation.</p>
<p>See the documentation for <a href="macro.self_cell.html" title="macro self_cell::self_cell"><code>self_cell</code></a> to dive further into the details.</p>
<p>Or take a look at the advanced examples:</p>
<ul>
<li>
<p><a href="https://github.com/Voultapher/self_cell/tree/main/examples/fallible_dependent_construction">Example how to handle dependent construction that can
fail</a></p>
</li>
<li>
<p><a href="https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast">How to build a lazy AST with
self_cell</a></p>
</li>
<li>
<p><a href="https://github.com/Voultapher/self_cell/tree/main/examples/mut_ref_to_owner_in_builder">How to handle dependents that take a mutable reference</a> see also <a href="struct.MutBorrow.html" title="struct self_cell::MutBorrow"><code>MutBorrow</code></a></p>
</li>
<li>
<p><a href="https://github.com/Voultapher/self_cell/tree/main/examples/owner_with_lifetime">How to use an owner type with
lifetime</a></p>
</li>
</ul>
<h4 id="min-required-rustc-version"><a class="doc-anchor" href="#min-required-rustc-version">§</a>Min required rustc version</h4>
<p>By default the minimum required rustc version is 1.51.</p>
<p>There is an optional feature you can enable called “old_rust” that enables
support down to rustc version 1.36. However this requires polyfilling std
library functionality for older rustc with technically UB versions. Testing
does not show older rustc versions (ab)using this. Use at your own risk.</p>
<p>The minimum versions are a best effor and may change with any new major
release.</p>
</div></details><h2 id="macros" class="section-header">Macros<a href="#macros" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="macro" href="macro.self_cell.html" title="macro self_cell::self_cell">self_<wbr>cell</a></div><div class="desc docblock-short">This macro declares a new struct of <code>$StructName</code> and implements traits
based on <code>$AutomaticDerive</code>.</div></li></ul><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.MutBorrow.html" title="struct self_cell::MutBorrow">MutBorrow</a></div><div class="desc docblock-short">Wrapper type that allows creating a self-referential type that hold a mutable borrow <code>&amp;mut T</code>.</div></li></ul></section></div></main></body></html>