<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[The {pnk}f(eli)x Blog]]></title>
  <link href="http://blog.pnkfx.org/atom.xml" rel="self"/>
  <link href="http://blog.pnkfx.org/"/>
  <updated>2022-05-12T14:19:54-04:00</updated>
  <id>http://blog.pnkfx.org/</id>
  <author>
    <name><![CDATA[Felix S. Klock II]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Linking Rust Crates, Part 1]]></title>
    <link href="http://blog.pnkfx.org/blog/2022/05/12/linking-rust-crates/"/>
    <updated>2022-05-12T01:50:00-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2022/05/12/linking-rust-crates</id>
    <content type="html"><![CDATA[<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This post is the first part in a planned series on linking Rust crates.
My desire is to get informal feedback on these posts, and then
turn it into more structured content suitable for the Rust reference, or
maybe the Rustonomicon (or a book on its own.)
</span>
Working on the Rust compiler, one topic that I come across from time to time is
&ldquo;what is <em>supposed</em> to happen when we use these particular features of my
tools?&rdquo; More specifically, Rust has various metaphorical knobs that allow
fine-grained control of the object code generated by the compiler, several of
which are related to the process of linking that code to other object code.</p>

<p>From <a href="https://doc.rust-lang.org/reference/linkage.html">Linkage</a> chapter of the Rust Reference, we can see there are seven
kinds of crates: <code>bin</code>, <code>lib</code>, <code>dylib</code>, <code>staticlib</code>, <code>cdylib</code>, <code>rlib</code>, and <code>proc-macro</code>.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I had originally intended to cover all seven, but the time got late and the post got long
and I decided that <code>proc-macro</code> can be dealt with another day.
</span></p>

<p>What this post is going to do is walk through the first six of the crate types
listed above and demonstrate: how to build an example of such a crate, how to
link to it, and how to run with that linked crate.</p>

<!-- more -->


<p>In later posts, I will explore the various attributes and command-line flags
that can influence the linking step. But right now, I want to establish the
foundation for that later discussion.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Some phenomena require mixing multiple crate types in order to observe corner
cases that are worth addressing. I am leaving that for a future post as well.
</span></p>

<p>These initial examples are as simple as possible. We will want to actually
demonstrate each case running. Since most crate types are not executable, that
means we will need multiple crates in almost all of our examples.</p>

<p>Also, I will not be using Cargo in any of my examples. I will try to note points
where things I am doing are deviating from what you would normally do if you
were using Cargo (such as my use of <code>extern crate</code> in these examples), and
hopefully a later post will explore the status quo of how Cargo handles various
linkage scenarios. But, I am taking baby steps here; lets focus on <code>rustc</code> alone
for now.</p>

<p>At a very high level, we will be looking at object file structures that
look something like this:</p>

<div class="mermaid">
graph LR
SbSource[simple-bin.rs]
SbObj["simple-bin (exec)"]
SbSource --> SbCompile((rustc))
SbCompile -- generates --> SbObj
</div>


<p>That is: Given some input like <code>simple-bin.rs</code>, you can feed into <code>rustc</code> and
get an executable as its output.</p>

<p>The actual code for a case like the above is trivial:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-bin.rs</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;bin&quot;</span><span class="p">]</span> <span class="c1">// (&quot;bin&quot; is the default; other examples vary here.)</span>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>With that code in place, you can compile and run the program. (In practice
 developers would usally do this via <code>cargo run</code>.)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/bins/ps/dsb simple-bin.rs
</span><span class='line'>% ls out/bins/ps/dsb
</span><span class='line'>simple-bin
</span><span class='line'>% out/bins/ps/dsb/simple-bin
</span><span class='line'>Running main from simple-bin.rs
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I am using a bespoke directory naming convention unique to this blog post.
For example,  in <code>--out-dir</code> in this invocation: All output goes under <code>out</code>.
Executable binaries go under <code>out/bin</code>. If static linkage was preferred during the build, then it goes under <code>out/bin/ps</code> (for &ldquo;prefer static&rdquo;); if dynamic linkage was preferred, then under <code>out/bin/pd</code> (for &ldquo;prefer dynamic&rdquo;); the post explains this &ldquo;preference&rdquo; further down, with the discussion of <code>-Cprefer-dynamic</code>. Finally, I added a directory named via a unique key for each test (here, <code>dsb</code>, for &ldquo;demo-simple-bin&rdquo;), so that the <code>ls</code> invocations are tidy.
</span>
In these examples, I will be overriding the default output directory so that each example
will have its own direcrory. This forces the examples to specify precisely where it is
getting its libraries from; it is a good way to double-check one&rsquo;s understanding of what
is actually happening under-the-hood.</p>

<a name="Simple.linkage.of.a..code.lib..code..crate"></a>
<h2>Simple linkage of a <code>lib</code> crate</h2>

<p>Of course, since our subject of interest is linking, we will want to look at
examples that involve library crates. Here is perhaps the simplest intance of
that:</p>

<div class="mermaid">
graph TD
SlSource[simple-lib.rs]
SlObj[libsimple_lib.rlib]
SlSource --> SlCompile((rustc))
SlCompile --generates --> SlObj
DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-lib.rs]
DemoSlObj[demo-simple-lib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
link -- generates --> DemoSlBin["demo-simple-lib (exec)"]
</div>


<p>What is the advantage of separating your code like this, into separate libraries
that are subsequently linked? One reason to do this is to identify which code is
under active development, and focus on its development separately from the
overall product. So, if <code>simple-lib.rs</code> were under development, we could focus
just on that, and not have our tools spend time processing <code>demo-simple-lib.rs</code>.
Or vice-versa: If <code>demo-simple-lib.rs</code> were under development, then we could
focus on that, and our tools would process, at most, the <code>libsimple_lib.rlib</code>
library produced by running <code>rustc</code> on <code>simple-lib.rs</code>.</p>

<p>Here are the code and commands that correspond to the picture above
for compiling <code>demo-simple-lib</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-lib.rs</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// generate a library (what kind? The &quot;default&quot; for this platform)</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;lib&quot;</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Here&#39;s the function we&#39;ll provide to our clients.</span>
</span><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// demo-simple-lib.rs</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// link to library built from simple-lib.rs</span>
</span><span class='line'><span class="k">extern</span> <span class="n">crate</span> <span class="n">simple_lib</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// call function it exports</span>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">simple_lib</span><span class="o">::</span><span class="n">main</span><span class="p">();</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We have omitted <code>#![crate_type="bin"]</code> from <code>demo-simple-lib.rs</code> because that is
the default crate type.</p>

<p>(In practice, most modern Rust code does not use <code>extern crate</code>; instead, people
let Cargo handle injecting compiler options that achieve a similar effect. For now,
we will use <code>extern crate</code> in our initial examples, so that the Rust code itself
indicates its dependence on a separate library.)</p>

<p>With the above two files in place, we can compile each of them
and run the resulting binary.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/ps/sl simple-lib.rs
</span><span class='line'>% ls out/ps/sl
</span><span class='line'>libsimple_lib.rlib
</span><span class='line'>% rustc --out-dir out/bins/ps/dsl demo-simple-lib.rs -Lout/ps/sl
</span><span class='line'>% ls out/bins/ps/dsl
</span><span class='line'>demo-simple-lib
</span><span class='line'>% out/bins/ps/dsl/demo-simple-lib
</span><span class='line'>Running main from simple-lib.rs
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
If you&rsquo;re squinting at the diagram and wondering how you might confirm that the relations
it describes properly reflect what these commands are doing, I recommend you
check out the &ldquo;Who is using that library?&rdquo; appendix at the end of this post.
It walks through some of the issues that arise when linking crates
together.
</span></p>

<p>The first <code>rustc</code> invocation, compiling <code>simple-lib.rs</code>, is much like our <code>simple-bin.rs</code> example.
The second <code>rustc</code> invocation, compiling <code>demo-simple-lib.rs</code>, has something new: it is
passing the option <code>-Lout/sl</code>, which tells the compiler &ldquo;if you need to resolve any external crates,
you should add <code>out/sl</code> to the list of paths you will search for them.&rdquo;</p>

<p>The <code>demo-simple-lib</code> example demonstrates Rust&rsquo;s <code>lib</code> crate type,
which is specified as a compiler-defined choice from one of the flavors of
libraries that Rust supports.</p>

<p>At the time of this blog post, Rust&rsquo;s <code>lib</code> crate type maps to <code>rlib</code>, at least
on my machine. We will talk more about <code>rlib</code> further down; but for now, you can
just keep in mind the points made above for <code>simple-lib</code>: the compiler itself
will read the metadata stored in <code>rlib</code> crates, <em>and</em> the linker also extracts
definitions from <code>rlib</code> crates as well.</p>

<p>We will now step through other supported crate types, and provide
a similar demonstration of how they operate.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Re-reading the overall post now, I am thinking that I should have put <code>dylib</code> at
the end, due to the number of rabbit holes it opens up. Maybe I will edit the
post in the future and do that rearrangement, so that people can see the &ldquo;easy
cases&rdquo; first.
</span></p>

<a name="Dynamic.Libraries:..code.dylib..code."></a>
<h2>Dynamic Libraries: <code>dylib</code></h2>

<p>The next crate type listed in the Rust reference is <code>dylib</code>.</p>

<div class="mermaid">
graph TD
SlSource[simple-dylib.rs]
SlObj[libsimple_dylib.so]
SlSource --> SlCompile((rustc))
SlCompile --generates --> SlObj
DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-dylib.rs]
DemoSlObj[demo-simple-dylib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
link -- generates --> DemoSlBin["demo-simple-dylib (exec)"]
SlObj -. "dynamically loaded by" .- DemoSlBin
</div>


<p>This is a similar picture to the <a href="#Simple.linkage.of-a..lib..crate">one presented above</a>
for <code>lib</code>. In fact, if you look at the two pictures side-by-side, most of the
differences can be attributed to uniform renaming &hellip; except for one: There is
now an extra arc in the diagram, connecting the <code>demo-simple-dylib</code> executable
directly to the <code>libsimple_dylib.so</code> library file.</p>

<p>This is because a <code>dylib</code> crate is a dynamic library; it is meant to be loaded
<em>dynamically</em>, when the program is executed. There are a couple different
reasons one might want this: Perhaps the program is meant to support a &ldquo;plug-in&rdquo;
architecture, where one can get load up new behaviors by swapping in a different
dynamic library. Another common reason is to reduce executable binary sizes: if
many programs depend on the same external crate, then it might be more efficient
to have them all share the same <code>dylib</code>.</p>

<p><em>Note: The <code>dylib</code> format is not guaranteed to remain stable between different versions of the Rust compiler.
Therefore, if you use the <code>dylib</code> format, you need to ensure that all crates
that are sharing the same <code>dylib</code> and the <code>dylib</code> itself are all built
with the same version of the Rust compiler.</em></p>

<p>Here are the code and commands that correspond to the picture above
for compiling `demo-simple-dylib".</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-dylib.rs</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;dylib&quot;</span><span class="p">]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// demo-simple-dylib</span>
</span><span class='line'><span class="k">extern</span> <span class="n">crate</span> <span class="n">simple_dylib</span><span class="p">;</span>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">simple_dylib</span><span class="o">::</span><span class="n">main</span><span class="p">();</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>With the above two files in place, we can compile each of them
and run the resulting binary.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/pd/sd -C prefer-dynamic simple-dylib.rs
</span><span class='line'>% ls out/pd/sd
</span><span class='line'>libsimple_dylib.so
</span><span class='line'>% rustc --out-dir out/bins/ps/dsd demo-simple-dylib.rs -Lout/pd/sd
</span><span class='line'>% ls out/bins/ps/dsd
</span><span class='line'>demo-simple-dylib
</span><span class='line'>% <span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>out/pd/sd:<span class="k">$(</span>rustc --print<span class="o">=</span>sysroot<span class="k">)</span>/lib out/bins/ps/dsd/demo-simple-dylib
</span></code></pre></td></tr></table></div></figure>


<p>You might have noticed that our <code>demo-simple-dylib</code> code is very similar to the
<code>demo-simple-lib</code> code; the only effective change to the source is the
difference in <code>crate_type</code> for <code>simple-dylib.rs</code>. On the other hand, the commands to
compile these inputs and run the executable have had some pretty severe changes
applied to them. Let us explore why those changes were necessary.</p>

<a name="Adapting.command.lines.to.meet.needs.of.crate.type"></a>
<h3>Adapting command lines to meet needs of crate type</h3>

<p>If we tried to reuse the <code>demo-simple-lib</code> sequence of steps to compile these
files and run the presumably generated executable, we hit some roadblocks.</p>

<a name="Why.was.-Cprefer-dynamic.added"></a>
<h4>Why was -Cprefer-dynamic added</h4>

<p>First, if we tried to compile <code>simple-dylib.rs</code> using the same command that was
used for <code>simple-lib.rs</code>, it <em>seems</em> to work at first:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% mkdir -p out/ps/sd
</span><span class='line'>% rustc --out-dir out/ps/sd simple-dylib.rs
</span><span class='line'>% ls out/ps/sd
</span><span class='line'>libsimple_dylib.so
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p>The problem arises when we try to <em>use</em> that generated dylib that was compiled; that
step causes the following error output:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="sb">```</span>sh
</span><span class='line'>% rustc --out-dir out/bins/ps/dsd demo-simple-dylib.rs -Lout/ps/sd
</span><span class='line'>error: cannot satisfy dependencies so <span class="sb">`</span>std<span class="sb">`</span> only shows up once
</span><span class='line'>  <span class="p">|</span>
</span><span class='line'>  <span class="o">=</span> <span class="nb">help</span>: having upstream crates all available in one format will likely make this go away
</span><span class='line'>
</span><span class='line'>error: cannot satisfy dependencies so <span class="sb">`</span>core<span class="sb">`</span> only shows up once
</span><span class='line'>  <span class="p">|</span>
</span><span class='line'>  <span class="o">=</span> <span class="nb">help</span>: having upstream crates all available in one format will likely make this go away
</span><span class='line'><span class="o">[</span>...<span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>and so on, for all of the upstram crates <code>std</code>, <code>core</code>, <code>compiler_builtins</code>,
<code>rustc_std_workspace_core</code>, <code>alloc</code>, <code>libc</code>, <code>unwind</code>, <code>cfg_if</code>, <code>hashbrown</code>,
<code>rustc_std_workspace_alloc</code>, <code>std_detect</code>, <code>rustc_demangle</code>, <code>addr2line</code>, <code>gimli</code>,
<code>object</code>, <code>memchr</code>, <code>miniz_oxide</code>, <code>adler</code>, and <code>panic_unwind</code>.</p>

<p>Understanding why this happens requires we take a step back.</p>

<p>The compiler needs to decide, in the absence of explicit indication from the
programmer, how each dependency should be incorporated into the executable
binary being generated. Namely, should a given dependency be &ldquo;statically linked&rdquo;
into the output object (which effectively means that anything the object needs
will be copied into the output from the referenced library), or should the given
dependency be &ldquo;dynamically linked&rdquo; (which means the executable carries a
dependence on the dynamic library, that will need to be resolved at runtime).
This is a non-trivlal decision, because Rust allows individual crates to
opt-into supporting multiple distinct crate types: a single crate can say &ldquo;I can
be used as an <code>rlib</code> or a <code>dylib</code>; I will let my downstream client decide which
object file they want to pull in for their needs.&rdquo;</p>

<p>But if no one tells the compiler what choice to make, the Rust compiler applies
a simple-minded tactic for guessing what options would be best, and currently,
that tactic is heavily influenced by the presence or absence of
<code>-C prefer-dynamic</code>.</p>

<p>When <code>simple-dylib.rs</code> was compiled <em>without</em> <code>-C prefer-dynamic</code>, the compiler
interpreted the absence of that flag as a signal that the compiler should
attempt to link all dependencies of <code>simple-dylib.rs</code> statically.</p>

<p>Furthermore, the compiler manages to succeed at this static linkage of those
dependencies, but in doing so, it has it impossible to link the resulting
statically-linked crate into <code>demo-simple-dylib.rs</code>.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
A reasonable person might note here: &ldquo;Why is the linkage of <code>std</code> from  <code>demo-simple-dylib</code> treated as its own distinct thing? In other words, why doesn&rsquo;t the compiler just let <code>simple-dylib</code>, which has already statically-linked in those crates, provide them to <code>demo-simple-dylib</code>? And you wouldn&rsquo;t be alone in thinking this: Alex Crichton, who is responsible for the basic logic in use here, made the same suggestion in <a href="https://github.com/rust-lang/rust/issues/34909">rust-lang/rust#34909</a>. I plan to explore this question more in a future blog post.
</span>
The <code>demo-simple-dylib</code> crate <em>also</em> wants to link to all the same upstream
crates, and the compiler rejects this, saying it is not legal for both the <code>simple-dylib</code> and the <code>demo-simple-dylib</code> crates to
have duplicate copies of those dependencies.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The semantics described here dates from
<a href="https://github.com/rust-lang/rfcs/blob/master/text/0404-change-prefer-dynamic.md">RFC 404</a>,
which was introduced in 2014 before Rust had even hit 1.0 status. That RFC itself
refers to the comments in the code as the documentation; those comments have moved as
the compiler has gone through various refactorings, but the most recent version can
be found here in
<a href="https://github.com/rust-lang/rust/blob/a7d6768e3b60209d4195c822ea3247482909b604/compiler/rustc_metadata/src/dependency_format.rs">rustc_metadata::dependency_format</a>
</span></p>

<p>In the absence of <code>-Cprefer-dynamic</code> and <code>--extern</code> flags (and also absent any
constraints forcing everything to be statically linked), the default logic of
the compiler when trying to decide which upstream crate types to use is as
follows:</p>

<ol>
<li><p>First try to statically link all of the upstream dependencies via their
<code>.rlib</code> libraries. If that succeeds, we are done.</p></li>
<li><p>If static linking failed, then either linking in general is impossible, or at
least one dependency will have to be a dynamic library. Since at least one
dependency has to be dynamic, the compiler, as a simple-minded tactic, tries to
satisfy as many upstream dependencies as possible via their <code>dylib</code> object
files.</p></li>
</ol>


<p>However, if one <em>does</em> provide <code>-Cprefer-dynamic</code>, then that tells the compiler
to not attempt the static link step, and instead to prefer to use <code>dylib</code>
whenever possible for its upstream dependencies. And <em>that</em> is the fix we need here:
we need <code>simple-lib.dylib</code> to prefer the <code>dylib</code> version of <code>std</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/pd/sd -C prefer-dynamic simple-dylib.rs
</span></code></pre></td></tr></table></div></figure>


<p>Once that is in place, everything else follows suit.</p>

<p>First, consider how <code>demo-simple-dylib.rs</code> is built.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/bins/ps/dsd demo-simple-dylib.rs -Lout/pd/sd
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Note that this story here is simple in part because <code>simple-dylib.rs</code>
was only compiled to one crate type. If we had generated both <code>dylib</code>
and <code>rlib</code> crates for it, <em>then</em> the presence/absence of <code>-Cprefer-dynamic</code>
would become significant for building <code>demo-simple-dylib</code>.
</span></p>

<p>Once we have established that the <code>simple-dylib</code> crate is only
available as a <code>dylib</code>, then it does not matter whether we pass
<code>-Cprefer-dynamic</code> or not when building <code>demo-simple-dylib</code>: if we leave it off,
then all that happens is the compiler will first explore trying to statically
link all of the dependencies. Once it determines it cannot (due to
<code>simple-dylib</code>), it will go back to trying to use dynamic libraries for as much
as possible, and thus it will resolve both <code>simple-dylib</code> <em>and</em> <code>std</code> to dynamic
libraries.</p>

<p>Next, we consider the way that <code>demo-simple-dylib</code> needs to be invoked:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% <span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>out/pd/sd:<span class="k">$(</span>rustc --print<span class="o">=</span>sysroot<span class="k">)</span>/lib out/bins/ps/dsd/demo-simple-dylib
</span></code></pre></td></tr></table></div></figure>


<p>The main point of interest here is that we had to add some entries to the
<code>LD_LIBRARY_PATH</code>: when the program runs, it needs to satisfy its upstream dylib
dependencies, which we just finished establishing are <code>simple-dylib</code> (in
<code>out/pd/sd</code>) and <code>std</code> (which we map to a directory by asking <code>rustc</code> itself
where those support files all live by running <code>rustc --print=sysroot</code>).</p>

<a name="Rust.libraries:..code.rlib..code."></a>
<h2>Rust libraries: <code>rlib</code></h2>

<p>Phew, that was exhausting.</p>

<p>Lets try to go through an easier case next: the Rust library type, <code>rlib</code>.</p>

<p>This is not necessarily a simple case, but it is an obvious one to deal with,
because we&rsquo;ve been discussing it this whole time; we just did not say that we
were.</p>

<p>Specifically: the <code>demo-simple-lib</code> example covered Rust&rsquo;s <code>lib</code> crate type,
which is specified as a compiler-defined choice from one of the flavors of
libraries that Rust supports. At the time of this blog post, Rust&rsquo;s <code>lib</code> crate
type maps to <code>rlib</code>, at least on my machine.</p>

<p>So, the usage patterns and issues we described up above for <code>lib</code> all apply to <code>rlib</code>.</p>

<p>For completeness, here is a diagram showing how <code>rlib</code> is used; it will look
very familiar.</p>

<div class="mermaid">
graph TD
SlSource[simple-rlib.rs]
SlObj[libsimple_rlib.rlib]
SlSource --> SlCompile((rustc))
SlCompile --generates --> SlObj
DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-rlib.rs]
DemoSlObj[demo-simple-rlib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
link -- generates --> DemoSlBin["demo-simple-rlib (exec)"]
</div>


<p>Likewise, here is the source code for the files listed in the diagram.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-rlib.rs</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;rlib&quot;</span><span class="p">]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// demo-simple-rlib.rs</span>
</span><span class='line'><span class="k">extern</span> <span class="n">crate</span> <span class="n">simple_rlib</span><span class="p">;</span>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">simple_rlib</span><span class="o">::</span><span class="n">main</span><span class="p">();</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, the command invocations that implement the diagram above.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/ps/sr simple-rlib.rs
</span><span class='line'>% ls out/ps/sr
</span><span class='line'>libsimple_rlib.rlib
</span><span class='line'>% rustc --out-dir out/bins/ps/dsr demo-simple-rlib.rs -Lout/ps/sr
</span><span class='line'>% ls out/bins/ps/dsr
</span><span class='line'>demo-simple-rlib
</span><span class='line'>% out/bins/ps/dsr/demo-simple-rlib
</span><span class='line'>Running main from simple-rlib.rs
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p>But, there are no surprises here.</p>

<a name="Static.libraries.for.non.Rust.code:..code.staticlib..code."></a>
<h2>Static libraries for non Rust code: <code>staticlib</code></h2>

<p>If you want to call Rust from another language, you can do that by compiling
your Rust code into a static library, and then linking to that static library
from your foreign program.</p>

<p>Now, for purposes of demonstration in this example, I am using Rust to implement
<code>demo-simple-staticlib</code>; but, crucially, I <strong>didn&rsquo;t have to</strong>. It could have
been written in C, or I could have used Java and JNI to interface with it. (Or
<code>simple-staticlib</code> could have been a Python extension, <em>et cetera</em>.)</p>

<p>Here&rsquo;s what our linkage picture looks like for <code>staticlib</code>:</p>

<div class="mermaid">
graph TD
SlSource[simple-staticlib.rs]
SlObj[libsimple_staticlib.a]
SlSource --> SlCompile((rustc))
SlCompile --generates --> SlObj
%% DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-staticlib.rs]
DemoSlObj[demo-simple-staticlib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
link -- generates --> DemoSlBin["demo-simple-staticlib (exec)"]
</div>


<p>If we compare this against our picture for <code>rlib</code>, the main difference
now is that there is no longer an arc from <code>rustc</code> to <code>libsimple_staticlib.a</code>.
This is actually a pretty big difference!</p>

<ol>
<li><p>The generated archive file, <code>libsimple_staticlib.a</code>, is <em>not</em> a Rust crate.
It does not have the metadata the Rust compiler would need to intepret it as
a crate. Instead, it is just another library archive, like the others
typically used in a C project.</p></li>
<li><p>When compiling <code>demo-simple-staticlib.rs</code>, we will have to pass flags to the
compiler that tell it to link to the static library. The compiler will no
longer magically figure this out for us.</p></li>
<li><p>Since <code>libsimple_staticlib.a</code> is not a Rust crate, we have to provide
explicit declarations in <code>demo-simple-staticlib.rs</code> for the functions it
provides.</p></li>
</ol>


<p>The differences above can arguably be summed up in: It is like you are
programming in C, in terms of having to deal with keeping function signatures
consistent and juggling linker flags. If you have experience with that, none of
this should seem surprising.</p>

<p>That said, here is the source code for the files in the diagram.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-staticlib.rs</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;staticlib&quot;</span><span class="p">]</span>
</span><span class='line'><span class="cp">#[no_mangle]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">extern</span> <span class="s">&quot;C&quot;</span> <span class="k">fn</span> <span class="n">staticlib_main</span><span class="p">()</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running staticlib_main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">extern</span> <span class="s">&quot;C&quot;</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">staticlib_main</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="p">{</span> <span class="n">staticlib_main</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And here are the command invocations that complete the diagram above.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/ps/ss simple-staticlib.rs
</span><span class='line'>% ls out/ps/ss
</span><span class='line'>libsimple_staticlib.a
</span><span class='line'>% rustc --out-dir out/bins/ps/dss demo-simple-staticlib.rs -Lout/ps/ss -lsimple_staticlib
</span><span class='line'>% ls out/bins/ps/dss
</span><span class='line'>demo-simple-staticlib
</span><span class='line'>% out/bins/ps/dss/demo-simple-staticlib
</span><span class='line'>Running staticlib_main from simple-staticlib.rs
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<a name="Dynamic.libraries.for.non.Rust.code:..code.cdylib..code."></a>
<h2>Dynamic libraries for non Rust code: <code>cdylib</code></h2>

<p>Conceptually so far we have covered three cells in the following 2x2 matrix,
and <code>cdylib</code> will finish the table.</p>

<table>
<thead>
<tr>
<th>            </th>
<th> Linked from Rust  </th>
<th> Linked from Non-Rust</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Static</strong>  </td>
<td>   rlib            </td>
<td>    staticlib</td>
</tr>
<tr>
<td><strong>Dynamic</strong> </td>
<td>  dylib            </td>
<td>   cdylib</td>
</tr>
</tbody>
</table>


<p>The diagram for using <code>cdylib</code> should have elements that remind you of both the table
for <code>dylib</code> and the table for <code>staticlib</code>.</p>

<div class="mermaid">
graph TD
SlSource[simple-cdylib.rs]
SlObj[libsimple_cdylib.so]
SlSource --> SlCompile((rustc))
SlCompile --generates --> SlObj
%% DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-cdylib.rs]
DemoSlObj[demo-simple-cdylib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
link -- generates --> DemoSlBin["demo-simple-cdylib (exec)"]
SlObj -. "dynamically loaded by" .- DemoSlBin
</div>


<p>Namely, here we see:</p>

<ol>
<li><p>Much like <code>demo-simple-staticlib</code>, compiling <code>demo-simple-cdylib.rs</code>
does not attempt to extract metadata from the <code>simple-cdylib.so</code> or even
treat it as a Rust crate; instead, one must provide the right linker flags to
the compiler, and the right <code>extern</code> function signatures in the source code
for <code>demo-simple-cdylib.rs</code>.</p></li>
<li><p>Much like <code>demo-simple-dylib</code>, the execution of <code>demo-simple-cdylib</code> will
itself load the shared library <code>demo-simple-cdylib.so</code> and link to its code
dynamically.</p></li>
</ol>


<p>The source code for this demostration is just like that of <code>staticlib</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// simple-cdylib.rs</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span><span class="o">=</span><span class="s">&quot;cdylib&quot;</span><span class="p">]</span>
</span><span class='line'><span class="cp">#[no_mangle]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">extern</span> <span class="s">&quot;C&quot;</span> <span class="k">fn</span> <span class="n">cdylib_main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Running cdylib_main from {}&quot;</span><span class="p">,</span> <span class="n">file</span><span class="o">!</span><span class="p">());</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c1">// demo-simple-cdylib.rs</span>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">extern</span> <span class="s">&quot;C&quot;</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">cdylib_main</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="p">{</span> <span class="n">cdylib_main</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The command sequence here is interesting: we are no longer forced to use <code>-C prefer-dynamic</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rustc --out-dir out/ps/sc simple-cdylib.rs
</span><span class='line'>% ls out/ps/sc
</span><span class='line'>libsimple_cdylib.so
</span><span class='line'>% rustc --out-dir out/bins/ps/dsc demo-simple-cdylib.rs -Lout/ps/sc -lsimple_cdylib
</span><span class='line'>% ls out/bins/ps/dsc
</span><span class='line'>demo-simple-cdylib
</span><span class='line'>% <span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>out/ps/sc out/bins/ps/dsc/demo-simple-cdylib
</span><span class='line'>Running cdylib_main from simple-cdylib.rs
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This hypothesis is one of many items that I want to follow up on in a future post.
</span>
I believe this is because we end up treating the two components
(<code>simple-cdylib.so</code> and <code>demo-simple-dylib</code>) as completely divorced entities:
thus, they each get <em>their own copy</em> of the functions they use from the Rust standard library statically
linked into them.</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>That was quite a romp!</p>

<p>And yet, we have not even gotten to some of the hairier stuff, like:</p>

<ul>
<li>mixing distinct upstream crate types into the same project,</li>
<li>having multiple crate-types for the same crate available,</li>
<li>using <code>--extern</code> to specify which crate type should be used for a given crate type,</li>
<li>mixing crates built with and without <code>-Cprefer-dynamic</code> (how to get it to work today, and how should it work in ideal world?), or</li>
<li>varying whether the program will statically or dynamically link to the platforms C runtime.</li>
</ul>


<p>Furthermore, I did not really dig into what static linking <em>means</em>, especially
when it comes to crate types like <code>rlib</code>, which explicitly <em>do not have</em>
link-time dependencies. I want to elaborate on that too, preferably by demonstrating
how to use <code>objdump</code> to learn things about the generated code.</p>

<p>So, lots of material for future posts.</p>

<p>(And also, lots of opportunities to try to clean up the presentation of this
post.)</p>

<a name="Appendix:.Who.is.using.that.library."></a>
<h2>Appendix: Who is using that library?</h2>

<p>Consider this diagram:</p>

<div class="mermaid">
graph TD
SlObj[libsimple_lib.rlib]
DemoSlCompile -.finds file.-> SlObj
DemoSlSource[demo-simple-lib.rs]
DemoSlObj[demo-simple-lib.obj]
DemoSlSource --> DemoSlCompile((rustc))
SlObj --> link
DemoSlCompile -- generates --> DemoSlObj
subgraph "implicit &nbsp;&nbsp; link-step"
DemoSlObj --> link
link((link))
end
</div>


<p>Here is an important question you should ask yourself: is <code>libsimple_lib.rlib</code>
actually used by the linker? Or is it solely used as input to <code>rustc</code> (i.e.,
potentially used in the generation of <code>demo-simple-lib.obj</code> itself). Or is it
used by both <code>rustc</code> <em>and</em> the linker?</p>

<p>We can test this question directly, with some slight tweaks to our commands.</p>

<a name="Proving.the.link.step.s.dependence.on.the.library"></a>
<h3>Proving the link step&rsquo;s dependence on the library</h3>

<p>First, we can test whether its used by the linker at all by separating the link
invocation from the rest of the compiler steps, and then modifying it and
running it on its own.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% mkdir -p out/sl out/bins/ps/dsl2step
</span><span class='line'>% rustc --out-dir out/ps/sl simple-lib.rs
</span><span class='line'>% ls out/ps/sl
</span><span class='line'>libsimple_lib.rlib
</span><span class='line'>% <span class="nv">LINKER_COMMAND</span><span class="o">=</span><span class="k">$(</span>rustc --out-dir out/bins/ps/dsl2step demo-simple-lib.rs -Lout/ps/sl -Csave-temps --print<span class="o">=</span>link-args -Ccodegen-units<span class="o">=</span>1<span class="k">)</span>
</span><span class='line'>% ls out/bins/ps/dsl2step
</span><span class='line'>demo-simple-lib                                                demo-simple-lib.demo_simple_lib.66aa33f3-cgu.0.rcgu.o
</span><span class='line'>demo-simple-lib.demo_simple_lib.66aa33f3-cgu.0.rcgu.bc         demo-simple-lib.hlsxcd1s0pxo20a.rcgu.bc
</span><span class='line'>demo-simple-lib.demo_simple_lib.66aa33f3-cgu.0.rcgu.no-opt.bc  demo-simple-lib.hlsxcd1s0pxo20a.rcgu.o
</span><span class='line'>% ./out/bins/ps/dsl2step/demo-simple-lib
</span><span class='line'>Running main from simple-lib.rs
</span><span class='line'>% rm ./out/bins/ps/dsl2step/demo-simple-lib
</span><span class='line'>% <span class="nb">eval</span> <span class="nv">$LINKER_COMMAND</span>
</span><span class='line'>% ./out/bins/ps/dsl2step/demo-simple-lib
</span><span class='line'>Running main from simple-lib.rs
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p>The significance of the above sequence: It runs <code>rustc -Csave-temps --print=link-args</code> which will preserve the generated object files and also print out the linker invocation it runs.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In practice when doing these kinds of experiments, you should not blindly use <code>eval</code>  in the manner I have shown here,
but instead echo the linker command to the screen and confirm that it is something you trust running.
</span>
We can run the generated binary, delete the binary, and then re-run that linker
command ourselves (<code>eval $LINKER_COMMAND</code>), and re-run the binary again. This
confirms that this linker invocation does indeed generate that binary.</p>

<p>With that in place, one way we could exercise the linker&rsquo;s use of the file: we
could just delete <code>libsimple_lib.rlib</code>, and run the original linker invocation:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% <span class="nb">eval</span> <span class="nv">$LINKER_COMMAND</span>
</span><span class='line'>% rm out/ps/sl/libsimple_lib.rlib
</span><span class='line'>% ls out/ps/sl/
</span><span class='line'>% <span class="nb">eval</span> <span class="nv">$LINKER_COMMAND</span>
</span><span class='line'>/usr/bin/ld: cannot find /media/pnkfelix/Rust/Linking/out/ps/sl/libsimple_lib.rlib: No such file or directory
</span><span class='line'>collect2: error: ld returned <span class="m">1</span> <span class="nb">exit </span>status
</span></code></pre></td></tr></table></div></figure>


<p>Another slightly more complicated way we could expose the dependence of our
object code on that file: We can remove the reference to <code>libsimple_lib.rlib</code>
from the linker invocation, and run the resulting new linker invocation:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% <span class="nv">NEW_COMMAND</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&quot;$LINKER_COMMAND&quot;</span> <span class="p">|</span> sed -e <span class="s1">&#39;s@&quot;-Wl,-Bstatic&quot; .*/libsimple_lib.rlib&quot;@@&#39;</span><span class="k">)</span>
</span><span class='line'>% <span class="nb">eval</span> <span class="nv">$NEW_COMMAND</span>
</span><span class='line'>/usr/bin/ld: out/bins/ps/dsl2step/demo-simple-lib.demo_simple_lib.66aa33f3-cgu.0.rcgu.o: in <span class="k">function</span> <span class="sb">`</span>demo_simple_lib::main<span class="s1">&#39;:</span>
</span><span class='line'><span class="s1">demo_simple_lib.66aa33f3-cgu.0:(.text._ZN15demo_simple_lib4main17h9794b393d760d697E+0x3): undefined reference to `simple_lib::main&#39;</span>
</span><span class='line'>collect2: error: ld returned <span class="m">1</span> <span class="nb">exit </span>status
</span></code></pre></td></tr></table></div></figure>


<p>This gives you an idea of the kinds of nasty error messages you have to deal
with when you start playing games with your build artifacts: The linker is
rightfully complaining that the generated object code for
<code>demo_simple_lib::main</code> has some reference to <code>simple_lib::main</code> (indeed,the
very definition of the former is just a single invocation of the latter), and
yet that reference cannot be satisfied. (It is up to the user to read that
message and infer that the core problem is that the linker is no longer
receiving the path to <code>libsimple_lib.rlib</code> as one of its command line
arguments.)</p>

<a name="Proving.the.compiler.s.dependence.on.the.library"></a>
<h3>Proving the compiler&rsquo;s dependence on the library</h3>

<p>The previous section established that the linker needs the <code>.rlib</code> file in
place. But, maybe that&rsquo;s only necessary for the link step alone, and <code>rustc</code>
itself doesn&rsquo;t need the actual file?</p>

<p>We can test this theory too, in a similar form of direct experimentation
on the build artifacts.</p>

<p>First, lets try removing the file (same as illustrated in the previous section)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>% rm -f out/ps/sl/libsimple_lib.rlib
</span><span class='line'>% ls out/ps/sl
</span><span class='line'>% rustc --out-dir out/bins/ps/dsl demo-simple-lib.rs -Lout/ps/sl
</span><span class='line'>error<span class="o">[</span>E0463<span class="o">]</span>: can<span class="s1">&#39;t find crate for `simple_lib`</span>
</span><span class='line'><span class="s1"> --&gt; demo-simple-lib.rs:1:1</span>
</span><span class='line'><span class="s1">  |</span>
</span><span class='line'><span class="s1">1 | extern crate simple_lib;</span>
</span><span class='line'><span class="s1">  | ^^^^^^^^^^^^^^^^^^^^^^^^ can&#39;</span>t find crate
</span><span class='line'>
</span><span class='line'>error: aborting due to previous error
</span><span class='line'>
</span><span class='line'>For more information about this error, try <span class="sb">`</span>rustc --explain E0463<span class="sb">`</span>.
</span><span class='line'>%
</span></code></pre></td></tr></table></div></figure>


<p>This shows that the compiler is <em>definitely</em> using the file <code>libsimple_lib.rlib</code>
as part of its compilation of <code>demo-simple-lib.rs</code>.</p>

<p>If we try to force the compiler to make forward progress by giving it a dummy file,
it will still complain:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="o">%</span> <span class="n">touch</span> <span class="n">out</span><span class="o">/</span><span class="n">ps</span><span class="o">/</span><span class="n">sl</span><span class="o">/</span><span class="n">libsimple_lib</span><span class="p">.</span><span class="n">rlib</span>
</span><span class='line'><span class="o">%</span> <span class="n">ls</span> <span class="o">-</span><span class="n">s</span> <span class="n">out</span><span class="o">/</span><span class="n">ps</span><span class="o">/</span><span class="n">sl</span><span class="o">/</span>
</span><span class='line'><span class="n">total</span> <span class="mi">0</span>
</span><span class='line'><span class="mi">0</span> <span class="n">libsimple_lib</span><span class="p">.</span><span class="n">rlib</span>
</span><span class='line'><span class="o">%</span> <span class="n">rustc</span> <span class="o">--</span><span class="n">out</span><span class="o">-</span><span class="n">dir</span> <span class="n">out</span><span class="o">/</span><span class="n">bins</span><span class="o">/</span><span class="n">ps</span><span class="o">/</span><span class="n">dsl</span> <span class="n">demo</span><span class="o">-</span><span class="n">simple</span><span class="o">-</span><span class="n">lib</span><span class="p">.</span><span class="n">rs</span> <span class="o">-</span><span class="n">Lout</span><span class="o">/</span><span class="n">ps</span><span class="o">/</span><span class="n">sl</span>
</span><span class='line'><span class="n">error</span><span class="p">[</span><span class="n">E0786</span><span class="p">]</span><span class="o">:</span> <span class="n">found</span> <span class="n">invalid</span> <span class="n">metadata</span> <span class="n">files</span> <span class="k">for</span> <span class="n">crate</span> <span class="err">`</span><span class="n">simple_lib</span><span class="err">`</span>
</span><span class='line'> <span class="o">--&gt;</span> <span class="n">demo</span><span class="o">-</span><span class="n">simple</span><span class="o">-</span><span class="n">lib</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="mi">1</span>
</span><span class='line'>  <span class="o">|</span>
</span><span class='line'><span class="mi">1</span> <span class="o">|</span> <span class="k">extern</span> <span class="n">crate</span> <span class="n">simple_lib</span><span class="p">;</span>
</span><span class='line'>  <span class="o">|</span> <span class="o">^^^^^^^^^^^^^^^^^^^^^^^^</span>
</span><span class='line'>  <span class="o">|</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">note</span><span class="o">:</span> <span class="n">failed</span> <span class="n">to</span> <span class="n">mmap</span> <span class="n">file</span> <span class="err">&#39;</span><span class="o">/</span><span class="n">media</span><span class="o">/</span><span class="n">pnkfelix</span><span class="o">/</span><span class="n">Rust</span><span class="o">/</span><span class="n">Linking</span><span class="o">/</span><span class="n">out</span><span class="o">/</span><span class="n">ps</span><span class="o">/</span><span class="n">sl</span><span class="o">/</span><span class="n">libsimple_lib</span><span class="p">.</span><span class="n">rlib</span><span class="err">&#39;</span><span class="o">:</span> <span class="n">memory</span> <span class="n">map</span> <span class="n">must</span> <span class="n">have</span> <span class="n">a</span> <span class="n">non</span><span class="o">-</span><span class="n">zero</span> <span class="n">length</span>
</span><span class='line'>
</span><span class='line'><span class="n">error</span><span class="o">:</span> <span class="n">aborting</span> <span class="n">due</span> <span class="n">to</span> <span class="n">previous</span> <span class="n">error</span>
</span><span class='line'>
</span><span class='line'><span class="n">For</span> <span class="n">more</span> <span class="n">information</span> <span class="n">about</span> <span class="n">this</span> <span class="n">error</span><span class="p">,</span> <span class="n">try</span> <span class="err">`</span><span class="n">rustc</span> <span class="o">--</span><span class="n">explain</span> <span class="n">E0786</span><span class="err">`</span><span class="p">.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Upon reflection, this all makes perfect sense: As part of compiling
<code>demo-simple-lib.rs</code>, the compiler is going to reference external metadata (i.e.
the function signatures and type definitions from the <code>simple-lib</code> crate).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Visuals redux: Getting mermaid going]]></title>
    <link href="http://blog.pnkfx.org/blog/2022/05/10/visuals-redux-getting-mermaid-going/"/>
    <updated>2022-05-10T16:24:52-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2022/05/10/visuals-redux-getting-mermaid-going</id>
    <content type="html"><![CDATA[<p>This is just a post where I&rsquo;ll either be happy or sad, depending on whether Github pages manages to
render the same content the way that I see it on my local system.</p>

<div class="mermaid">
graph TD

A["Felix tries to add Mermaid support to his blog"]
B["Felix previews blog locally"]
C["Felix tries to deploy blog to github pages"]
A --> B
B --broke--> A
B --works--> C

C--works-->D[Happy]

C--broke-->E(Sad);
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What is Rust's Hole Purpose?]]></title>
    <link href="http://blog.pnkfx.org/blog/2022/02/09/what-is-rusts-hole-purpose/"/>
    <updated>2022-02-09T13:00:00-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2022/02/09/what-is-rusts-hole-purpose</id>
    <content type="html"><![CDATA[<p>There is an adage in the business world that goes something like this:</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This quote is attributed to Theodore Levitt, but there is <a href="https://quoteinvestigator.com/2019/03/23/drill/">significant evidence</a> that the
adage predated his use of it.
</span></p>

<blockquote><p>People don&rsquo;t want to buy a quarter-inch drill, they want a quarter-inch hole.</p></blockquote>

<p>It is a good line.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Some people I talk to make the leap from safety to another property: <em>security</em>.
The two topics are related, since safety issues can sometimes be exploited and thus
yield security issues. But you can theoretically achieve security atop an unsafe language; and safety alone does not ensure security. So it is a messy relationship at best.
</span></p>

<p>The adage came to my mind recently in a discussion of Rust&rsquo;s selling points.
An oft-cited selling point, at least for a Programming Language enthusiast like myself, is that Rust offers <em>safety</em>.</p>

<!-- more -->


<p>I was not familiar with the adage before last year. I first heard it used as the
punchline to a significantly longer parable, set at the keynote for a sales convention for a drill company.
The lesson of the adage is that to be customer-focused, you
must keep in mind that drills are only a <em>means to an end</em> for your customer.</p>

<p>Safety is important: it eliminates a significant class of bugs that
plague software written in low-level systems languages.</p>

<p>But, thinking of the drill/hole adage, I stopped and asked myself: &ldquo;Who <em>wants</em> safety? Is it an end in itself? If it is merely a means to an end, then to <em>what end</em>?&rdquo;</p>

<p>At this point, while reflecting on that topic, I decided to look more into the origins of the drill/hole adage; that diversion led me to a lovely <a href="https://www.websearchsocial.com/why-that-whole-people-dont-want-a-drill-they-want-a-hole-thing-doesnt-go-far-enough/">post critiquing the adage</a>, saying it &ldquo;doesn&rsquo;t go far enough.&rdquo; The heart of the argument there is that people don&rsquo;t want <em>holes</em> either. The hole is itself another means to an end, such as hooks or shelving.
But do people want hooks and shelving? No, they want to store objects on the wall.
Why?
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
A shelf of objects can also serve as decor; my favorite walls are filled with books.
</span>
Because they want room to store <em>more things</em>, or they want to be able to fetch and replace things more efficiently, yielding <em>more time</em>.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The <a href="https://www.websearchsocial.com/why-that-whole-people-dont-want-a-drill-they-want-a-hole-thing-doesnt-go-far-enough/">post</a> includes the caveat that intermediate results
like the hole are not irrelevant. Its just important to keep the end-goal somewhere
in your mind, if only in the back of your mind, as you identify your more immediate (and usually intermediate) goals.
</span></p>

<p>That is what people want: Extra capacity for &ldquo;stuff&rdquo;, or to reduce the time they
spend searching through clutter.</p>

<p>That is such an important point, and I think it provides the right perspective that we will need to answer the question of &ldquo;What is Rust&rsquo;s hole purpose?&rdquo; (Or, if you prefer a pun-free version: &ldquo;What is Rust&rsquo;s value proposition?&rdquo;)</p>

<!-- I do not think this section serves the overall document. Its just filler. So I'm killing it.

## The Pillars

Under "Why Rust?", the language website offers three pillars:

* Performance
* Reliability
* Productivity

We can already see a shift in perspective: "safety" is listed *under* "reliabilty", as a component of that feature.

There is a reason the team is showing all three pillars at once. The underlying
point is that you have to weigh tradeoffs.

Historically, maximizing performance meant that you had to work in a language
like C or C++. That risks sacrificing reliabilty; if you wanted to recover
reliability, you had to spend more time architecting and validating your system
to avoid the safety pitfalls suffered by those languages.

As just-in-time compiler and memory-management technology has improved, managed
languages like Java are narrowing the performance gap when compared with C, *if*
you are willing to accept the garbage-collection overhead (either in time or in
memory usage), and you also need to know how to write code in a manner that
meshes well with your runtime environment so that it will optimize well.

So in either case, if you want to deliver performance, then either reliability
or productivity will suffer.

Rust's claim is that you can get all three. But how?

-->


<a name="The.Promise.s..of.Rust"></a>
<h2>The Promise(s) of Rust</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I am using &ldquo;sub-&rdquo; and &ldquo;super-&rdquo; here in a mathematical sense, as in &ldquo;every safe Rust program is also an Unsafe Rust program, but there are some Unsafe Rust programs that are not part of safe Rust.&rdquo; There is no value judgement being made as to one being &ldquo;superior&rdquo; to the other.
</span></p>

<p>Rust provides two distinct languages: the safe Rust (sub)language, and the Unsafe Rust (super)language. You can read the <a href="https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html">Rustonomicon</a> for more discussion of this distinction.</p>

<p>An over-simplified way of describing the benefits of the safe Rust language is
this &ldquo;promise&rdquo;: You will get <em>predictable</em> behavior from your program. If you
write a program in safe Rust, it will not surprise you.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
After all, if a program were incapable of surprising anyone, then would it be worth
executing in the first place?
</span>
But, that promise is a lie: There&rsquo;s plenty of ways to observe unpredictable
outcomes, in most any programming language of interest. (Consider for example <a href="https://en.wikipedia.org/wiki/Pseudorandom_number_generator">psuedorandom number generation</a>.)</p>

<p>Here is a somewhat improved promise: You will never get <a href="https://en.wikipedia.org/wiki/Undefined_behavior">Undefined Behavior</a>
from a safe Rust program. It won&rsquo;t ever access memory after its been freed, and
it won&rsquo;t ever have two threads racing to read and write the same location in
memory.</p>

<p>But in fact, this is still somewhat of a lie!</p>

<p>For one thing, we allow crates written in safe Rust to link to crates that are
written in Unsafe Rust. Should that be considered an instance of a &ldquo;safe Rust&rdquo;
program? If it is, then its easy to see a counter-example to the improved
promise: just have safe crate that calls out to a helper function <code>oops</code> in an
unsafe crate, where <code>oops</code> demonstrates undefined behavior.</p>

<p>Even if you say &ldquo;no, I do not consider such a program to be an instance of safe
Rust. You need <em>all</em> of your crates to be written in safe Rust to make me
happy&rdquo;, you will still run afoul of problems. (1.) Rust&rsquo;s standard library is
using unsafe code that might not always maintain global safety invariants. Even
worse, (2.) the Rust compiler itself may generate incorrect output.</p>

<p>So, your program might <em>still</em> exhibit Undefined Behavior even if you restrict
yourself to crate graphs where all crates are written in safe Rust.</p>

<p>Such an outcome is not what anyone <em>desires</em>; but it is a reality that we have
to deal with, at least with the state of the art today.</p>

<!-- Do I need to say this? Lets see how it looks without this.

Software development is a process of continual refinement, striving towards
idealized goals. Those idealized goals themselves may change over time. Part of
that process is that expecting mistakes to happen, and having plans in place to
correct errors in a timely fashion after they have been detected.
-->


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This title implicitly references the work of <a href="https://www2.ccs.neu.edu/racket/pubs/icfp2002-ff.pdf">Findler and Felleisen (2002)</a> on
using contracts to assign proper <em>blame</em> when one is dealing with higher-order functions.</p>

<p></span></p>

<a name="Blame.Assignment"></a>
<h2>Blame Assignment</h2>

<p>Here is my favorite statement of Rust&rsquo;s promise: Undefined Behavior is never a
bug in your (safe) code.</p>

<p>Now <em>this</em> is a promise I can get behind.</p>

<p>This is important, because it clearly delineates the
<a href="https://en.wikipedia.org/wiki/Trusted_computing_base">&ldquo;Trusted Computing Base&rdquo;</a>
for your program.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In other words, The TCB is TCB: The Trusted Computing Base is Taking Care of Business.
</span></p>

<p>In safe Rust, you are trusting the compiler and standard library to get the
safety conditions right. You expect that any crates you link to will properly
ensure any preconditions necessary for <em>their</em> <code>unsafe</code> blocks, if any.</p>

<p>Why does this matter: Compare against other environments, like C projects, where
people can debate for ages about whether a given example is violating the rules
of an API or of the language itself, and that leads to issues lying unaddressed,
because its unclear <em>who is responsible</em> for the issue.</p>

<p>In Rust, this occurs far less frequently. If someone finds unsound behavior via
a program example that has no occurrences of <code>unsafe { ... }</code>, then the Rust
community tends to immediately say &ldquo;that must be a bug!&rdquo;, and the only task then
is to identify whether it is from some <code>unsafe { ... }</code> code elsewhere, or if
the Rust compiler itself has an issue.</p>

<p>Of course, Rust is not alone in enjoying this property. <em>Any</em> safe language
worth its salt can make the same statement. But Rust is different, in that we
make it really easy for people who <em>want</em> to drop into the Unsafe Rust
superlanguage to do so.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Again, no value judgement is being made here. Really! Safe and unsafe Rust are mathematically incomparable when it comes to inherent value!
</span>
That lets developers get their work done faster,
because they can hyper-optimize their generated machine code. Or they can
easily call out to a foreign library and avoid implementing a tricky algorithm in the first place!</p>

<p>I claim: Compared to developers using unsafe languages, safe Rust developers
spend less time debating about who is responsible when soundness issues arise.
Compared to developers using safe languages, Unsafe Rust developers spend less
time figuring out how to deliver a performant solution.</p>

<p>The end value provided by Rust to its developers (and thus to <em>their</em> customers
and employers) is <em>less time</em> arguing linguistic minutia and <em>less time</em>
wrestling with a managed language environment, and <em>more time</em> focused on what
actually matters to each of those developers (be it business logic, or family
time).</p>

<p>But, notice that I used two distinct categories for the subjects of the two
claims. Am I comfortable strengthening my claim? Can I just say &ldquo;Rust developers
spend less time debating about who is responsible when issues arise, and they
spend less time figuring out how to get a performant solution into shape&rdquo;?</p>

<a name="The.Holes.in.the.Argument"></a>
<h2>The Holes in the Argument</h2>

<p>I would like to make that stronger claim. I think we have some evidence to support
it. But we are not all the way there yet.</p>

<a name="From.safe.to.unsafe"></a>
<h3>From safe to unsafe</h3>

<p>To me, the biggest open problem is: How does one make the transition from safe
Rust developer to unsafe Rust developer? How do you prove to yourself that your
<code>unsafe { ... }</code> code is not introducing an soundness issue?</p>

<p>We have some ongoing work in this space, but it is not a solved problem.</p>

<a name="How.to.stay.safe"></a>
<h3>How to stay safe</h3>

<p>The other obvious open problem is: When is safe Rust not performant enough, and
why?</p>

<p>There are some inherent overheads that safe Rust is simply going to pay (e.g.
bounds checking on array accesses). Some of those cases can be side-stepped in
many cases by better understanding of what the language offers (e.g. iterating
rather than indexing will skip the bounds checks), which is arguably an instance
of &ldquo;wrestling with your environment&rdquo; to reap more performance.</p>

<p>Then there are overheads that are incidental rather than inherent. The Rust
developers have tried to leave many doors open for future improvements to our
output code quality. (Some of these cases overlap with our need for better ways
to catch bugs in <code>unsafe</code> code. Others are a matter of &ldquo;just&rdquo; putting in the
work.)</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>If you are interested in helping solve any of these problems, please reach
out!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why I use a debugger]]></title>
    <link href="http://blog.pnkfx.org/blog/2022/01/10/why-i-use-a-debugger/"/>
    <updated>2022-01-10T11:12:57-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2022/01/10/why-i-use-a-debugger</id>
    <content type="html"><![CDATA[<p>I have been thinking about the Rust debugging experience, and I want to try
tease apart what value a debugger provides to me.</p>

<!-- more -->


<p>Last year, I gave a talk at <a href="https://plus.qconferences.com/plus2021/presentation/reversible-debugging-rr">QCon</a> that promoted the use of <a href="https://rr-project.org/"><code>rr</code></a> as a tool
for exploring Rust code. I wanted to convey an <em>excitement</em> about debugging,
about using this tool to dive into the weeds of your program&rsquo;s behavior.</p>

<p>Since then, I have continued to talk to developers, promoting <code>rr</code> (and the
associated service <a href="https://pernos.co/">pernos.co</a>). And I heard Rust developers say that they are
happy with their experience using instrumentation such as logging statements or
the <a href="https://tracing.rs/tracing/">tracing</a> infrastructure.</p>

<p>I have to agree: Logging statements <em>are</em> useful, and sometimes they are all you
need. Here is a great quote from &ldquo;The Practice of Programming&rdquo;, by Kernighan and
Pike:</p>

<blockquote><p>As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging statements stay with the program; debugging sessions are transient.</p></blockquote>

<p>This quote is apt for many reasons; I will revisit it again before the end of
this post.</p>

<p>I do not know the typical way that people use debuggers. But I can imagine it
looks much like the image depicted above: you start your program, you use a
single-step command to go through it line by line, and you examine raw memory
dumps to try to figure out what the machine is doing. After that initial
exploration, you might set breakpoints at specific lines of code, and then tell
the debugger to continue running until it hits any of those breakpoints.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Advanced debugger users will set <em>conditional</em> breakpoints, which only halt the
program if a specific predicate holds when it hits the breakpoint, or even
<em>scripted</em> breakpoints, which will automatically execute a series of debugger
commands each time they hit the breakpoint. One neat trick is that you often can
end a script with <code>continue</code>, so that it seems as though the program never
stopped at all, except for the side-effects on the debugger itself (such as
setting <em>other</em> breakpoints).
</span></p>

<p>But that typical usage pattern doesn&rsquo;t really provide much value over just
adding log statements. If all you want to do is learn what steps the computer
took, and what data was in certain variables at those steps, printing to a log
<em>is</em> a better way to achieve that.</p>

<p>So, why am I advocating for more people to include a debugger as one of the tools
to keep ready on their Rust development utility belt?</p>

<p>There are four main features that a debugger gives me that are not always
fulfilled by adding log statements:</p>

<ul>
<li><a href="#Object.Code.Inspection">object code inspection</a>,</li>
<li><a href="#Raw.Control-Flow">raw control-flow</a>,</li>
<li><a href="#Memory.Exploration">memory exploration</a>, and</li>
<li><a href="#Hardware.Watchpoints">hardware watchpoints</a>.</li>
</ul>


<p>Of the four, i think hardware watchpoints are the best example of a capability
that is both broadly useful and not typically available outside of a debugger.
I will delve into each of these in turn below.</p>

<a name="Object.Code.Inspection"></a>
<h2>Object Code Inspection</h2>

<p>By &ldquo;object code inspection&rdquo;, I mean that I can attach a debugger to any binary,
without having to recompile anything. When your workflow is to add new print
statements each time you want to inspect something new, that means editing your
code and recompiling it. That edit-recompile-debug cycle has two problems: it can
be slow (especially the recompilation step). Worse still, the edits can cause
bugs to mysteriously go away, aka the <a href="https://en.wikipedia.org/wiki/Heisenbug">&ldquo;observer effect&rdquo;</a>.
(To be fair, using a debugger can also cause those <a href="https://en.wikipedia.org/wiki/Heisenbug">Heisenbugs</a> to change
behavior. This is where tools like <a href="https://rr-project.org/"><code>rr</code></a> can really shine.)</p>

<p>How valuable is &ldquo;object code inspection&rdquo;? I have given two reasons to avoid the
edit-recompile steps: reduced latency, and reducing the observer effect.</p>

<p><em>Honestly:</em> It is not a frequent need for my current work. Much of my work
involves either fixing bugs that reproduce readily in the face of source code
changes, or adding features (which inherently requires source code changes).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
However, in practice this can be very
painful: We do not have much support for building an unoptimized <code>rustc</code> (it has
a <em>very</em> long bootstrap time), but once you enable optimizations, the debugging
experience degrades quite a bit in Rust today.
</span></p>

<p>There is one important exception here: <code>rustc</code> itself has a long bootstrap time;
so I have often <em>tried</em> to use a debugger to debug <code>rustc</code> itself, rather than
rely on an edit-recompile-debug cycle.</p>

<a name="Raw.Control-Flow"></a>
<h2>Raw Control-Flow</h2>

<p>By &ldquo;raw control-flow&rdquo;, I mean that one can step through the individual assembly
code instructions to see exactly what the machine is executing.</p>

<p>For example, at a method invocation, one can step forward and discover how
exactly to which function that invocation dispatches as it goes through <code>Deref</code>
implementations until it finally reaches the target method.</p>

<p>As another example, one can step through the the instructions corresponding to
the subcomponents of a <code>match</code> pattern. This way, one might discover which parts
matched and which failed to match, and in what order they were evaluated.</p>

<p>Here is a concrete example of the latter:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">P</span> <span class="p">{</span> <span class="n">a</span><span class="o">:</span> <span class="n">char</span><span class="p">,</span> <span class="n">b</span><span class="o">:</span> <span class="n">char</span><span class="p">,</span> <span class="n">c</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="kt">str</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">p</span> <span class="o">=</span> <span class="n">P</span> <span class="p">{</span> <span class="n">a</span><span class="o">:</span> <span class="sc">&#39;h&#39;</span><span class="p">,</span> <span class="n">b</span><span class="o">:</span> <span class="sc">&#39;i&#39;</span><span class="p">,</span> <span class="n">c</span><span class="o">:</span> <span class="s">&quot;world&quot;</span> <span class="p">};</span>
</span><span class='line'>    <span class="n">foo</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">p</span><span class="o">:</span> <span class="n">P</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">match</span> <span class="n">p</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">P</span> <span class="p">{</span> <span class="n">b</span><span class="o">:</span> <span class="sc">&#39;i&#39;</span><span class="p">,</span> <span class="n">a</span><span class="o">:</span> <span class="sc">&#39;y&#39;</span><span class="p">,</span> <span class="n">c</span> <span class="p">}</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;yi, {}&quot;</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span>
</span><span class='line'>        <span class="n">P</span> <span class="p">{</span> <span class="n">a</span><span class="o">:</span> <span class="sc">&#39;h&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="p">}</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;h{}, {}&quot;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span>
</span><span class='line'>        <span class="n">_</span> <span class="o">=&gt;</span> <span class="n">panic</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;unmatched&quot;</span><span class="p">),</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>After compiling the above with debuginfo enabled and running it under <code>gdb</code>,
I can investigate the body of <code>foo</code> while its running:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">step</span>
</span><span class='line'><span class="n">boom</span><span class="o">::</span><span class="n">foo</span> <span class="p">(</span><span class="n">p</span><span class="o">=</span><span class="p">...)</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">9</span>
</span><span class='line'><span class="mi">9</span>     <span class="k">match</span> <span class="n">p</span> <span class="p">{</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">disassemble</span>
</span><span class='line'><span class="n">Dump</span> <span class="n">of</span> <span class="n">assembler</span> <span class="n">code</span> <span class="k">for</span> <span class="n">function</span> <span class="n">_ZN4boom3foo17h3035bcff6328b12bE</span><span class="o">:</span>
</span><span class='line'>   <span class="mh">0x000055555555db70</span> <span class="o">&lt;+</span><span class="mi">0</span><span class="o">&gt;:</span>   <span class="n">sub</span>    <span class="err">$</span><span class="mh">0x128</span><span class="p">,</span><span class="o">%</span><span class="n">rsp</span>
</span><span class='line'>   <span class="mh">0x000055555555db77</span> <span class="o">&lt;+</span><span class="mi">7</span><span class="o">&gt;:</span>   <span class="n">mov</span>    <span class="o">%</span><span class="n">rdi</span><span class="p">,</span><span class="mh">0x38</span><span class="p">(</span><span class="o">%</span><span class="n">rsp</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mh">0x000055555555db7c</span> <span class="o">&lt;+</span><span class="mi">12</span><span class="o">&gt;:</span>    <span class="n">cmpl</span>   <span class="err">$</span><span class="mh">0x69</span><span class="p">,</span><span class="mh">0x14</span><span class="p">(</span><span class="o">%</span><span class="n">rdi</span><span class="p">)</span>
</span><span class='line'>   <span class="mh">0x000055555555db80</span> <span class="o">&lt;+</span><span class="mi">16</span><span class="o">&gt;:</span>  <span class="n">jne</span>    <span class="mh">0x55555555db8d</span> <span class="o">&lt;</span><span class="n">_ZN4boom3foo17h3035bcff6328b12bE</span><span class="o">+</span><span class="mi">29</span><span class="o">&gt;</span>
</span><span class='line'>   <span class="mh">0x000055555555db82</span> <span class="o">&lt;+</span><span class="mi">18</span><span class="o">&gt;:</span>  <span class="n">mov</span>    <span class="mh">0x38</span><span class="p">(</span><span class="o">%</span><span class="n">rsp</span><span class="p">),</span><span class="o">%</span><span class="n">rax</span>
</span><span class='line'>   <span class="mh">0x000055555555db87</span> <span class="o">&lt;+</span><span class="mi">23</span><span class="o">&gt;:</span>  <span class="n">cmpl</span>   <span class="err">$</span><span class="mh">0x79</span><span class="p">,</span><span class="mh">0x10</span><span class="p">(</span><span class="o">%</span><span class="n">rax</span><span class="p">)</span>
</span><span class='line'>   <span class="mh">0x000055555555db8b</span> <span class="o">&lt;+</span><span class="mi">27</span><span class="o">&gt;:</span>  <span class="n">je</span>     <span class="mh">0x55555555db9d</span> <span class="o">&lt;</span><span class="n">_ZN4boom3foo17h3035bcff6328b12bE</span><span class="o">+</span><span class="mi">45</span><span class="o">&gt;</span>
</span><span class='line'>   <span class="mh">0x000055555555db8d</span> <span class="o">&lt;+</span><span class="mi">29</span><span class="o">&gt;:</span>  <span class="n">mov</span>    <span class="mh">0x38</span><span class="p">(</span><span class="o">%</span><span class="n">rsp</span><span class="p">),</span><span class="o">%</span><span class="n">rax</span>
</span><span class='line'>   <span class="mh">0x000055555555db92</span> <span class="o">&lt;+</span><span class="mi">34</span><span class="o">&gt;:</span>  <span class="n">cmpl</span>   <span class="err">$</span><span class="mh">0x68</span><span class="p">,</span><span class="mh">0x10</span><span class="p">(</span><span class="o">%</span><span class="n">rax</span><span class="p">)</span>
</span><span class='line'>   <span class="mh">0x000055555555db96</span> <span class="o">&lt;+</span><span class="mi">38</span><span class="o">&gt;:</span>  <span class="n">je</span>     <span class="mh">0x55555555dbeb</span> <span class="o">&lt;</span><span class="n">_ZN4boom3foo17h3035bcff6328b12bE</span><span class="o">+</span><span class="mi">123</span><span class="o">&gt;</span>
</span><span class='line'>   <span class="mh">0x000055555555db98</span> <span class="o">&lt;+</span><span class="mi">40</span><span class="o">&gt;:</span>  <span class="n">jmp</span>    <span class="mh">0x55555555dc6e</span> <span class="o">&lt;</span><span class="n">_ZN4boom3foo17h3035bcff6328b12bE</span><span class="o">+</span><span class="mi">254</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In the above, we can see three comparison instructions: a comparison of <code>0x14(%rdi)</code> with <code>$0x69</code> (the character &lsquo;i&rsquo;), then a comparison of <code>0x10(%rax)</code> with <code>$0x79</code> (the character &lsquo;y&rsquo;). If they&rsquo;re both equal, then it jumps to <code>0x55555555db9d</code> (which is presumably the first arm&rsquo;s body). If they&rsquo;re not, then it does a comparison of <code>0x10(%rax)</code> with <code>$0x68</code> (the character &lsquo;h&rsquo;), and if <em>that</em> is equal, then it jumps to <code>0x55555555dbeb</code> (which is preumably the second arm&rsquo;s body).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The people I imagine doing this kind of investigation are the ones working out the low-level semantic guarantees when it comes to investigating
things like <a href="https://github.com/rust-lang/rust/issues/87520">rust#87520</a>.
</span>
Pretty low-level details, admittedly. Someone <em>new</em> to Rust cannot be expected to do this kind of investigation to gain insight into the language.</p>

<p>In short, this seems like a case where Kernighan and Pike&rsquo;s quote above is
especially apt: we can easily get lost in the details of the
control flow as rendered here.</p>

<p>So, how valuable is &ldquo;raw control-flow&rdquo;?</p>

<p><em>Honestly:</em> The more experience I gain in a language or a particular project,
the less and less I find myself relying on this kind of spulunking. The
evaluation order of <code>match</code> shouldn&rsquo;t matter in most cases, so I would not
optimize the debugging UX for that. Seeing how method dispatch resolves <em>is</em>
useful, but in practice logging statements provide enough insight that people
rarely find themselves wanting to step through the individual assembly
instructions.</p>

<p>Insight into the raw control-flow is probably most useful for someone peeking
into low-level details of the semantics of the language (or a given project,
especially a code base with tricky macros that generate control-flow
structures). One might hope that that group generalizes to beginners who are
learning the language. But I am not certain that raw control-flow will
efficiently provide practical insight. For example, consider the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]</span>
</span><span class='line'><span class="k">struct</span> <span class="n">D</span><span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;static</span> <span class="kt">str</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">d</span> <span class="o">=</span> <span class="n">D</span><span class="p">(</span><span class="s">&quot;my name is D&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{:?}&quot;</span><span class="p">,</span> <span class="n">d</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">D</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Goodbye, {}&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A newcomer to Rust who is not familiar with the destructor system might think
that the above code only prints a single line of text. Running the code (even
outside of a debugger) will show that to be incorrect. But: Will stepping
through it in a debugger provide the insight about where the <code>&lt;D as Drop&gt;::drop</code>
call comes from? It is not clear to me that it would.</p>

<a name="Memory.Exploration"></a>
<h2>Memory Exploration</h2>

<p>By &ldquo;memory exploration&rdquo;, I mean that when my debugger is attached to a paused
program, I can inspect values on the stack or heap, walking down the nodes of a
binary tree or the entries in a hashtable. A good debugger will do some amount
of memory traversal and semantic interpretation on my behalf, using type
information from the program&rsquo;s associated debuginfo to determine how best to
interpret the bits it finds and print it nicely (e.g. showing comma-separated
array elements).</p>

<p>How valuable is &ldquo;memory exploration&rdquo;?</p>

<p><em>Honestly:</em> In Rust, one can add <code>#[derive(Debug)]</code> to type definitions to get
methods that print the structure for their values. The debugger printouts were
useful when the language didn&rsquo;t provide it out of the box (like in C and C++),
but they less value in Rust.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Another counter-argument to this supposed first benefit: In a language like Rust,
anyone can use <code>unsafe</code> code to transmute the value to raw bits, and subsequently print them. This power is not solely in the debugger&rsquo;s hands.
</span>
One benefit of using a debugger here, rather than just using log statements, is
that a debugger will let you immediately see the concrete representation (such
as concrete hashtable layout) in places where the developer has chosen a more
abstract view for the <code>Debug</code> trait implementation. But again we hear echos of
the Kernighan and Pike quote: Seeing that concrete representation may be crucial
in some scenarios, but in many cases it will just be unnecessary detail
distracting you from the problem at hand.</p>

<p>A second benefit with respect to memory exploration is that a debugger will also
let you inspect values that were not part of the original log statement. But,
one can view that as a special case of bypassing the edit-recompile cycle, which
we already discussed above. If the edit-recompile cycle is short, then there is
little cost to adding a new log statement that includes the value of interest.</p>

<a name="Hardware.Watchpoints"></a>
<h2>Hardware Watchpoints</h2>

<p>So we have come to perhaps my <em>favorite</em> debugger feature: Hardware watchpoints.</p>

<p>This is the main feature that most programming languages do not provide.</p>

<p>The idea is simple: the gdb command <code>watch -location &lt;place&gt;</code> will
break the next time the memory at the given place is modified.
For example, <code>watch -location array[i]</code> will evaluate <code>&amp;array[i]</code> to
its address, and then the next time <code>array[i]</code> is changed, the debugger
will stop and print out both the old value and the new value.</p>

<p>Consider the following (buggy) code for merging two sorted sequences into a
single sorted sequence:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="mi">99</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">95</span><span class="p">];</span>
</span><span class='line'>    <span class="n">merge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">r</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">30</span><span class="p">],</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">60</span><span class="p">]);</span>
</span><span class='line'>    <span class="n">dbg</span><span class="o">!</span><span class="p">(</span><span class="n">r</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Supposedly merges sorted `a` and `b` into  `recv`.</span>
</span><span class='line'><span class="k">fn</span> <span class="n">merge</span><span class="p">(</span><span class="n">recv</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">],</span> <span class="n">a</span><span class="o">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">],</span> <span class="n">b</span><span class="o">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">ai</span> <span class="o">=</span> <span class="n">a</span><span class="p">.</span><span class="n">iter</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">bi</span> <span class="o">=</span> <span class="n">b</span><span class="p">.</span><span class="n">iter</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">a_cur</span><span class="p">,</span> <span class="k">mut</span> <span class="n">b_cur</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">(),</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">());</span>
</span><span class='line'>    <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mf">0.</span><span class="p">.</span><span class="n">recv</span><span class="p">.</span><span class="n">len</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">match</span> <span class="p">(</span><span class="n">a_cur</span><span class="p">,</span> <span class="n">b_cur</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">Some</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="o">*</span><span class="n">x</span> <span class="o">&lt;=</span> <span class="o">*</span><span class="n">y</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>                    <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>                    <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">None</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>                <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="p">(</span><span class="nb">None</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>                <span class="n">b_cur</span> <span class="o">=</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="p">(</span><span class="nb">None</span><span class="p">,</span> <span class="nb">None</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">return</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>When I run the code above, I get the output:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">[</span><span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">4</span><span class="p">]</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>    <span class="mi">10</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">40</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">60</span><span class="p">,</span>
</span><span class='line'><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>which is not quite right! The third element of the generated array is 20,
instead of 30.</p>

<p>This toy example is small enough that you might be able to see the bug from
immediate inspection. Adding more test cases to the run might also make the
problem apparent. But I am going to use it to illustrate how to use a hardware
watchpoint to jump immediately to the point in the control flow where the third
element of the <code>recv</code> array is overwritten.</p>

<p>After starting up the debugger, we let it evaluate the line that creates
the destination array:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">start</span>
</span><span class='line'><span class="n">Temporary</span> <span class="n">breakpoint</span> <span class="mi">1</span><span class="p">,</span> <span class="n">boom</span><span class="o">::</span><span class="n">main</span> <span class="p">()</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">2</span>
</span><span class='line'><span class="mi">2</span>     <span class="kd">let</span> <span class="k">mut</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="mi">99</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">95</span><span class="p">];</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">next</span>
</span><span class='line'><span class="mi">3</span>     <span class="n">merge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">r</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">30</span><span class="p">],</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">60</span><span class="p">]);</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, lets first check that we understand what we are looking at:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="nb">print</span> <span class="n">r</span>
</span><span class='line'><span class="err">$</span><span class="mi">1</span> <span class="o">=</span> <span class="p">[</span><span class="mi">99</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">95</span><span class="p">]</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="nb">print</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'><span class="err">$</span><span class="mi">2</span> <span class="o">=</span> <span class="mi">97</span>
</span></code></pre></td></tr></table></div></figure>


<p>Yep: We have our destination array <code>r</code>, and it currently has 97 as its
third element <code>r[2]</code>.</p>

<p>So we tell the debugger that we want it to break as soon as that location
is changed, and then let the program run!</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">watch</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">2</span><span class="o">:</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="k">continue</span>
</span><span class='line'><span class="n">Continuing</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">2</span><span class="o">:</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">Old</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">97</span>
</span><span class='line'><span class="n">New</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">20</span>
</span><span class='line'><span class="n">boom</span><span class="o">::</span><span class="n">merge</span> <span class="p">(</span><span class="n">recv</span><span class="o">=&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">a</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">b</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...})</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">29</span>
</span><span class='line'><span class="mi">29</span>                    <span class="n">b_cur</span> <span class="o">=</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>We are now within the body of <code>fn merge</code> instead of <code>fn main</code> (as you might have
expected), immediately after the mutation occured:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'>        <span class="p">(</span><span class="nb">None</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>            <span class="n">b_cur</span> <span class="o">=</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>        <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And indeed, if we print out <code>recv</code> at this point, we can see that the
array has been &ldquo;corrupted&rdquo;, since we now see the two copies of 20 in the
output:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">p</span> <span class="n">recv</span>
</span><span class='line'><span class="err">$</span><span class="mi">3</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> <span class="o">=</span> <span class="p">{</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">95</span><span class="p">}</span>
</span><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="err">```</span>
</span></code></pre></td></tr></table></div></figure>


<p>I am running with the <code>rust-gdb</code> command here, which has extensions for
printing slices nicely. If you were doing this under just normal <code>gdb</code>, then
you would see something like this instead.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">gdb</span><span class="p">)</span> <span class="n">p</span> <span class="n">recv</span>
</span><span class='line'><span class="err">$</span><span class="mi">3</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">]</span> <span class="p">{</span><span class="n">data_ptr</span><span class="o">:</span> <span class="mh">0x7fffffffe238</span><span class="p">,</span> <span class="n">length</span><span class="o">:</span> <span class="mi">5</span><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This kind of break-on-write is most useful for <em>unsafe</em> languages, when you have
data being corrupted due to out of bounds accesses. One certainly can encode
examples of that in unsafe Rust, but we also do not expect them to arise as
frequently.</p>

<p>But <em>honestly</em> (a ha): Is this actually revealing anything about the core problem
here? The logic at <em>this</em> <code>match</code>-arm is entirely sound: if we have <code>(None,
Some(y))</code> for our two cursors traversing the slices, then we should pass along
<code>y</code> and keep traversing down the right cursor. Whatever the bug is, it is
arising somewhere else, before we even get here.</p>

<a name="Reversible.Debugging"></a>
<h2>Reversible Debugging</h2>

<p>If I were restricting my attention to <code>gdb</code>/<code>rust-gdb</code> alone, this would be a
point where I would start talking about re-running the program and stepping
through it carefully, or trying to hypothesize points of interest based on
analyzing the source code and setting breakpoints at those points. But if we
were going to do that, then we might as well invest our time adding some of
those logging statements discussed above, because I think those would show the
problem here just as fast, if not faster!</p>

<p>My goal is to show you an <em>alternative</em> strategy, that works for code bases that
you are not that familiar with.</p>

<p>Lets continue looking at the merge example, but let us now run it under <a href="https://rr-project.org/"><code>rr.</code></a></p>

<p>First we record a run of interest:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="o">%</span> <span class="n">rr</span> <span class="n">record</span> <span class="p">.</span><span class="o">/</span><span class="n">boom</span>
</span><span class='line'><span class="n">rr</span><span class="o">:</span> <span class="n">Saving</span> <span class="n">execution</span> <span class="n">to</span> <span class="n">trace</span> <span class="n">directory</span> <span class="err">`</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">pnkfelix</span><span class="o">/</span><span class="p">.</span><span class="n">local</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">rr</span><span class="o">/</span><span class="n">boom</span><span class="o">-</span><span class="mi">2</span><span class="err">&#39;</span><span class="p">.</span>
</span><span class='line'><span class="p">[</span><span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">4</span><span class="p">]</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>    <span class="mi">10</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">40</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">60</span><span class="p">,</span>
</span><span class='line'><span class="p">]</span>
</span><span class='line'><span class="o">%</span>
</span></code></pre></td></tr></table></div></figure>


<p>With that recording in place, we can replay the run under <code>rr</code>, which gives an
interface similar to <code>gdb</code>. (And we will tell <code>rr</code> that we want it to use
<code>rust-gdb</code> as our debugger to get those extensions for rendering Rust
collections.)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="o">%</span> <span class="n">rr</span> <span class="n">replay</span> <span class="o">-</span><span class="n">d</span> <span class="o">~/</span><span class="p">.</span><span class="n">cargo</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">rust</span><span class="o">-</span><span class="n">gdb</span>
</span></code></pre></td></tr></table></div></figure>


<p>Our initial interaction with <code>rr</code> will be much like how we interacted with <code>gdb</code>
above: we&rsquo;ll start the program, set a hardware watchpoint for the third array
element, and let it run forward.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="k">break</span> <span class="n">main</span>
</span><span class='line'><span class="n">Breakpoint</span> <span class="mi">1</span> <span class="n">at</span> <span class="mh">0x55e4f162f437</span><span class="o">:</span> <span class="n">main</span><span class="p">.</span> <span class="p">(</span><span class="mi">2</span> <span class="n">locations</span><span class="p">)</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">c</span>
</span><span class='line'><span class="n">Continuing</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Breakpoint</span> <span class="mi">1</span><span class="p">,</span> <span class="mh">0x000055e4f162fae0</span> <span class="k">in</span> <span class="n">main</span> <span class="p">()</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">next</span>
</span><span class='line'><span class="n">Single</span> <span class="n">stepping</span> <span class="n">until</span> <span class="n">exit</span> <span class="n">from</span> <span class="n">function</span> <span class="n">main</span><span class="p">,</span>
</span><span class='line'><span class="n">which</span> <span class="n">has</span> <span class="n">no</span> <span class="n">line</span> <span class="n">number</span> <span class="n">information</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Breakpoint</span> <span class="mi">1</span><span class="p">,</span> <span class="n">boom</span><span class="o">::</span><span class="n">main</span> <span class="p">()</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">2</span>
</span><span class='line'><span class="mi">2</span>     <span class="kd">let</span> <span class="k">mut</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="mi">99</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">95</span><span class="p">];</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span>
</span><span class='line'><span class="mi">3</span>     <span class="n">merge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">r</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">30</span><span class="p">],</span> <span class="o">&amp;</span><span class="p">[</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">60</span><span class="p">]);</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">watch</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">2</span><span class="o">:</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">c</span>
</span><span class='line'><span class="n">Continuing</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">2</span><span class="o">:</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">Old</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">97</span>
</span><span class='line'><span class="n">New</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">20</span>
</span><span class='line'><span class="n">boom</span><span class="o">::</span><span class="n">merge</span> <span class="p">(</span><span class="n">recv</span><span class="o">=&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">a</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">b</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...})</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">29</span>
</span><span class='line'><span class="mi">29</span>                    <span class="n">b_cur</span> <span class="o">=</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>But now that we have reached this point in <em>replay</em>, we can rewind time.
We can ask questions like &ldquo;how did <code>a_cur</code> (the left-hand side of the tuple) become <code>None</code> already, without us ever emitting 30 to the <code>recv</code> array?
Well, the question doesn&rsquo;t <em>quite</em> look like that. But we can ask "When was <code>a_cur</code> last written to before this point?&rdquo;, which ends up effectively the same question.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">watch</span> <span class="n">a_cur</span>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">3</span><span class="o">:</span> <span class="n">a_cur</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we tell the system to run backwards.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">reverse</span><span class="o">-</span><span class="k">continue</span>
</span><span class='line'><span class="n">Continuing</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">2</span><span class="o">:</span> <span class="o">-</span><span class="n">location</span> <span class="n">r</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">Old</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">20</span>
</span><span class='line'><span class="n">New</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">97</span>
</span><span class='line'><span class="mh">0x000055e4f162fa95</span> <span class="k">in</span> <span class="n">boom</span><span class="o">::</span><span class="n">merge</span> <span class="p">(</span><span class="n">recv</span><span class="o">=&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">a</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">b</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...})</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">28</span>
</span><span class='line'><span class="mi">28</span>                    <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The <code>gdb</code> output is potentially confusing because the notions of &ldquo;Old&rdquo; and &ldquo;New&rdquo;
are inverted here. To dive deeper into this topic, you might consider the
watching the films Primer or TENET.
</span></p>

<p>We still have our first watch point in place for <code>r[2]</code>, so it halted almost
immediately. (When we were running forward, a watchpoint makes us stop right
after the write occurs. When we run backwards, a watchpoint makes us stop right
before the write occurs.)</p>

<p>Let us keep going backwards.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span> <span class="n">reverse</span><span class="o">-</span><span class="k">continue</span>
</span><span class='line'><span class="n">Continuing</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="n">Hardware</span> <span class="n">watchpoint</span> <span class="mi">3</span><span class="o">:</span> <span class="n">a_cur</span>
</span><span class='line'>
</span><span class='line'><span class="n">Old</span> <span class="n">value</span> <span class="o">=</span> <span class="n">core</span><span class="o">::</span><span class="n">option</span><span class="o">::</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="kt">i32</span><span class="o">&gt;::</span><span class="nb">None</span>
</span><span class='line'><span class="n">New</span> <span class="n">value</span> <span class="o">=</span> <span class="n">core</span><span class="o">::</span><span class="n">option</span><span class="o">::</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="kt">i32</span><span class="o">&gt;::</span><span class="nb">Some</span><span class="p">(</span><span class="mh">0x55e4f1664004</span><span class="p">)</span>
</span><span class='line'><span class="n">boom</span><span class="o">::</span><span class="n">merge</span> <span class="p">(</span><span class="n">recv</span><span class="o">=&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">a</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...},</span> <span class="n">b</span><span class="o">=&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">](</span><span class="n">size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> <span class="o">=</span> <span class="p">{...})</span> <span class="n">at</span> <span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">20</span>
</span><span class='line'><span class="mi">20</span>                        <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'><span class="p">(</span><span class="n">rr</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>And now we see where <code>a_cur</code> is being assigned <code>None</code>: line 20:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'>    <span class="k">match</span> <span class="p">(</span><span class="n">a_cur</span><span class="p">,</span> <span class="n">b_cur</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">Some</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="o">*</span><span class="n">x</span> <span class="o">&lt;=</span> <span class="o">*</span><span class="n">y</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>                <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">recv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>                <span class="n">a_cur</span> <span class="o">=</span> <span class="n">ai</span><span class="p">.</span><span class="n">next</span><span class="p">();</span> <span class="c1">// here&#39;s the assignment</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="p">...</span>
</span><span class='line'>    <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And if you look at this, you might see the problem: in that arm of the <code>if</code>, we
are copying over the right-hand tuple value (<code>*y</code>, from <code>b_cur</code>), but we are
advancing the <em>left-hand</em> cursor, <code>a_cur</code>.</p>

<p>With that insight, we can make an easy fix: replace line 20 with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'>                <span class="n">b_cur</span> <span class="o">=</span> <span class="n">bi</span><span class="p">.</span><span class="n">next</span><span class="p">();</span> <span class="c1">// was `a_cur = ai.next();`</span>
</span></code></pre></td></tr></table></div></figure>


<p>With that change in place, the code works:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">[</span><span class="n">boom</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">4</span><span class="p">]</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>    <span class="mi">10</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">30</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">40</span><span class="p">,</span>
</span><span class='line'>    <span class="mi">60</span><span class="p">,</span>
</span><span class='line'><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
<em>This</em> is a case where the ability to explore memory
and add printouts from the debugger is crucial: Because now we are exploring the
behavior of one specific trace, and we do not always have the opportunity to
try to recreate the trace on a new version of the program.
</span></p>

<p>There are other advantages provided by <code>rr</code>. For example, record/replay means
that you can investigate a trace repeatedly. Each time you replay the trace,
you&rsquo;ll observe the same execution; and you can add breakpoints (and print
statements on those breakpoints) on that exact trace as it replays. This is
invaluable for tracking down bugs that are intermittent or that depend on subtle
event orderings.</p>

<a name="Closing.Thoughts"></a>
<h2>Closing Thoughts</h2>

<p>I started writing this post thinking &ldquo;I&rsquo;m excited about debuggers! Why is no one
in the Rust community using them?&rdquo; As I dug into the topic, I kept asking myself
&ldquo;what feature is provided here that people cannot more readily get via their
logging instrumentation? What value <em>am</em> I getting from this?&rdquo;</p>

<p>As you might infer from my &ldquo;Honestly&rdquo; notes above, I had to admit that
the advantages of a debugger when compared to logging instrumentation
may be limited in scope. At least, that&rsquo;s how I see things with typical
debugging workflows.</p>

<p>Tools like <code>rr</code> open up <em>new</em> debugging workflows, one of which I delved into
above. I plan to write more in the future about other such new workflows, such
as ones provided by services like <a href="https://pernos.co/">pernos.co</a>. More generally, I want to spend
some time thinking about the nature of debugging: how it links in with how we
develop features, how we communicate our ideas, and how we validate our models.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Road to TurboWish part 3: Design]]></title>
    <link href="http://blog.pnkfx.org/blog/2021/05/03/road-to-turbowish-part-3-design/"/>
    <updated>2021-05-03T14:29:02-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2021/05/03/road-to-turbowish-part-3-design</id>
    <content type="html"><![CDATA[<p>This is part three in a series about the TurboWish performance analysis tool suite. In <a href="http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/">part one</a> I described why our team selected this as a focus, and the goals for the tools. In <a href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/">part two</a> I presented four narratives, each representing different idealized future customer experiences using the tools.</p>

<p>Now I want to show you the design document I developed, which digs more into how I think<label for='how-i-think' class='margin-toggle sidenote-number'></label><input type='checkbox' id='how-i-think' class='margin-toggle'/><span class='sidenote'>I cannot emphasize enough that nothing here is set in stone. These are ideas I am circulating with you precisely so that you can tell me what needs to change. </span> the system should be architected.</p>

<!-- more -->


<p>I will warn you up-front: This is a long post. Eight pages printed in my PDF preview; ten if you include the appendices. And yet it is largely just a transcription of <a href="https://hackmd.io/WsJg_695SUiH41DLMBRekA">another doc</a>. But the thing it is transcribing is going to evolve with time, and I like the idea of taking a snapshot of its state today. I also think the ideas in it are fun. A lot of it still remains to be designed. Much in here falls into the category of software that you can produce with a ton of dedicated programming on <em>every level of the software stack</em>; I want to figure out how to avoid that.</p>

<p>My most important unresolved question is, how can we deliver all of this functionality with <em>minimal investment</em> on the part of our end developer who is themselves a newcomer to Async Rust programming.</p>

<p>Everything that follows was taken verbatim<label for='pink-floyd' class='margin-toggle sidenote-number'></label><input type='checkbox' id='pink-floyd' class='margin-toggle'/><span class='sidenote'>Okay, not <em>verbatim</em>. I am again spicing things up a little by interleaving another favorie song alongside the text of the document, at the risk of turning this post into a Mark Z. Danielewski novel. </span> from <a href="https://hackmd.io/WsJg_695SUiH41DLMBRekA">the document</a> I presented to the other members of the AWS Rust team. This document is an attempt<label for='second-attempt' class='margin-toggle sidenote-number'></label><input type='checkbox' id='second-attempt' class='margin-toggle'/><span class='sidenote'>There was an earlier iteration of this document, with a slightly different design. I am not going to write a blog post about the earlier document (I figure it is better to jump straight to the superior version), but it is <a href="https://hackmd.io/QYohB4uTTkas20t6rhCrww">openly available</a>, just like the document I have transcribed into this blog post. </span>  to describe a software architecture for the first, most important tool: An &ldquo;Async Monitor&rdquo; that models the behavior of one&rsquo;s Rust async runtime, alongside an &ldquo;Async Console&rdquo; that presents slices of information from that model. As with parts <a href="http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/">one</a> and <a href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/">two</a>, I will be adding side-commentary on the right-hand margin.</p>

<hr />

<a name="TurboWish.Development.Plan:.The.Async.Monitor.and.Console"></a>
<h2>TurboWish Development Plan: The Async Monitor and Console</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
(This time I did not repeat my <a href="https://twitter.com/pnkfelix/status/1387022496717807622">&ldquo;mistake&rdquo; of crowd-sourcing</a> the choice of source material. If I were a proper magician, I would have employed a force, but I had a bit too much confidence in my ability to find appropriate quotes, even from ABBA for goodness sakes!)
</span></p>

<blockquote><p>Overhead the albatross</p>

<p>Hangs motionless upon the air</p>

<p>And deep beneath the rolling waves</p>

<p>In labyrinths of coral caves</p></blockquote>

<a name="TurboWish.Overview"></a>
<h2>TurboWish Overview</h2>

<p>TurboWish is a suite of tools that give Rust developers insight into performance issues<label for='issues-with-issues' class='margin-toggle sidenote-number'></label><input type='checkbox' id='issues-with-issues' class='margin-toggle'/><span class='sidenote'>&ldquo;Performance issues&rdquo; raises questions immediately. What does &ldquo;issues&rdquo; mean? Is this a profiler? A debugger? My current answer: I had not appreciated this until recently, but I think there is a spectrum between profiling and debugging. After all, they both come down to <em>understanding the behavior a program</em>. Providing insight into that is what TurboWish is all about. </span> in their code.</p>

<p>The first TurboWish deliverable is the Async Monitor and Console, which answers a developer&rsquo;s questions about how their code&rsquo;s async runtime<label for='runtime-v-executor' class='margin-toggle sidenote-number'></label><input type='checkbox' id='runtime-v-executor' class='margin-toggle'/><span class='sidenote'>I had been using the word &ldquo;async executor&rdquo; here, but Carl pointed out to me that the executor is just one small piece of the overall framework provided by a typical async environment. So now it says &ldquo;runtime.&rdquo; I am curious what other terms might work here as well. </span> is behaving as their program runs.</p>

<p>The Async Console provides a summary of an async runtime&rsquo;s behavior, using concepts shared across the async rust ecosystem (such as tasks and resources), and metrics that are applicable to any async program (such as the average time each task spends waiting in a ready state).</p>

<p>When a developer asks: &ldquo;Why is my task stuck?&rdquo; or &ldquo;Why is my app slow?&rdquo;, the Async Console is the first, and in some cases, the only tool they need to reach for. It will allow the developer to quickly see how tasks are scheduled (to learn how much time is spent in the developer&rsquo;s own code versus waiting to run), identify tasks that are starving or blocked and what resources they are waiting on, and identify tasks responsible for replenishing a scarce resource.</p>

<p>We plan to expand the TurboWish tool suite with other tools<label for='other-tools' class='margin-toggle sidenote-number'></label><input type='checkbox' id='other-tools' class='margin-toggle'/><span class='sidenote'>You may have wondered when reading the <a href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/">user stories in part two</a> how a single tool was going to satisfy all those different narratives. The phrase &ldquo;other tools&rdquo; here hopefully answers that questions: currently, I am not planning to have a single tool do all of the stuff described in those stores. </span>  dedicated to other investigations, such heap profiling or sampling-based CPU profiling. This design document is dedicated to the Async Monitor and Console; in tandem, they are the tool that will drive the top-down investigation of an async developer&rsquo;s performance issues.</p>

<blockquote><p>The echo of a distant time</p>

<p>Comes willowing across the sand</p>

<p>And everything is green and submarine</p></blockquote>

<a name="Document.overview"></a>
<h2>Document overview</h2>

<p>This document describes the development plan for the first TurboWish tool: the Async Monitor and Console. It opens with the original goals followed by (proposed, unfinalized) <a href="#Tenets.of.TurboWish.Tool.Suite">tenets</a> for the TurboWish suite itself. It then presents a description of the <a href="#The.Async.Console.Experience">customer experience</a> using the Async Monitor and Console. Then it sketches an <a href="#Implementation.Plan">implementation plan</a>. A section follows describing <a href="#Metrics">metrics</a> for evaluating whether the tools are achieving their goal, and finally a section touching on <a href="#Security.Concerns">security concerns</a>. <a href="#Appendices">Appendices</a> follow the <a href="#Conclusion">conclusion</a> of the document, including an appendix with the <a href="#Schedule">project schedule</a>.</p>

<blockquote><p>And no one showed us to the land</p>

<p>And no one knows the where&rsquo;s or why&rsquo;s</p>

<p>But something stirs and something tries</p>

<p>And starts to climb toward the light</p></blockquote>

<!-- goals embedded from other doc -->


<a name="Goals"></a>
<h1>Goals</h1>

<!-- We don't need this link here; people who want to comment will already be looking at the original hackmd -->


<!--
[link to goals](https://hackmd.io/OcfdnDwKRSiW-6WmSVt0Bw) (if you want to comment on them, go to the linked doc)
-->


<p><em>Profile Production Code</em>: Incorporating the TurboWish Framework is low-overhead: it can be incorporated into production code<label for='production-code' class='margin-toggle sidenote-number'></label><input type='checkbox' id='production-code' class='margin-toggle'/><span class='sidenote'>You might ask: Does &ldquo;production code&rdquo; mean the same thing as &ldquo;deployed code running live&rdquo;? And you would be right to ask that. In hindsight, I should have included an entry about this in the &ldquo;Minimum Viable Product&rdquo; section where I described long-term concerns versus short-term sacrifices. My attitude here, in any case, is that there are <em>other</em> infrastructures for logging behavior of live services. Integration with those infrastructures might make sense eventually, but I do not regard it as a pre-requisite for launching <em>this</em> product. </span>  without producing an undue maintenance burden and without incurring significant performance overhead.</p>

<p><em>Domain-specific Feedback</em>: Frameworks and applications can provide data for specialized metrics, specific to their internal architecture.</p>

<p><em>Understand Hidden Costs and Connections</em>: Frameworks like tokio ease writing asynchronous code because they hide a number of details behind abstractions (such as generator code produced by the Rust compiler, or task queues managed by the tokio runtime). TurboWish exposes those hidden details, allowing developers to correlate them with other program events. It also exposes connections that humans usually have to reconstruct by hand (such as future to resource to future chains that can yield deadlock), allowing one to directly see from Rust’s ownership model how resources are being held in the object graph.</p>

<p><em>Framework Agnostic</em>: Many of Rust’s customers use tokio, but not all of them. async-std  and fuschia_async are other frameworks for asynchronous programming. TurboWish can provide value to any such framework (though it may also provide framework-specific functionality when warranted). For our initial releases, we can focus on tokio alone, but expect integration with others if use with tokio proves successful.</p>

<p><em>EC2 Instance Type Agnostic</em>: If we make use of any OS specific features (e.g. dtrace probes), they will be available on all EC2 AL2 instances, regardless of instance-type. (Specifically, we cannot require access to CPU performance counters for core functionality. We may offer extra features that utilize them.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This use of the word &ldquo;tenets&rdquo; is part of Amazon parlance. When you see it, you can think &ldquo;Guiding Principles&rdquo;.
</span></p>

<a name="Tenets..of.TurboWish.Tool.Suite"></a>
<h2>Tenets  of TurboWish Tool Suite</h2>

<p>The Rust community at large, both within and outside of AWS, is the customer for TurboWish.</p>

<p>Injected instrumentation must not block application progress.</p>

<p>Timing-measurement noise induced by client instrumentation should be minimized.</p>

<p>Present diagnoses in terms of customer-centric concepts, such as resource and task.</p>

<p>Minimize coupling between components to encourage concurrent community development.</p>

<p>The transition from development to production deserves as much performance tooling as production monitoring itself. (More specifically: We see customers struggling to get their software operating well enough to push to release; therefore, some tools can be specialized to the development use-case.)
The Async Monitor is one such tool: It is aimed at programs under development, not in release.</p>

<blockquote><p>Strangers passing in the street</p>

<p>By chance, two separate glances meet</p>

<p>And I am you and what I see is me</p></blockquote>

<a name="The.Async.Console.Experience"></a>
<h2>The Async Console Experience</h2>

<p>When a developer wants to deploy the Async Monitor on their program, they will need to hook it in by adding it as an upstream dependency (in the <code>Cargo.toml</code> file) and also writing a few initialization lines at the start of their source code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">turbowish_async_monitor</span> <span class="k">as</span> <span class="n">tw_monitor</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#[tokio::main]</span>
</span><span class='line'><span class="n">async</span> <span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">tw_monitor</span><span class="o">::</span><span class="n">builder</span><span class="p">().</span><span class="n">port</span><span class="p">(</span><span class="mi">8080</span><span class="p">).</span><span class="n">init</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Rest of the app</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>With that initialization code in place, the service will operate in the same fashion as before, but will now also run the <em>Async Monitor</em>, which observes events and then, based on those observations, builds an internal model of the program and the async executor. External programs, such as the <em>Async Console</em> can now connect and present the state of the Async Monitor by connecting to the port indicated above..</p>

<p>When the developer first connects the Async Console, they get a presentation similar to the UNIX <code>top</code> command, showing a brief summary of the executors (with metrics like the number of tasks running or sleeping, average times spent waiting to run, average <code>Future::poll</code> runtimes), and below that, a list of the current tasks, each on its own line with with an id number, name, current run state (Polling, Ready to poll, and Waiting), and a list of task attributes that include developer-specified metadata.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Mock up of the console UI was provided by Carl Lerche, a lead Tokio developer.
</span>
<img src="https://i.imgur.com/F71IQMl.png" alt="async console terminal user interface" /></p>

<p>This view will dynamically update (just like <code>top</code>) as the application runs.</p>

<p>The async console presents data primarily oriented around tasks and resources. The aim is for a model as straight-forward to understand as the Resource Allocation Graphs<label for='holt' class='margin-toggle sidenote-number'></label><input type='checkbox' id='holt' class='margin-toggle'/><span class='sidenote'>I will be honest: These task/resource graphs are the part of the system I personally am most excited about. I do not yet know how we will deliver on the developer experience that I envisage, but I want it to be as beautiful as the graphs I presented in <a href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/">part two</a>. </span> described by <a href="https://dl.acm.org/doi/10.1145/356603.356607">Ric Holt in 1972</a>: We wish to explain as much as we can in terms of tasks waiting for or using resources (either by locking them if they are exclusive resources, or by consuming them if they are cumulative resources such as message channels), or resources waiting for tasks to make them available (either by unlocking them for exclusive resources, or by refueling them if they are cumulative resources).</p>

<p>The async console monitors for known performance pitfalls, and includes a highlighted alert at the top of the screen if the program is currently exhibiting one of those pitfalls. The alert provides a link to a problem-oriented view, that explains the pitfall and provides guidance as to how one can resolve it.</p>

<p>From the async console, the developer can do three main things. First, they can dig into an individual <strong>record</strong> of a task or resource, by traversing hyperlinks for that task or resource. (A &ldquo;record&rdquo; in this context is a screen summarizing the event history and current status for that task or resource.) Second, they can <strong>pause</strong> a waiting task (or request that a specific non-waiting task be paused when it next evaluates a <code>.await</code>); such paused tasks can be subsequently inspected by a debugger attaching to the running process, and then resumed when the developer is done with the attached debugger. Third, they can <strong>rollback</strong> history, in order to inspect past states for tasks or resources.</p>

<blockquote><p>And do I take you by the hand</p>

<p>And lead you through the land</p>

<p>And help me understand the best I can?</p></blockquote>

<a name="Performance.Pitfall.Alerts"></a>
<h3>Performance Pitfall Alerts</h3>

<p>The performance pitfall alerts handle a collection of known cases where our customers are asking themselves: &ldquo;why is my task stuck?&rdquo;</p>

<p>Example of problems that the Async Monitor can detect include: deadlock cycles, excessive polling times, and buggy implementation of <code>Future</code> that fail to register a waker.</p>

<p>As a concrete example: When a deadlock cycle occurs, the async console displays an alert saying &ldquo;deadlock cycle detected.&rdquo; The developer follows the hyperlink for the alert, and this brings up a &ldquo;problem view&rdquo; that shows an interleaving list of tasks and resources<label for='lists-vs-graphs' class='margin-toggle sidenote-number'></label><input type='checkbox' id='lists-vs-graphs' class='margin-toggle'/><span class='sidenote'>Here I made a concession to reality: users do not want graph diagrams shoved in their faces all the time. Lists are sometimes an entirely reasonable presenation medium, especially when it comes to describing a deadlock cycle. </span>, corresponding to the chain of dependencies that forms the cycle.</p>

<a name="Resource.Records"></a>
<h3>Resource Records</h3>

<p>A resource record shows information about an individual resource.</p>

<p>Some resources are <em>exclusive</em>: they can be held by at most N tasks at a time (where N is often 1, such as in the case of a mutex lock). The resource record for an exclusive resource will include a list of tasks that currently hold it. It will also include a separate list of tasks that are currently blocked while trying to acquire the resource.</p>

<p>Some resources are <em>cumulative</em>: they hold some number of resource units (work items in a queue, messages on a channel, <em>et cetera</em>). The resource record for a cumulative resource will include a list of tasks that are currently blocked on the resource&rsquo;s current state (for example, for a channel, a receiver will block on an empty channel; a sender will block on a bounded channel at full capacity).<label for='blocking-in-either-direction' class='margin-toggle sidenote-number'></label><input type='checkbox' id='blocking-in-either-direction' class='margin-toggle'/><span class='sidenote'>The fact that a (bounded) channel can cause a sender or receiver to block is an insight that is simultaneously obvious but at the same time raises important modelling questions. In short: the arcs representing blocking dependencies in the task/resource graph may go in <em>either direction</em>, depending on the state of the channel. My mind keeps coming back to this point, and I want to make sure we do not forget it. </span></p>

<p>(In <a href="#holt72">Holt 1972</a>, the terms &ldquo;reusable&rdquo; and &ldquo;consumable&rdquo; roughly correspond to our usage of &ldquo;exclusive&rdquo; and &ldquo;cumulative&rdquo;. The correspondence is imperfect though; e.g. Holt refers to individual consumable resource units, while for us, a &ldquo;cumulative resource&rdquo; describes a collection of such consumable units, such as a channel.)</p>

<p>In addition, the resource record will include lists of tasks that have signaled <em>intent</em> to interact with the resource. This way, the resource record for a multi-producer single-consumer channel can include a list of all of the sending tasks that hold the channel, as well as the receiver task associated with the channel, regardless of whether the channel&rsquo;s message buffer is empty, partially-full, or full.</p>

<p>Listing the tasks that intend to interact with the resource is how we can provide the developer with enough information to resolve unexpected blocking behavior in their code. For example, after seeing that a sender task is blocked because a bounded channel is at full capacity, it is simple for the developer to follow hyperlinks to go from the sender task to the channel&rsquo;s resource record, and from there through another hyperlink to the receiver task, and then work on figuring out how to make the receiver task process messages more efficiently.</p>

<a name="Task.Records"></a>
<h3>Task Records</h3>

<p>If a task is blocked, the task record will show what specific <code>.await</code> expression it is blocked on, by showing the span (file:line and column range) and the expression itself (<code>my_channel.send(value).await</code>). If the blockage is due to a specific resource, then a hyperlink to its resource record will be provided as well.</p>

<p>More generally, a task record shows information about an individual task, including lists of resources associated with the task.</p>

<p>If a task currently holds exclusive access to resources, all such resources will be listed.</p>

<p>As mentioned earlier, tasks can signal intent to interact with a resource. There are two kinds of intention that can be signaled: conditional intent and unconditional intent.<label for='kinds-of-intent' class='margin-toggle sidenote-number'></label><input type='checkbox' id='kinds-of-intent' class='margin-toggle'/><span class='sidenote'>I need to more research to see what related work there is here. My naive notion of &ldquo;conditional&rdquo; and &ldquo;unconditional&rdquo; intent is probably not novel. What I really want to know is whether it is a <em>useful</em> distinction to make. </span></p>

<p>A task signals <em>conditional intent</em> when the interaction is predicated on some external condition holding; i.e., it will occur only on some of the task&rsquo;s non-error control-flow paths. (One could imagine approximating conditional intent by just listing all the resources that are <em>reachable</em> from the task; this is a topic we should explore during implementation.)</p>

<p>A task signals <em>unconditional intent</em> as a way to state &ldquo;<em>if</em> I can make sufficient forward progress, I <em>will</em> interact in this manner with that resource.&rdquo; It is essentially another way of saying: &ldquo;if you can figure out how to get me unblocked, these are the actions I will take&rdquo;, which can be crucial in resolving certain kinds of resource starvation issues.</p>

<p>The task record shows two separate lists corresponding to the two kinds of intention. This way, developers are informed about <em>which</em> tasks to look at first when trying to understand the interactions between tasks and resources in their program.</p>

<p>During execution, resources may move from the conditional list to the unconditional list, or they may move off the conditional list entirely, all according to what a task indicates as its code runs. When a task has actually performed its intended operation to completion (e.g. if it is entirely done sending messages on a given channel, and signals such to the async monitor) then the resource will likewise be removed from the task&rsquo;s resource lists.</p>

<blockquote><p>And no one calls us to move on</p>

<p>And no one forces down our eyes</p>

<p>No one speaks and no one tries</p>

<p>No one flies around the sun</p></blockquote>

<a name="Pausing.a.Task"></a>
<h3>Pausing a Task</h3>

<p>Sometimes the information provided in the TurboWish Async Monitor&rsquo;s records will not give enough detail, and the developer will want to inspect the actual state of the task&rsquo;s memory on the live process in a debugger.</p>

<p>To pause a task, the developer can go to its Task record page, or just select it in the Async Console overview, and then issue the &ldquo;pause&rdquo;  command. The executor pauses tasks by opting not to schedule them, instead leaving them suspended where they evaluated <code>.await</code>.</p>

<p>As a convenience, the Async Console provides <code>gdb</code> and <code>lldb</code> commands as helpers that pause the task, then spawn the corresponding debugger processes and attach them appropriately to the paused task.</p>

<a name="Rolling.Back.the.Event.Log"></a>
<h3>Rolling Back the Event Log</h3>

<p>Sometimes humans just don&rsquo;t understand how they got into some mess.</p>

<p>For those situations, the Async Monitor offers rollback functionality. Developers can step backwards<label for='step-backwards' class='margin-toggle sidenote-number'></label><input type='checkbox' id='step-backwards' class='margin-toggle'/><span class='sidenote'>I have spent a long time advocating for the use of the <a href="https://rr-project.org/"><code>rr</code> debugger</a>, and I suspect this section is a small reflection of that. (This document is describing a completely different operational model to what <code>rr</code> does, though. I am emphatically <em>not</em> suggesting the event log contain enough state to actually replay program code.) </span> through the event history and see how such steps affect the task and resource records.</p>

<p>For example, a <code>select!</code> expression in tokio will run a collection of futures concurrently. It will proceed with the value provided by whichever future completes first, <em>canceling</em> the other futures that lost the race. If code is not written to anticipate such cancellation, it can lead to data corruption, or tasks appearing to be blocked indefinitely (aka &ldquo;hung&rdquo;).</p>

<p>As a concrete example adapted from a <a href="https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d54d63934a1c">blog post</a>, consider this code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kd">let</span> <span class="k">mut</span> <span class="n">file</span> <span class="o">=</span> <span class="p">...;</span>
</span><span class='line'><span class="kd">let</span> <span class="k">mut</span> <span class="n">channel</span> <span class="o">=</span> <span class="p">...;</span>
</span><span class='line'><span class="k">loop</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">futures</span><span class="o">::</span><span class="n">select</span><span class="o">!</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">_</span> <span class="o">=&gt;</span> <span class="n">read_send</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">file</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">channel</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{},</span>
</span><span class='line'>        <span class="n">some_data</span> <span class="o">=&gt;</span> <span class="n">socket</span><span class="p">.</span><span class="n">read_packet</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// ...</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here, <code>read_send</code> is constructing a future on every iteration through the loop. If the <code>socket.read_packet()</code> invocation ever wins the <code>select!</code>-race, then the <code>read_send</code> future is dropped, which means the data may have been extracted from the file but not yet relayed on the <code>channel</code>. (The details are spelled out on the <a href="https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d54d63934a1c">blog post</a>.)</p>

<p>If a task appears to be hung, the Async Monitor allows the developer to gain insight into why: They can visit the task view for the blocked task. The task view will indicate where it is stuck (in the <code>select!</code>). Since <code>select!</code> is known to be a source of problems for developers, the view will also include a hyperlink that will &ldquo;rewind time&rdquo; to the invocation of <code>select!</code> on the previous iteration of this loop, so that one can observe what side-effects it had. Upon rewinding time, the task view indicates that the <code>socket.read_packet()</code> future won the race, and that the future returned from <code>read_send</code> was <em>dropped</em>.</p>

<p>(At this point, we are relying on the developer having an &ldquo;Aha&rdquo; moment about the effect of dropping a future when it is in the middle of its computation. It would be good to explore ways to help people get the insight sooner. For example, maybe having the view here indicate <em>where</em> the <code>read_send</code> future was in its own computation at the time it was dropped would help someone see that we need to keep that same future running.)</p>

<a name="Constraining.event.log.overhead"></a>
<h4>Constraining event log overhead</h4>

<p>As part of the configuration options for the Async Monitor, one can adjust the upper-bound on the size of the event log, in order to ensure its memory usage does not induce memory exhaustion, virtual memory swapping, or other problems that could excessively perturb performance evaluation.</p>

<a name="Concluding.the.Experience"></a>
<h3>Concluding the Experience</h3>

<p>For many problems, the Async Monitor will provide the developer with the insight they need to resolve their questions about their programs interactions with the async executor. However, some performance problems will require further inspection. The Async Monitor can help with some of that, such as when it allows a developer to <a href="#Pausing.a.Task">pause a task</a>. But sometimes a developer will need insight into other aspects of their program, such as where memory or CPU time is going. Other tools will be needed for such cases.</p>

<p>An appendix of this document shows a diagram of the expected developer <a href="#Appendix.B:.TurboWish.User.Work.Flow">work flow</a>. The diagram presents steps that are described above; but it also shows decision points where a user might need to employ another tool.</p>

<p>Now that we have finished explaining the experience of someone using the tool, we will now discuss how to deliver that experience to our customers.</p>

<blockquote><p>Cloudless everyday</p>

<p>You fall upon my waking eyes</p>

<p>Inviting and inciting me to rise</p></blockquote>

<a name="Implementation.Plan"></a>
<h2>Implementation Plan</h2>

<p>As mentioned above, there are two main components: the Async Monitor, and the Async Console.</p>

<p>The 2021 release of TurboWish will need to provide value without having any support from the Rust compiler or standard library. Therefore, the initial release will work by:
 1. leveraging instrumentation added directly to the async executor,
 2. encouraging service developers to add corresponding instrumentation, and
 3. capturing stack backtraces at key executor events.</p>

<a name="Instrumentation"></a>
<h3>Instrumentation</h3>

<p>The instrumentation will be responsible for documenting how the relationships between tasks and resources change over time. More specifically, the instrumentation will capture: task state transitions (running, ready, waiting), task acquisition of exclusive resource (e.g. locking a mutex), task modifications of resource state (e.g. sending on a channel or receiving from it), and task <em>intent</em> to interact with resources.</p>

<p>As mentioned in the <a href="#Task.Records">Task Records section</a>, there are two kinds of intent: conditional and unconditional. My long-term hope is to leverage some sort of heap-ownership tracing system to <em>infer conditional intent</em>, because signalling it via manual instrumentation will be arduous and error-prone. (Heap ownership tracking alone cannot infer unconditional intent, but it may be possible to leverage compiler analysis to perform such inference of unconditional intent.)</p>

<a name="Component.Separation"></a>
<h3>Component Separation</h3>

<p>There are four short-term deliverables: 1. the Async Monitor, 2. the Async Console, 3. a specification of what instrumentation events the Async Monitor understands (which may come from the client code, the async executor, or any related libraries (e.g. Rayon or other crates that offer a thread pool)), and 4. the instrumentation of Tokio (following the aforementioned specification) to support the Async Monitor.</p>

<a name="Diagram.of.Async.Monitor.Architecture"></a>
<h4>Diagram of Async Monitor Architecture</h4>

<p>This is a rendering of the component separation. There are two running programs: The program being developed, and the Async Console. Within the program being developed, instrumentation events are generated and travel on the event bus, where they are observed by the Async Monitor running as a thread in that process. The Async Monitor communicates with the Async Console, presenting portions of the model according to the requests that arrive from the console.</p>

<!-- The manual height specification is a rough guess, to allow the rest of the doc to predict the space occupied by the graph once it is rendered. -->


<div class="mermaid" style="height: 750px">
flowchart TD
  subgraph Client
    TwCollect --- pause_reqs ---> Tokio
    pause_reqs([introspection requests,<br/>e.g. 'pause'])
    TracingEventBus
    TracingEventBus -.-> TwCollect
    TwCollect[Async Monitor]
    TwCollect --- EventLog
    EventLog[(EventLog)]

    Tokio[Async Executor<br/>e.g. Tokio]
    ClientCode[Client App Code]
    Rayon

    ClientCode -.-> TracingEventBus
    Tokio -.-> TracingEventBus
    Rayon -.-> TracingEventBus

    TracingEventBus[Event Bus<br/>atop tracing crate<br/>&lt;follows event spec&gt;]
  end

  subgraph Console [Console Program __]
    TwTui <--> TwCollect
    TwTui([Async Console])
  end
</div>


<a name="Development.Decoupling"></a>
<h3>Development Decoupling</h3>

<p>In order to enable concurrent development of the four deliverables, we will follow these steps:</p>

<a name="Deliverable:.Event.specification"></a>
<h4>Deliverable: Event specification</h4>

<p>First, we must pick some format for specifying the grammar of the instrumentation events. Anything with an existing off-the-shelf parser-generator available as a Rust crate will serve. JSON might be a reasonable choice here, at least for initial prototyping; but we should also evaluate whether other event description formats incur less encoding overhead than JSON.</p>

<p>(Another option would be a dedicated enum type for events. That would then need to be exposed in its own crate that downstream clients would need to add as a dependency. <del>Perhaps more importantly: we are very likely to use <code>tracing</code> as the event bus, which takes string-encoded messages as the basis for its encoding.</del>)</p>

<p>Second, we must make an initial specification of events. Just saying &ldquo;it&rsquo;s JSON&rdquo; is not sufficient; we need to state how each desired event is actually encoded in the chosen grammar. This will evolve over time. It must cover everything listed in <a href="#Instrumentation">Instrumentation</a>.</p>

<p>With these two pieces in place, we can spin off a few parallel tracks of development.</p>

<a name="Deliverable:.Instrumenting.tokio"></a>
<h4>Deliverable: Instrumenting tokio</h4>

<p>For instrumenting tokio. I recommend that we start by developing an event-validating async monitor (or more simply, &ldquo;event-validator&rdquo;). The event-validator is responsible for ensuring the incoming event stream is coherent; it might build up a minimal model as part of its coherence check, but it is not responsible for gathering all the metrics that are expected of the Async Monitor product itself. With an event-validator in place, one can test the correctness of tokio instrumentation as it is added. (We will also need to do integration tests once the async monitor itself is constructed.)</p>

<a name="Deliverable:.Async.Monitor"></a>
<h4>Deliverable: Async Monitor</h4>

<p>For the Async Monitor, I recommend the following baby-steps toward implementation.</p>

<p>First, either make a new mock async executor, or select a pre-existing simple reference async executor (several exist on github), and using this as the mock executor. Use the mock executor for initial development of the Async Monitor: that is, the in-development Async Monitor would be exercised by building an internal model of the mock executor&rsquo;s state.</p>

<p>The reason for employing a mock executor is two-fold: 1. it will be quicker to add (and modify when inevitably needed) the necessary instrumentation as the Async Monitor itself is developed, and 2. using a mock rather than tokio directly will help prevent inadvertent coupling between tokio itself and the async monitor; such coupling would make it hard to add support to other async executors like async-std in the future.</p>

<p>In addition to a mock executor, I also recommend making an mock event stream that will simulate <em>both ends</em> connected to the Async Monitor: it will generate the events that we expect to be signaled by an instrumented application sitting atop some instrumented executor, and it will <em>also</em> simulate a console attached to the other side of the Async Monitor. I recommend having a mock event streamer because this is the easiest way to generate a deterministic series of instrumentation events interleaved with console events. Making such event generation deterministic will be crucial for testing the async monitor.</p>

<a name="Deliverable:.Async.Console"></a>
<h4>Deliverable: Async Console</h4>

<p>Finally, for the console, I recommend that we make a mock async monitor. It will simulate the Async Monitor&rsquo;s side of the communication protocol used by any Console connecting to the monitor&rsquo;s port.</p>

<p>(Defining the communication protocol between the Async Monitor and the Console is a prerequisite here. However, this protocol is only exposed to the Monitor and Console, and so it can be revised without having to worry about updating downstream clients.)</p>

<a name="Deliverable.Development.Decoupling.Diagram"></a>
<h4>Deliverable Development Decoupling Diagram</h4>

<p>The three decoupled tracks listed above are repeated below in a visual diagram, showing the dependencies between the pieces.</p>

<!-- The manual height specification is a rough guess, to allow the rest of the doc to predict the space occupied by the graph once it is rendered. -->


<div class="mermaid" style="height: 300px">
flowchart TD
    spec[Event Specification]
    spec --> validating_monitor[Event-Validating Async Monitor]
    spec --> mock_executor[Mock Async Executor]
    validating_monitor --> instrument_tokio[Add instrumentation to tokio]
    spec --> mock_event_stream
    mock_event_stream[Mock Event Streamer]
    mock_executor --> async_monitor[Async Monitor]
    mock_event_stream --> async_monitor
    mock_monitor[Mock Async Monitor] --> Console
</div>


<a name="Long-term.concerns..short-cuts.for.the.Minimum.Viable.Product"></a>
<h3>Long-term concerns; short-cuts for the Minimum Viable Product</h3>

<p>See <a href="#Appendix.A:.Sacrifices.for.Minimum.Viable.Product">Appendix: Sacrifices for Minimum Viable Product</a></p>

<blockquote><p>And through the window in the wall</p>

<p>Come streaming in on sunlight wings</p>

<p>A million bright ambassadors of morning</p></blockquote>

<a name="Metrics"></a>
<h2>Metrics</h2>

<p>The goal of these tools is to provide users with insight into performance pitfalls. How can we know if the Async Monitor and Console are achieving their goal?</p>

<p>There are two ways I can imagine approaching this: telemetry from the Async Console program, or evaluating out-of-band signals (such as sentiment analysis on social media). I will focus here on the telemetry option, under the assumption that any potential telemetry would be an opt-in choice presented to the customer when they first use the Async Console tool.</p>

<a name="Telemetry:.Success.Metrics"></a>
<h3>Telemetry: Success Metrics</h3>

<p>For evaluating whether the tool is successfully providing users with insight, the most obvious answer is we could ask our users. When the console detects a problem and the user shifts to the dedicated problem view describing the problem, the console could also proactively ask the &ldquo;Yes&rdquo;/&ldquo;No&rdquo; question of whether the information it presents is helping the user solve their problem (or perhaps request a user happiness rating on a 1-5 to scale), and then ship those responses back to a service that collects such feedback.</p>

<p>Alternatively: we already plan to have the tool link to websites that provide documentation of various known performance pitfalls. Rather than building telemetry into the console, the linked websites could ask the visitor whether the Async Monitor and Console are working for them. (However, this approach runs the risk of omitting the experiences of users who do not follow the links.)</p>

<a name="Telemetry:.Failure.Metrics"></a>
<h3>Telemetry: Failure Metrics</h3>

<p>On the flip side of things, we also want to ensure that the instrumentation from TurboWish is not injecting too much overhead into our customer&rsquo;s applications.</p>

<p>While it is probably not reasonable to try to measure the time spent issuing each individual instrumentation event, it is entirely reasonable to measure how many messages are being sent to the Async Monitor, how large they are, and which component (namely, the aync executor, or user code) issued them.</p>

<p>My recommendation is to monitor how much load the instrumentation is putting onto the event bus, according to the event density over a sliding window of time (let&rsquo;s say 100 ms long). If the event density from user code exceeds some predetermined threshold in any given 100ms window, then the Async Console signals a problem report to the developer, telling them that their program&rsquo;s instrumentation may be slowing down the program. If the event density from the async executor (lets say tokio) exceeds a similar predetermined threshold, then the Async Console reports that up to a service associated with the tokio project. (Or, if the tokio project does not see value in getting such traffic, then the Async Console could suggest that the user file a bug on the tokio github.)</p>

<a name="Security.Concerns"></a>
<h2>Security Concerns</h2>

<p>The instrumentation added to the tokio runtime and client application code may expose details of internal operation that customers do not exposed to the world at large.</p>

<p>We should check that there are controls in place that ensure either: 1. code deployed to production does not have such instrumentation turned on, or 2. the async monitor is not initiated on production systems,  or 3. the port associated with the async monitor is blocked by a firewall guarding the customer&rsquo;s host machine or intranet.</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>The Async Monitor and Console answer a developer&rsquo;s questions about how their code&rsquo;s async executor is behaving as their program runs. They provide a summary of the executor&rsquo;s behavior, with metrics about the tasks and resources their program is using. They allow the developer to identify scheduling decisions and see how task and resources depend on each other.</p>

<p>Furthermore, they serve as the foundation of TurboWish. So, in effect: We aim in 2021 to deliver the foundation for 2022 and beyond. We will work with the Rust community to lay this groundwork, and our community will be enabled to make even more amazing tools atop this foundation.</p>

<blockquote><p>And no one sings me lullabies</p>

<p>And no one makes me close my eyes</p>

<p>So I throw the windows wide</p>

<p>And call to you across the sky</p></blockquote>

<a name="FAQ"></a>
<h1>FAQ</h1>

<ul>
<li>Q: Why build the Async Monitor into the application binary? Couldn&rsquo;t that be part of the Async Console instead, and have all the events stream to the Async Console?

<ul>
<li>A: The primary reason that the Async Monitor is part of the application binary is that we believe streaming all the events that the monitor needs to observe to an external program will inject too much overhead.
A secondary reason for building the Async Monitor into the application binary is simplicity. If the monitor were a separate program, then one cannot ensure that the full stream of events reaches the monitor. At best one could strive for a <em>suffix</em> of the event stream, which means that the monitor has to be designed to still produce a useful model given such a suffix. (A <a href="https://hackmd.io/QYohB4uTTkas20t6rhCrww">previously considered architecture</a> handled the suffix problem by allowing the monitor to pose queries to the instrumented application, in order to get information such as &ldquo;what is the current set of tasks?&rdquo;)</li>
</ul>
</li>
</ul>


<a name="Appendices"></a>
<h1>Appendices</h1>

<a name="Appendix.A:.Sacrifices.for.Minimum.Viable.Product"></a>
<h2>Appendix A: Sacrifices for Minimum Viable Product</h2>

<a name="Minimal.Viable.Product:.Shims.for.resource.instrumentation"></a>
<h3>Minimal Viable Product: Shims for resource instrumentation</h3>

<!-- Note (pnkfelix): I'm not sure instrumented replacements will be the actual technique we use. 
 But initial versions of the tool will need to either do this, or something even more invasive, so better to say
 *something* about the need to take this kind of action. -->


<p><em>Long-term concern:</em> We want developers to be able to deploy the Async Monitor with minimal changes to their code. A few lines of initialization code is acceptable, but broad changes to many files is not a good customer experience.</p>

<p>Ways to accomplish this are under active discussion, but any solution with such limited source code modification will require one or more of: 1. changes to the Rust standard library, 2. changes to the rust compiler, or 3. use of low-level features such as <a href="https://illumos.org/books/dtrace/chp-intro.html">dtrace probes</a> or <a href="https://ebpf.io/">eBPF</a>. We have not yet decided on which of these options is appropriate.</p>

<p><em>Short term sacrifice</em>: In addition to the initialization code described at the start of the description of <a href="#The.Async.Console.Experience">the developer experience</a>, initial versions of TurboWish also require the developer to swap in instrumented versions of common modules; a provided lint will guide developers in this process and help ensure no instances are overlooked.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">turbowish</span><span class="o">::</span><span class="n">sync</span><span class="o">::</span><span class="n">Mutex</span><span class="p">;</span> <span class="c1">// was previously `use std::sync::Mutex;`</span>
</span></code></pre></td></tr></table></div></figure>


<p>(As already stated above, longer-term, we hope to leverage other facilities to get these instrumentation events.)</p>

<a name="Minimal.Viable.Product:.Tokio-specific"></a>
<h3>Minimal Viable Product: Tokio-specific</h3>

<p><em>Long-term concern:</em> We want the Async Monitor and Console to work with any popular async executor: tokio and async-std are obvious choices here. For the Async Monitor to be useful on an async program, one must use an async executor that has appropriate TurboWish instrumentation added to it.</p>

<p><em>Short term sacrifice:</em> We will deploy a prototype with tokio, but try to keep in mind any differences with other async executors as we design the protocol used for the async executor to communicate with the async monitor.</p>

<a name="Minimum.Viable.Product:.Require.client.instrumentation.for.full-features"></a>
<h3>Minimum Viable Product: Require client instrumentation for full-features</h3>

<p><em>Long-term concern:</em> Client application code can benefit from adding extra instrumentation to their code. However, developers should be able to use and benefit from TurboWish without going to extremes adding new instrumentation beyond what the executor has out-of-the-box.</p>

<p>Some components of the Async Monitor will work with zero client instrumentation. In particular: the initial console output that shows the list of tasks and how their time is spent between polling, ready, and waiting does not require any client instrumentation.</p>

<p>However, other features of the Async Monitor, such as tasks listing resources with which they <em>intend</em> to interact, require either Rust compiler support or client instrumentation, or maybe both.</p>

<p><em>Short term sacrifice:</em> We will prototype under the assumption that clients are willing to add instrumentation. The Async Monitor will differentiate between instrumentation that is &ldquo;trusted&rdquo;: cases where instrumentation bugs will make the Async Monitor and Console produce misleading results (e.g. if transitions between polling and waiting are omitted or forged), and &ldquo;untrusted&rdquo;: cases where instrumention bugs, by design of the monitor, will at most lead to confusion, but not outright lies (e.g. if incorrect attributes are attached to a task or resource, the console output showing those attributes will be likewise incorrect, but it need not disrupt other parts of the Async Monitor or Console).</p>

<a name="Appendix.B:.TurboWish.User.Work.Flow"></a>
<h2>Appendix B: TurboWish User Work Flow</h2>

<!-- The manual height specification is a rough guess, to allow the rest of the doc to predict the space occupied by the graph once it is rendered. -->


<div class="mermaid" style="height: 1750px">
flowchart TD
   Start --> PerfStart
   %% Start --> TasksSeemBlocked
   PerfStart([Performance does not match expectations])
   PerfStart --> QA
   %% TasksSeemBlocked([Tasks seem stuck])
   %% TasksSeemBlocked --> A
   QA{using<br/>async<br/>rust?}
   QA --"yes" --> A
   A --> R --> CC --> QProblemHighlighted
   A[add TurboWish Async Console to service]
   R[start serivce]
   CC[connect to console]
      
   QProblemHighlighted{Console<br/>highlights<br/>problem}
    
   QProblemHighlighted -- "yes" --> ConsoleHighlight
   ConsoleHighlight[observe console output]

   ConsoleHighlight --> PendingWithoutWaker
   PendingWithoutWaker([Console reports:<br/>buggy Future detected])
   
   ConsoleHighlight --> CycleDetected
   CycleDetected([Console reports:<br/>deadlock cycle detected])
   
   PendingWithoutWaker --> UserReadsDocs
   CycleDetected --> UserReadsDocs
   UserReadsDocs[read linked Rust documentation]
   
   UserReadsDocs --> IdentifyRootCause   
   
   QProblemHighlighted -- "no" --> QStuckTask
   
   QStuckTask{any tasks<br/>blocked?}
   
   QStuckTask -- "yes" --> InspectEachStuckTask --> FollowTaskResourceChains --> IdentifyRootCause
   
   InspectEachStuckTask[inspect each stuck task]
   FollowTaskResourceChains[follow task/resource dependencies]
   IdentifyRootCause[identify root cause of problem]
     
   QPH{excessive<br/>memory usage?}
  
   QPH -. "yes" .-> H
   QPH -. "no" .-> P
   
   QA -. "no" .-> QPH
   
   H[use turbowish-heapprof<br/>&lt;future project&gt;]
   P[use turbowish-perf<br/>&lt;future project&gt;]
</div>


<a name="Appendix.C:.Instrumentation.notes..brainstorming."></a>
<h2>Appendix C: Instrumentation notes (brainstorming)</h2>

<p>(This section assumes that a set of related wakers is a reasonable and necessary proxy for &ldquo;resource&rdquo;. This assumption will be revisited during development; the executor controls creation of wakers, so it is a natural point to instrument; but the wakers may not have sufficient context available at their creation points to support describing their associated resource.)</p>

<p>The most basic functionality for the task/resource graph user story requires the executor to emit events whenever:</p>

<ul>
<li>a task is spawned,</li>
<li>a task is dropped,</li>
<li>a waker is created,</li>
<li>a waker is cloned,</li>
<li>a waker is dropped, or</li>
<li>a waker is transferred from one task to another.</li>
</ul>


<p>Supporting other user stories will likely require tracking other information as well (such as how many pending futures have had <code>wake</code> called and are awaiting a call to <code>poll</code>). We may need to add additional hooks to the async executor, analogous to the support for &ldquo;pause&rdquo;, that the Async Monitor can invoke to turn on tracing of such information.</p>

<p>The emitted events should include unique identifiers (UID) for any referenced task/wakers.</p>

<ul>
<li>For values that are themselves boxed or own a heap-allocated value, we should be able to use a memory address as a UID, as long as we also include some sort of timestamp with the events (and the Event Collector will infer when memory is being reused and update its internal model accordingly).</li>
<li>(If we need to track values that do not have a uniquely associated heap values, then we may need to add some sort of unique-id generation for them. So far I haven&rsquo;t seen a need in tokio&rsquo;s types.)</li>
</ul>


<p>The emitted events should also include some notion of the calling context for the event. This calling context should be meaningful from the viewpoint of the Client App Code.</p>

<ul>
<li>For example, when <code>&lt;TimerFuture as Future&gt;::poll</code> calls <code>cx.waker().clone()</code>, we want the waker construction event to include (at minimum) that a waker was created from <code>TimerFuture</code>, so that one can properly tell what <em>kind of resource</em> that <code>waker</code> is associated with.</li>
<li>(It would be even better to include enough information in the event for the Event Collector to know <em>which specific resource</em> is associated with the waker, rather than just its type.</li>
</ul>


<p>These events may include program-internal details such as (partial) stack traces that will include memory addresses of program code</p>

<ul>
<li>(We cannot change existing APIs to thread through details like file/line-number info in the style of <code>#[track_caller]</code>, so in general this is the only way I expect to be able to infer calling context without putting undue burden on client code.)</li>
<li>More specifically: Based on my understanding of the API&rsquo;s available, providing contextual info about the calling context of <code>cx.waker().clone()</code> will require either 1. client instrumentation that sets some thread- or task-local state, or 2. backtracing through the stack to find instruction addresses that the Async Monitor can, via debuginfo, map back to the calling context.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Road to TurboWish; Part 2: Stories]]></title>
    <link href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/"/>
    <updated>2021-04-27T11:21:32-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories</id>
    <content type="html"><![CDATA[<p>It&rsquo;s story-time!</p>

<blockquote><p>As I walk, I think about a new way to walk</p></blockquote>

<p>In my <a href="http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/">previous post</a>, I described the observations that led us to select performance tooling as a focus, as well as the goals document I wrote to guide the next steps of the project. Now I want to show you the User Stories I wrote, to show what I think our customers want (and can reasonably expect) out of performance tools.</p>

<!-- more -->


<p>Everything that follows was taken verbatim<label for='tmbg' class='margin-toggle sidenote-number'></label><input type='checkbox' id='tmbg' class='margin-toggle'/><span class='sidenote'>Okay, not <em>verbatim</em>. <a href="https://twitter.com/pnkfelix/status/1387022496717807622">As promised</a>, I am spicing things up a little, this time via embedding of outright quotations (at an offset), rather than section headings. </span> from the document I presented to the other members of the AWS Rust team. This document is an attempt to describe what I envisage as awesome developer experiences doing performance investigation. As with <a href="http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/">part 1</a>, I will be adding side-commentary on the right-hand margin.</p>

<blockquote><p>As I think, I&rsquo;m using up the time left to think</p></blockquote>

<p>My next post will present the design document that arose from these and other stories, as well as discussions about the realities of what we can expect to implement.</p>

<hr />

<p>Note: These are meant to be read in order: The first describes some up-front investment that the later stories either 1.) assume other developers already put in, or 2.) in the case of user “Barry”, state explicitly that such investment of effort is deliberately skipped by the developer.</p>

<blockquote><p>And this train keeps rolling off the track</p>

<p>Trying to act like something else</p>

<p>Trying to go where it&rsquo;s been uninvited</p></blockquote>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I jumped right in and started making up a story about a newcomer to async Rust.
I did not actually look at examples of user stories as they are typically used in Agile development, or even really how it is done at AWS. It has been a long time since I had read essays describing &ldquo;how&rdquo; to do Agile development; looking at that now, I see that typical user stories are <em>one or two sentences</em>. (I&rsquo;m not sure I can properly convey what I want these tools to do in one or two sentences. I mean, it would be a place to start, but I wanted to spell out the experience. Maybe the reality is that the step I&rsquo;m doing is <em>not</em> a user story. But it <em>does</em> seem like it at least falls into the <a href="https://medium.com/the-digital-project-manager/working-backwards-a-new-version-of-amazons-press-release-approach-to-plan-customer-centric-c17991583508">&ldquo;Working Backwards&rdquo; style</a> that is promoted here at AWS. It also matches the <a href="https://rust-lang.github.io/wg-async-foundations/vision/how_to_vision/shiny_future.html">&ldquo;shiny future&rdquo; story writing</a> approach that Rust&rsquo;s Async Foundations working group has been trail-blazing (apart from the fact that I skipped the step of writing a description of the <a href="https://rust-lang.github.io/wg-async-foundations/vision/how_to_vision/status_quo.html">&ldquo;status quo&rdquo;</a> for each of the stories here).
</span></p>

<a name="User.Story.1:.Abigail"></a>
<h2>User Story 1: Abigail</h2>

<p>Abigail is getting started with async Rust development. She&rsquo;s worked her way through the Async Book and transcribed some example code. Now she&rsquo;s trying to write her first medium sized program, a terminal-based chess program, and it doesn&rsquo;t produce any output after she makes her first move and is waiting for the opponent to move.</p>

<p>After asking for advice about what to do on the Tokio Discord chat, she enables the turbowish feature in her Cargo.toml, and recompiles. She receives warnings from the compiler saying that there are calls to <code>task::spawn</code> but no contextual labels anywhere in her crate.</p>

<p>Abigail reads the compiler&rsquo;s suggestions for the kinds of declarations to add, and adds annotations accordingly, labeling her tasks. (Her program is roughly structured according to an actor model, so she has labels like &ldquo;game AI&rdquo;, &ldquo;move validator&rdquo;, and &ldquo;terminal UI&rdquo;).</p>

<p>Abigail reattempts a build, and now notices some of the previous warnings were not addressed in her change and are emited again: These warnings are about missing labels on resources, namely the channels used for communication between the tasks, e.g. &ldquo;user input&rdquo;, &ldquo;player move&rdquo;, &ldquo;opponent move&rdquo;, etc. She adds labels to the channels, and the program now compiles with no diagnostic warning. She runs her Chess program.</p>

<p>The Chess program starts up, and this time it includes, as part of its console output, a socket to connect to, which is serviced by a dedicated Turbowish thread. She runs a separate tokio-console program, connecting it to the advertised socket on the Chess program. Events begin streaming from the TurboWish thread to the <code>tokio-console</code>. The <code>tokio-console</code> output notes that it has a webserver mode available; she opts into that, and the <code>tokio-console</code> spits out a local URL to connect to. Abigail starts up a web browser and connects it to the URL. The rendered page lists the three tasks.</p>

<p>The Chess program again unexpectedly blocks (or, more precisely, livelocks) after she inputs her first move. Abigail looks at the rendered page, and notices a button that says &ldquo;task dependencies.&rdquo; She clicks it, and the page renders a picture showing a directed graph,<label for='directed-graph' class='margin-toggle sidenote-number'></label><input type='checkbox' id='directed-graph' class='margin-toggle'/><span class='sidenote'>This is the core part of my vision for performance tooling that I strived to preserve when I ported this story into <a href="https://rust-lang.github.io/wg-async-foundations/vision/shiny_future/barbara_makes_a_wish.html">Barbara Makes A Wish</a> on the Async Vision document. </span>
linking tasks and resources (or more generally, wakers), which depicts both 1.) what resources a task is waiting on, and 2.) what tasks are responsible for making those resources available for use.</p>

<p>The resulting rendering shows a cycle in the graph that looks like this, where circular nodes are tasks and rectangular nodes are resources shared by the tasks, like channels.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I am breaking my rule about presenting the verbatim text here. In the document I shared with my colleagues, the underlying file didn&rsquo;t support mermaid or any other markdown-oriented diagramming tools. So there I resorted to something like
<code>(terminal UI)</code> <code>-&gt;</code> <code>[board update]</code> <code>-&gt;</code> <code>(move validator)</code> <code>-&gt;</code> <code>[player move]</code> <code>-&gt;</code> <code>(terminal UI)</code>
in that document, where parentheses and square brackets represent circle vs square node shapes, differentiating tasks from resources.
But I could not bring myself to subject my readers here to that, when its so easy to put in a mermaid diagram.
</span></p>

<!-- The manual height specification is a rough guess, to allow the rest of the doc to predict the space occupied by the graph once it is rendered. -->


<div class="mermaid" style="height: 300px">
graph LR
  AI(("game AI"))
  TUI --> Update --> Validator --> Player --> TUI
  TUI(("terminal UI"))
  Update["board update"]
  Validator(("move validator"))
  Player["player move"]
</div>


<p>Notably, there are no paths in the rendered graph from [board&nbsp;move]<label for='board-move-typo' class='margin-toggle sidenote-number'></label><input type='checkbox' id='board-move-typo' class='margin-toggle'/><span class='sidenote'>I must have meant for this to say [board&nbsp;update]. I had not caught that typo until just now. </span>
to (game&nbsp;AI).</p>

<p>Abigail wonders why the move validator task is waiting for a player move, when she would expect it to be waiting an opponent move from the AI.</p>

<p>She realizes there must be a error in her logic for how either the &ldquo;move&nbsp;validator&rdquo; or the &ldquo;board&nbsp;update&rdquo; are set up, since she would expect the &ldquo;game&nbsp;AI&rdquo; task to be somewhere in the path above.</p>

<p>Moving her mouse over the graph, she notices that the graph edges link to points in her source code. She starts digging in, using the provided links as direction for where to look to figure out what went wrong in her logic.</p>

<blockquote><p>And the rain falls down without my help I&rsquo;m afraid</p></blockquote>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
When I wrote these stories, I felt it would be useful for all of the characters to have names where their first letters corresponded to the letters of the Alphabet: Abigail, Barry, Chris, Daphne. Some feedback I got back almost immediately from Niko Matsakis was &ldquo;Why didn&rsquo;t you re-use the <a href="https://nikomatsakis.github.io/wg-async-foundations/vision/characters.html">characters from the Async Vision cast</a>?&rdquo; I don&rsquo;t have any great answers to that. (The obvious answer was a sheepish &ldquo;I haven&rsquo;t read the Async Vision document yet&hellip;&rdquo;; I have corrected that oversight since then.)
</span></p>

<a name="User.Story.2:.Barry"></a>
<h2>User Story 2: Barry</h2>

<p>Barry is an experienced tokio developer. He has been asked to help out with an AWS cloud service using tokio. The developers of the service are seeing higher latencies than expected for relatively small service requests.</p>

<p>Barry enables tokio&rsquo;s turbowish feature. He opts not to take the compiler&rsquo;s diagnostic suggestions regarding missing contextual labels and downgrades the diagnostic to <code>#![allow]</code> across the crate, knowing that TurboWish will infer labels and attach them automatically based upon crate and module names (and a fixed number of stack frames, when debuginfo is available).</p>

<p>Barry connects <code>tokio-console</code> to the cloud service&rsquo;s socket, and chooses its terminal user-interface instead of the webserver mode.</p>

<p>Barry first asks for a live feed of tasks transition between (<code>running</code>, <code>waiting</code>, <code>ready</code>). The feed produces too much output to the terminal, so Barry sends it to a file instead, and then inspects it in a text editor, trying to see trends by eye. It is a lot of data though, too much for Barry to interpret without more tooling.</p>

<p>Barry has dealt with parsing this output before, though.</p>

<p>Barry has a home-grown script to extract a CSV file with numeric data from the output. Barry imports the CSV file into a spreadsheet and then constructs a histogram with buckets of ranges of individual wait-times, and how many tasks’ transition points are in each bucket.</p>

<p>From this, Barry identifies a small set of tasks that spent an unusually long time in the <code>waiting</code> state. Going back to the original feed, Barry finds the the records for those long waits, which include a link to the point in the source code where the long waits occurred.</p>

<p>Barry looks, and sees a call to <code>std::thread::sleep</code> instead of tokio&rsquo;s sleep function. [TODO: I&rsquo;d be happy to put in some other
example here of blocking code that should be replaced with non-blocking code.]<label for='todo-other-examples' class='margin-toggle sidenote-number'></label><input type='checkbox' id='todo-other-examples' class='margin-toggle'/><span class='sidenote'>This TODO was in here during the team document review. The basic response was &ldquo;eh, std sleep is good enough as an example. It is a real instance of a much more general mistake that people do make, and it gets the idea across.&rdquo; </span></p>

<p>Barry replaces the call <code>std::thread::sleep</code> with tokio&rsquo;s sleep function, and returns to the histogram to see what other instances of unusually long wait times he can find.</p>

<blockquote><p>And my lawn gets wet though I&rsquo;ve withheld my consent</p></blockquote>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
With the Chris story, we have a sudden shift from async-oriented performance issues to compiler developer performance issues. what can I say other than <a href="https://thewritepractice.com/write-what-you-know/">&ldquo;write what you know&rdquo;</a>.
</span>
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
(Interestingly, all the essays I can find on that <a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/WriteWhatYouKnow">trope</a> indicate that it is meant to be about knowledge of <em>inner emotions</em>, not about facts or experience.)
</span></p>

<a name="User.Story.3:.Chris"></a>
<h2>User Story 3: Chris</h2>

<p>Chris is a contributor to the Rust compiler, <code>rustc</code>. Chris is well-versed with Rust, at least for batch programs like the compiler, but they do not do any async Rust development. Chris wants to gain better understanding of memory usage internal to <code>rustc</code> itself.</p>

<p>After asking around in the <code>#compiler-team</code> Zulip stream, Chris enables the <code>build.heap_inspector</code> setting in <code>rustc</code>&rsquo;s build
configuration file, and rebuilds the compiler.</p>

<p>Chris also fires up the TurboWish web frontend. This invocation of TurboWish uses a specialized config file developed and maintained by the Rust compiler team that handles interpreting the types that are special to the compiler.</p>

<p>Chris uses environment variables to indicate which points in the compiler&rsquo;s control flow are of interest to them. More specifically, Chris wants to inspect the heap as it stands immediately after the borrow-checker runs.</p>

<p>The compiler obliges: right after the borrow-checker runs, it starts from a set of known roots (tagged as such ahead of time by the rustc developer) and traverses the ownership graph from those roots,<label for='gc' class='margin-toggle sidenote-number'></label><input type='checkbox' id='gc' class='margin-toggle'/><span class='sidenote'>You can see my garbage-collection background leaking through here. I guess this is an instance of &ldquo;what what you knew&hellip;&rdquo; </span> emitting a description of the arcs it encounters during its traversal. For each heap-allocated value the traversal encounters, the traversal code also
includes information needed to reconstruct its &ldquo;payload size&rdquo;; i.e., enum values will include their discriminant, vectors and string include their length, etc.</p>

<p>The TurboWish web front end receives this stream of graph traversal data. It uses this to provide a table describing the number of objects of each type, and how much internal fragmentation it detects based on the reported payload sizes. Chris inspects this table and determines that that there is an opportunity to reduce fragmentation by changing one of the enums to use a <code>Box</code>. Chris tries it out and sees the memory consumption of the compiler go down, and files a pull request
with the change.</p>

<p>(Note: This user story may or may not not provide value over other tools like dhat, depending on 1. whether it allows tracking allocations at a finer grain than malloc calls (e.g. sub-allocations within an arena) and/or 2. how much value one puts on being able to inspect portions of the heap rooted at certain owners. See also <a href="#Appendix">the appendix</a>, which includes a more ambitious “dream” proposal for Chris, but also one that I personally am not as sure actually pays off in terms of customer value versus mere “coolness” factor.)</p>

<blockquote><p>When this grey world crumbles like a cake</p></blockquote>

<a name="User.Story.4:.Daphne"></a>
<h2>User Story 4: Daphne</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
With Daphne&rsquo;s story, we return to async-oriented performance analysis.
Async is a hot topic, and I figured it was worth exploring other stuff we could deliver. In this case, the idea is to turn the internal logging data into a rendered message sequence chart. (I actually do not know if people use message sequence charts on real logs in practice. I have seen them used <em>very</em> often for presenting small snippets that explain a protocol, but are they actually useful for traversing a complex series of interactions? I can imagine it could be, especially in an interactive presentation that can highlight links and automatically re-center on a selected end of a given arc in a graph.
</span>
Daphne is maintaining an existing a web service built atop tokio. She gets reports of poor performance for certain input queries that match the &ldquo;E&rdquo; command for her service, which already has TurboWish integrated. In response, she attaches <code>tokio-console</code> to her service, and tells it to trace the flow of requests matching the &ldquo;E&rdquo; command (more concretely, <code>[{req.path="/Q"}]=trace</code>), and then fires up the TurboWish web front-end.</p>

<p>Daphne chooses a tab that says &ldquo;Show Scheduler.&rdquo; The resulting page looks something like Message Sequence Chart: Each of tokio&rsquo;s executor threads has a vertical line, and as futures are polled, they have corresponding boxes on the corresponding thread. Since Daphne has limited the output to just events related to the &ldquo;E&rdquo; command, all the futures she sees being scheduled are part of that query.</p>

<p>From skimming the resulting charts, Daphne sees that when the &ldquo;E&rdquo; futures are being polled, they seem to yield again promptly. She does see some evidence the future is migrating to different threads, and she makes a note to try to investigate whether there is a way to ask tokio to avoid such thrashing (and also, whether there are metrics should could gather about whether doing so could help).</p>

<p>There are also points in the program flow when <em>no</em> future related to the &ldquo;E&rdquo; query is scheduled. The event stream does not include information about which futures are polled during those times. Those portions of the executor threads vertical lines are colored dark green: they may be doing useful work, but its not work directly related to the events that have been filtered in.</p>

<p>Daphne realizes that she needs to find out whether the &ldquo;E&rdquo; futures are being left unexecuted because they&rsquo;re still waiting for their corresponding wakers to be invoked, or if the &ldquo;E&rdquo; futures are all ready and there is some other issue in the scheduler (or in the other tasks that causes them to starve the executing threads). Daphne goes to <code>tokio-console</code> and issues the command requesting the feed of all tasks transitioning between (<code>running</code>, <code>waiting</code>, <code>ready</code>). With that, the message sequence chart now shows that her &ldquo;E&rdquo; futures are indeed ready much of the time. She also sees that there are large blocks of time where all of the threads in the pool are running without any interrupt. Daphne hovers the mouse over those rendered blocks of time,  and a pop-up window shows a description of the futures that are being polled at that time. Daphne goes off to investigate that piece of code, and discovers a <code>for</code>-loop with some semi-expensive body that never yields to the executor.</p>

<a name="Appendix"></a>
<h1>Appendix</h1>

<blockquote><p>I&rsquo;ll be hanging from the hope</p>

<p>That I&rsquo;ll never see that recipe again</p></blockquote>

<a name="User.Story.3b:.Chris.s.Dream"></a>
<h2>User Story 3b: Chris&rsquo;s Dream</h2>

<p>Chris wants to inspect the heap as it stands immediately after the borrow-checker runs.</p>

<p>The compiler obliges: right after the borrow-checker runs, it pauses and prompts for the user to connect TurboWish. Chris connects the <code>rustc-console</code> app and interactively asks what root objects are available to inspect. One of the named objects in the result is the &ldquo;MirBorrowckCtxt&rdquo; (i.e. the borrow-checking context). Still working at the terminal <code>rustc-console</code>, Chris first asks for how much memory is solely owned, potentially indirectly by the &ldquo;MirBorrowckCtxt&rdquo; object. <code>rustc-console</code> spits out a number. Chris then asks for how much memory is owned, potentially shared with others (e.g. via <code>Rc</code>), by the object. <code>rustc-console</code> spits out another, much larger number.</p>

<p>Chris connects the TurboWish web front-end, and then queries for a ownership tree describing the values owned by the &ldquo;MirBorrowckCtxt&rdquo; object.</p>

<p>TurboWish does a graph traversal over the owned heap allocated objects, starting from the borrow-checking context (<code>MirBorrowckCtxt</code>) as the root, and emits a description of the arcs it encounters during its traversal, as well as well as the data payload for any fields of types that have been previously marked by the rustc developers as of interest.</p>

<p>The TurboWish web front end renders the resulting graph. But in addition to the direct ownership relatinships implied by the Rust language semantics the graph, it also includes arcs for any <code>&amp;</code>/<code>&amp;mut</code> references in the graph, and it <em>also</em> includes some domain-specific dotted arcs for keys into tables that are meant to be interpreted as references. (This of course is only possible due to the rustc-specialized config file that was included when TurboWish was loaded up.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I think this whole appendix was just an excuse to try to squeeze in a reference to Hyperbolic Trees. Just over twenty years ago, I spent a summer (or was it a year) hacking together code to render a graph via such trees as part of a project called <a href="http://alumni.media.mit.edu/~wex/CHI-99-Footprints.html">Footprints</a>; the linked paper still has screenshots of it.
</span></p>

<p>However, since the object graph is massive, the rendering does not fit on the window. Chris first toggles an option to change the rendering to use a hyperbolic tree (see <a href="https://en.wikipedia.org/wiki/Hyperbolic_tree">https://en.wikipedia.org/wiki/Hyperbolic_tree</a>), where the current object is presented centrally, and immediate children are surrounding smaller nodes, and grand-children are still smaller, et cetera. The hyperbolic tree presentation compacts the view significantly, at the cost of obscuring details of distant descendants and ancestors, as well as cousins.</p>

<p>There is also an option on the presentation UI to have the circles for each node be different sizes depending on how much space they individually occupy on the heap (not including their linked children); Chris enables this setting, just to get a rough visual feeling for where memory space is going in the ownership tree.</p>

<hr />

<p>And that&rsquo;s all the user stories. That&rsquo;s the whole document.</p>

<p>For the sequel, I will be presenting the design document that I think best represents the plan going forward.</p>

<p>We are still figuring things out, to some extent, but I continue to dream about what we can do for our customers, the Rust developers of the world.</p>

<blockquote><p>When the word comes down &ldquo;Never more will be around&rdquo;</p>

<p>Thought I&rsquo;ll wish we were there, I was less than we could bear</p>

<p>And I&rsquo;m not the only dust my mother raised</p>

<p>I am not the only dust my mother raised</p></blockquote>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Road to TurboWish; Part 1: Goals]]></title>
    <link href="http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/"/>
    <updated>2021-04-26T12:51:35-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals</id>
    <content type="html"><![CDATA[<p>This is a post about some recent history. I want to tell the world about a project I am leading at Amazon Web Services, called &ldquo;TurboWish.&rdquo;</p>

<p>TurboWish, in a nutshell, is our umbrella term for a planned suite of tools for understanding your Rust program&rsquo;s dynamic behavior. We want the tools to especially focus on providing insights into the <em>performance</em> characteristics of your program.</p>

<!-- more -->


<p>Let me take a moment to tell you what has happened so far: How did I get here?</p>

<p>(if you want skip the history/motivations and jump <a href="#doc:.Opening.Line">straight to the doc</a>, you can follow that link; you may find yourself
in another part of the world.)</p>

<a name="Into.the.blue.again"></a>
<h2>Into the blue again</h2>

<p>About six months ago, I left Mozilla and joined Amazon Web Services (AWS). I am now part of a new team: the AWS Rust team.</p>

<p>Our team charter is simple: &ldquo;The AWS Rust team works to make Rust performant, reliable, and productive for all its users.&rdquo;</p>

<p>Details of what that means are spelled out via <a href="https://aws.amazon.com/blogs/opensource/how-our-aws-rust-team-will-contribute-to-rusts-future-successes/">our team&rsquo;s tenets</a>.
One of those tenets, one that is incredibly important to me, is that &ldquo;we work in the open.&rdquo; This blog post is itself my own attempt to follow through on that promise: I want to be more open about what I&rsquo;ve been writing down and circulating amongst a relatively small group of people, and try to be better about putting my draft ideas out into the open from the start going forward.</p>

<a name="Same.as.it.ever.was"></a>
<h2>Same as it ever was</h2>

<p>From my perspective, I still have the same personal career goals: make the Rust programming language an awesome option for developers, by improving the code of the Rust compiler, the design of the Rust language, and the organization of the Rust community.<label for='not-improve-community' class='margin-toggle sidenote-number'></label><input type='checkbox' id='not-improve-community' class='margin-toggle'/><span class='sidenote'>Our community is awesome. I would never want to claim that I am trying to &ldquo;improve&rdquo; the community itself. But&hellip; I also would not claim that we have any silver-bullet when it comes to self-organization. </span></p>

<p>Those were my goals when I was at Mozilla, and they are still my goals now.</p>

<a name="You.may.ask.yourself"></a>
<h2>You may ask yourself</h2>

<p>What do performance tools have to do with those goals?</p>

<p>Our team&rsquo;s inspiration for this focus was based on a few observations.</p>

<p>Part of Rust&rsquo;s promise, the reason people are trying Rust out at all, is that it says it can give you the kind of high-performance that in the past was normally the realm of low-level languages like C or C++.<label for='or-fortran' class='margin-toggle sidenote-number'></label><input type='checkbox' id='or-fortran' class='margin-toggle'/><span class='sidenote'>Or FORTRAN, I suppose, though I do not know if Rust is doing much today to target the scientific computing communities that have historically used FORTRAN. </span></p>

<p>At a customer-obsessed company like Amazon, that promise raises an important question.
Are our team&rsquo;s customers,<label for='on-customer-term' class='margin-toggle sidenote-number'></label><input type='checkbox' id='on-customer-term' class='margin-toggle'/><span class='sidenote'>Some people might be confused by this use of the word &ldquo;customer.&rdquo; I admit confusion too, since I do not expect to get any compensation from Rust developers themselves. But I still like the word here; I like that it challenges preconceptions about what a customer <em>is</em>. (Also, I have been using the word &ldquo;customers&rdquo; for projects written in Rust, such as Servo, since at least 2016.) </span>
the developers using Rust, actually seeing such performance wins in practice?</p>

<a name="There.is.water.at.the.bottom.of.the.ocean"></a>
<h2>There is water at the bottom of the ocean</h2>

<p>Based on some discussions and informal interviews with fellow Rust developers, I saw three groups of people with differing answers to that question.</p>

<p>The first group says &ldquo;Rust is great! Once I got it compiling and my unit tests passing, the code works and meets my performance expectations.&rdquo; These customers always made me happy; they are usually happy to then point out what pet features they want to see in the future.</p>

<p>The second group says: &ldquo;I got it compiling, but its not actually as fast as I had hoped. <strong>What should I do now?</strong>&rdquo;</p>

<p>Okay, to be fair, I&rsquo;m making a massive over-generalization there. The second group doesn&rsquo;t always say that. Some of them do <a href="https://blog.mozilla.org/nnethercote/2019/10/11/how-to-speed-up-the-rust-compiler-some-more-in-2019/">extensive analysis</a> to identify awesome ways to make things faster. Some also document exactly what they did and <a href="http://likebike.com/posts/How_To_Write_Fast_Rust_Code.html">how you can do it too</a>.</p>

<p>But the point remains: If Rust <em>isn&rsquo;t</em> meeting your performance goals, its not always obvious what to do. Some people with a lot of in-depth experience with compilers or systems analysis have tools in their utility belt that work well for C/C++ and &hellip; they sort of work for Rust.</p>

<p>But those tools do not work as well as I would like, and I&rsquo;m not sure they are the right answer for the bulk of our community.
I said five years ago that I want Rust to be <a href="https://www.infoq.com/presentations/rust/">Systems Programming for Everybody</a>, and part of that story is that we need tools that everybody can use and understand.</p>

<a name="How.do.I.work.this."></a>
<h2>How do I work this?</h2>

<p>The third group says: &ldquo;I struggle to figure out what design to use. I struggle to get my service compiling. You are asking me what I think about performance, but  I&rsquo;m debugging deadlocks from my <code>async</code> code.&rdquo;</p>

<p>This third group raises an entirely different line of thinking when it comes to tooling. When I first starting thinking about performance monitoring tools, I was thinking solely in terms of gathering and presenting metrics, such as CPU cycles, memory utilization. But this third group represents a broad set of customers for whom such focus is premature: They are hitting road blocks that prevent their project from ever leaving the prototype phase. One big source of problems was <code>async</code> code; there&rsquo;s a good chance that <code>async</code>-specific tooling will provide the biggest return on investment here.</p>

<p>The concerns of the second and third groups what led us to the TurboWish project: tools that will help our customers make Rust deliver on its promises: <a href="https://www.rust-lang.org/">performant, reliable, productive</a>.</p>

<a name="Letting.the.days.go.by"></a>
<h2>Letting the days go by</h2>

<p>After performing a set of informal interviews with various customers both within and outside of AWS, I felt confident that there <strong>are</strong> real problems here to solve. We want Rust developers to have good tools<label for='lang-feats' class='margin-toggle'> &#8853;</label><input type='checkbox' id='lang-feats' class='margin-toggle'/><span class='marginnote'>Ideally, the tools would leverage features of Rust itself: the type system, the ownership model, the value rendering system provided in <code>std::fmt</code>, the virtual method dispatch tables, <em>et cetera</em>. But that is not a strict requirement; it is just &ldquo;nice-to-have.&rdquo; </span>
on hand that will answer their questions.</p>

<p>So, I jumped into writing a goals document, so that our team could explain to other teams at AWS, and ourselves, what we want to make. I shared it with the rest of the AWS Rust team in the middle of February 2021; they had lots of feedback, but I am not including that here (mostly to avoid having to coordinate authorship of this blog post).</p>

<p>I am ending this blog post with that goals document, warts and all, along with meta-commentary in the right-hand margin notes.
In follow-on blog posts this week, I will share some of the next steps that followed after I wrote this.</p>

<a name="doc:.Opening.Line"></a>
<h3>doc: Opening Line</h3>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
You can see in the opening line itself the focus on <code>async</code>/<code>await</code>, for better or for worse.
</span>
TurboWish is a framework for profiling Rust programs, focused on illuminating the performance and resource usage of task-oriented code written with async/await.</p>

<a name="doc:.Goals"></a>
<h3>doc: Goals</h3>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I played a bit of a semantic shell game here, with my use of the term &ldquo;production code.&rdquo; That term could be interpreted as &ldquo;code deployed as a live service.&rdquo; Or it could be interpreted as &ldquo;code compiled in release mode, but still running on development boxes.&rdquo; I plan to talk more about this distinction in later posts, but the short version is: I think we can provide great value today to developers working on their development boxes, without trying to concern ourselves with making a tool that is sufficiently low-overhead and security risk-free that it could be part of a deployed system.
</span>
<em>Profile Production Code</em>: Incorporating the TurboWish Framework is low-overhead: it can be incorporated into production code without producing an undue maintenance burden and without incurring significant performance overhead.</p>

<p><em>Domain-specific Feedback</em>: Frameworks and applications can provide data for specialized metrics, specific to their internal architecture.</p>

<p><em>Understand Hidden Costs and Connections</em>: Frameworks like tokio ease writing asynchronous code because they hide a number of details behind abstractions (such as generator code produced by the Rust compiler, or task queues managed by the tokio runtime). TurboWish exposes those hidden details, allowing developers to correlate them with other program events. It also exposes connections that humans usually have to reconstruct by hand (such as future to resource to future chains that can yield deadlock), allowing one to directly see from Rust’s ownership model how resources are being held in the object graph.</p>

<p><em>Framework Agnostic</em>: Many of Rust’s customers use tokio, but not all of them. async-std  and fuschia_async are other frameworks for asynchronous programming. TurboWish can provide value to any such framework (though it may also provide framework-specific functionality when warranted). For our initial releases, we can focus on tokio alone, but expect integration with others if tokio proves successful.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I included this goal specifically because I had done a bunch of investigation into using <a href="https://rr-project.org/"><code>rr</code></a>, and discovered during that time that some of the cloud development machines hosted on <a href="https://aws.amazon.com/ec2/">EC2</a> do not support the performance counters that you need for <code>rr</code> to function.
</span>
<em>EC2 Instance Type Agnostic</em>: If we make use of any OS specific features (e.g. dtrace probes), they will be available on all EC2 AL2 instances, regardless of instance-type. (Specifically, we cannot require access to CPU performance counters.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
It was an interesting exercise writing this schedule. There are a number of constraints that I was trying to meet that are not represented in this table.
The biggest one was that the Rust release schedule itself follows a six-week cadence; if TurboWish needs any support from <code>rustc</code> itself, and we want it to be available in the stable version of the compiler at the end of October, then that means any such support needs to land in the nightly version of <code>rustc</code> before July 29th.
</span></p>

<a name="doc:.Milestones"></a>
<h3>doc: Milestones</h3>

<table>
<thead>
<tr>
<th>Milestone</th>
<th>Deadline</th>
</tr>
</thead>
<tbody>
<tr>
<td>3 to 5 User Stories identified for core focus</td>
<td>26 Feb 2021</td>
</tr>
<tr>
<td>Development Tracks identified</td>
<td>26 Mar 2021</td>
</tr>
<tr>
<td>PR/FAQ published</td>
<td>2 Apr 2021</td>
</tr>
<tr>
<td>3 Launch Partners established</td>
<td>30 Apr 2021</td>
</tr>
<tr>
<td>alpha prototype</td>
<td>2 Jul 2021</td>
</tr>
<tr>
<td>feedback gathered from demo of alpha to Launch Partners</td>
<td>16 Jul 2021</td>
</tr>
<tr>
<td>beta release</td>
<td>20 Aug 2021</td>
</tr>
<tr>
<td>beta integrated with Launch Partner code bases</td>
<td>17 Sep 2021</td>
</tr>
<tr>
<td>Evaluation Report of beta (interviews with Launch Partners)</td>
<td>24 Sep 2021</td>
</tr>
<tr>
<td>1.0 release</td>
<td>29 Oct 2021</td>
</tr>
</tbody>
</table>


<a name="doc:.Milestone.explanation"></a>
<h3>doc: Milestone explanation</h3>

<p><em>Development Tracks</em>: Some features of TurboWish will provide the most value to customers if they are developed in concert with additions to other components of the Rust ecosystem, such as the Rust compiler. However, we are not the sole owners of the Rust ecosystem nor those components. We need to identify target components of interest early (and I am assuming that part of that identification will require actual prototyping, which is why I am allocating a month for such prototyping in parallel with drafting the PR/FAQ<label for='pr-faq' class='margin-toggle sidenote-number'></label><input type='checkbox' id='pr-faq' class='margin-toggle'/><span class='sidenote'>I was unaware of the PR/FAQ format before joining AWS, but it is apparently used in many customer-centric and agile development models; see also <a href="https://medium.com/agileinsider/press-releases-for-product-managers-everything-you-need-to-know-942485961e31">this medium post</a>. </span>), so that we can properly prioritize such development. In each case where we do not own the component, we must also establish the backup plan if our desired changes will not land in time for use in the product this year.</p>

<p><em>Launch Partners</em>: Customers within Amazon are willing to evaluate pre-release versions of the product. We should strategically select three such customers to partner with us; these are the Launch Partners. We will give each such launch partner 1.) demonstrations of the alpha proof of concept, 2.) access to the beta minimum viable product, and 3.) dedicated engineering time for integrating the beta into their service. In exchange, the launch partner will give us feedback on the alpha and beta versions of the product (which will inform each subsequent development sprint).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
For some reason I was especially proud of the distinction being drawn in this paragraph. I have a somewhat superficial understanding of project management and Agile development methods, so I was not really thinking about whether demo&rsquo;s are common products of a sprint. (And a <a href="https://www.jrothman.com/mpd/2007/10/release-able-vs-demo-able/">post by Johanna Rothman</a> makes the great point that even a product that is &ldquo;only&rdquo; demo-able has still demonstrated <em>integration amongst the team</em>.)
From my perspective, the demo/release distinction had an entirely different motivation: I simply did not see time in the schedule for the year for two full release plus integration plus customer-feedback cycles.
</span>
<em>Alpha Demo</em> versus <em>Beta Release</em>: We want to move quickly, develop a minimum viable product and then iterate on it until we have something that delights our customers. We also want to work with a set of dedicated launch partners to evaluate an early version of the product (the beta). However, a product like this is unlikely to be a tool that can be trivially integrated: we expect there to be some amount of development effort associated with linking TurboWish into a given code base. Therefore, we do not expect our launch partners to be able to participate in multiple iterations of evaluating the product, simply due to the amount of development effort each integration is likely to take. So, we propose using different evaluation methodologies for different iteration cycles: For the alpha version, we will integrate TurboWish into code bases that we choose ourselves, give demos of the integrated result to our Launch Partners, and use their feedback in subsequent development of the alpha. For the beta version, we will work with our Launch Partners to integrate TurboWish into their code bases, and then at the end of the integration period, we will use the feedback they provide to make the final changes to the product.</p>

<a name="doc:.Risks..Mitigations"></a>
<h3>doc: Risks, Mitigations</h3>

<blockquote><p>Risk: Time from “development tracks identified” to “PR/FAQ published” is only a week.<label for='dev-track-to-pr-faq' class='margin-toggle sidenote-number'></label><input type='checkbox' id='dev-track-to-pr-faq' class='margin-toggle'/><span class='sidenote'>This risk was accurate. It took quite a while longer for me to make a suitable design document. That document will be the subject of a later post. </span></p></blockquote>

<p>Mitigation: We need to develop the PR/FAQ in parallel with doing the feasibility studies that identify the development tracks. (But I do not want to make them independent milestones; I want to be confident that the features in the PR/FAQ can be constructed before I try to enlist Launch Partners.)</p>

<blockquote><p>Risk: Rust compiler leadership/maintenance will distract pnkfelix.<label for='compiler-work' class='margin-toggle sidenote-number'></label><input type='checkbox' id='compiler-work' class='margin-toggle'/><span class='sidenote'>Another way to look at this: &ldquo;the TurboWish work will distract pnkfelix from their compiler development efforts.&rdquo; And indeed, both can be true. </span></p></blockquote>

<p>Mitigation 1. Get buy-in from others and spread development effort</p>

<p>Mitigation 2. Compiler Team focus for 2021 is rustc contributor experience, especially w.r.t. performance. Hopefully synergies will emerge from that.</p>

<blockquote><p>Risk: Not much time remaining in February to establish user stories. Felix’s personal focus for short term are memory usage issues, and so he has been contributing stories related to that. But many customers express concern related to async/await, especially about understanding why their tasks fail to progress (i.e. sources of deadlock).</p></blockquote>

<p><em>(No mitigation documented.)</em><label for='no-mitigation' class='margin-toggle sidenote-number'></label><input type='checkbox' id='no-mitigation' class='margin-toggle'/><span class='sidenote'>I did not come up with a mitigation for this risk. I just hoped I would have time to write something reasonable. </span></p>

<blockquote><p>Risk: Some features may depend on some amount of GC style tracing, potentially starting from local owned variables on the stack as roots, and in any case traversing values on the heap. (For example, automatically dissecting ownership chains between futures and resources in order to identify causes of deadlock could make use of such tracing.) pnkFelix has experience in this area and believes it to be a solvable problem (especially given the profiling goal, as opposed to correct integration with arbitrary 3rd party GC tech), but it is not a settled problem.</p></blockquote>

<p>Mitigation: Leverage ownership of relevant frameworks where possible. E.g. you don’t need to trace the local stack if you know your “root set” of interest is the set of tokio tasks. And you don’t need to make an general-purpose value-tracing system when a make-shift trait and associated derive will suffice for the specific problem at hand.</p>

<a name="Time.isn.t.holding.us...Time.isn.t.after.us"></a>
<h2>Time isn&rsquo;t holding us / Time isn&rsquo;t after us</h2>

<p>And that&rsquo;s the goals doc, as it stood in mid-February</p>

<p>Like I said above, there was a bit of a journey to get to this point. And even with this document in hand, we do not have enough to start making code: I wouldn&rsquo;t be able to hand this to a programmer and say &ldquo;do this.&rdquo;</p>

<p>But I had goals. And I had a schedule. What was next on the schedule? <a href="http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/"><em>User Stories.</em>, the subject of the next blog post.</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to dismantle an Atomic bomb]]></title>
    <link href="http://blog.pnkfx.org/blog/2021/03/25/how-to-dismantle-an-atomic-bomb/"/>
    <updated>2021-03-25T15:22:22-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2021/03/25/how-to-dismantle-an-atomic-bomb</id>
    <content type="html"><![CDATA[<a name="The.problem"></a>
<h1>The problem</h1>

<p>Driving deallocation of state via ref-counting under our current atomic API means that you cannot avoid having a <code>&amp;AtomicUsize</code> variable at the same time that you are deallocating the block of memory that contains the referenced atomic usize state.</p>

<a name="The.proposal"></a>
<h1>The proposal</h1>

<p>The idea is simple.</p>

<p>Experienced Rustaceans know that in the general case, <code>&amp;T</code> doesn&rsquo;t actually mean immutable; it merely signals that unsynchronized mutation through aliases is disallowed. Interior mutability is still an option, via <code>Cell</code> or <code>AtomicUsize</code>.</p>

<p>All such sources of interior mutability <em>are</em> tracked in the type system. Namely, they all have an <code>UnsafeCell&lt;U&gt;</code> somewhere in the structure layout that tells the compiler that such mutation is permitted on the <code>U</code> inside the unsafe cell. Thus the compiler knows it cannot make optimizations that rely on that <code>U</code> remaining invariant.</p>

<p>So, here&rsquo;s the suggested change: if code needs to allow for concurrent actors (or even aliasing accesses on the current thread) to mutate some state, that same code must allow that those accesses might <em>deallocate</em> that state.</p>

<!-- more -->


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
That is, &ldquo;may be modified or deallocated&rdquo; unless (of course) the compiler/author has some extra proof or established invariant that the memory M cannot be deallocated. Such invariants are the very basis of ref-counting, for example.
</span>
In other words: in addition to saying that the content of an <code>&amp;UnsafeCell&lt;U&gt;</code> might be modified via an alias, we also say that the memory holding the unsafe cell may even be outright <em>deallocated</em>, despite any extant <code>&amp;</code>-references to that unsafe cell.</p>

<p>These statements about &ldquo;what may happen&rdquo; are talking about what reasoning you can employ locally, based on the type declarations.</p>

<a name="L.Background..The.Issue:.Side-effects.of.atomic.operations"></a>
<h1>(Background) The Issue: Side-effects of atomic operations</h1>

<p>The status quo: I will present a strawman atomic-reference counted type (analogous to <code>std::rc::Arc</code>).</p>

<p>It needs a heap-allocated payload, along with the reference count.</p>

<p>As an added part of this strawman presentation, I&rsquo;m going to have the ref-counted object also carry a single-character label. The label will be used to illustrate potential program transformations (i.e. compiler optimizations) as we progress. (Furthermore, I will try to catch
use-after-free bugs resulting from these transformations by reallocating memory and scribbling on it before the label accesses.)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">std</span><span class="o">::</span><span class="n">sync</span><span class="o">::</span><span class="n">atomic</span><span class="o">::</span><span class="p">{</span><span class="bp">self</span><span class="p">,</span> <span class="n">AtomicUsize</span><span class="p">,</span> <span class="nb">Ordering</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">type</span> <span class="n">Data</span> <span class="o">=</span> <span class="p">[</span><span class="kt">u8</span><span class="p">;</span> <span class="mi">128</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">LabelledPayload</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">label</span><span class="o">:</span> <span class="n">char</span><span class="p">,</span>
</span><span class='line'>    <span class="cp">#[allow(dead_code)]</span>
</span><span class='line'>    <span class="n">data</span><span class="o">:</span> <span class="n">Data</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">Inner</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">ref_count</span><span class="o">:</span> <span class="n">AtomicUsize</span><span class="p">,</span>
</span><span class='line'>    <span class="n">payload</span><span class="o">:</span> <span class="n">LabelledPayload</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>fn dealloc</code> is a small shim around Box-based deallocation to keep the examples cleaner; <code>fn scribble</code> is a routine that tries to catch us if we have a use-after-free.  by making a fresh allocation and overwriting its state.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">dealloc</span><span class="p">(</span><span class="n">ptr</span><span class="o">:</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">drop</span><span class="p">(</span><span class="n">Box</span><span class="o">::</span><span class="n">from_raw</span><span class="p">(</span><span class="n">ptr</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">Inner</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">scribble</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">Box</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">Inner</span> <span class="p">{</span> <span class="n">ref_count</span><span class="o">:</span> <span class="n">AtomicUsize</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">payload</span><span class="o">:</span> <span class="n">LabelledPayload</span> <span class="p">{</span> <span class="n">label</span><span class="o">:</span> <span class="sc">&#39;X&#39;</span><span class="p">,</span> <span class="n">data</span><span class="o">:</span> <span class="p">[</span><span class="mi">0</span><span class="p">;</span> <span class="mi">128</span><span class="p">],</span> <span class="p">}</span> <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="n">macro_rules</span><span class="o">!</span> <span class="n">scribble_then_println</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">(</span><span class="err">$</span><span class="n">template</span><span class="o">:</span> <span class="n">expr</span><span class="p">,</span> <span class="err">$</span><span class="n">label</span><span class="o">:</span><span class="n">expr</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">scribble</span><span class="p">();</span>
</span><span class='line'>        <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="err">$</span><span class="n">template</span><span class="p">,</span> <span class="err">$</span><span class="n">label</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(In reality the <code>Payload</code> type would usually a generic type <code>T</code>, but this is detail we can side-step for this discussion.  The same issues with atomics still arise, and side-stepping generics simplifies the presentation in various ways with respect to issues of variance, <code>PhantomData</code> and <code>?Sized</code>.)</p>

<p>You will also need the handles that have (fractional) ownership of each heap-allocated <code>Inner</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">ptr</span><span class="o">:</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(In practice the type of the <code>ptr</code> field would actually be <code>core::ptr::NonNull&lt;Inner&gt;</code>, but that is a niche optimization we can sidestep in this presentation.)</p>

<p>The allocation code and ref-count maintenance code would look
something like this</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">new</span><span class="p">(</span><span class="n">label</span><span class="o">:</span> <span class="n">char</span><span class="p">,</span> <span class="n">data</span><span class="o">:</span> <span class="n">Data</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">x</span> <span class="o">=</span> <span class="n">Box</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">Inner</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">ref_count</span><span class="o">:</span> <span class="n">atomic</span><span class="o">::</span><span class="n">AtomicUsize</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span>
</span><span class='line'>            <span class="n">payload</span><span class="o">:</span> <span class="n">LabelledPayload</span> <span class="p">{</span> <span class="n">label</span><span class="p">,</span> <span class="n">data</span> <span class="p">},</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>        <span class="n">Self</span> <span class="p">{</span> <span class="n">ptr</span><span class="o">:</span> <span class="n">Box</span><span class="o">::</span><span class="n">leak</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span> <span class="nb">Clone</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span> <span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_add</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Relaxed</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>        <span class="c1">// (we&#39;ll skip preventing overflow; see Arc code for those details.)</span>
</span><span class='line'>        <span class="n">Handle</span> <span class="p">{</span> <span class="n">ptr</span><span class="o">:</span> <span class="bp">self</span><span class="p">.</span><span class="n">ptr</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The troubles arrive with the destructor code that decrements the ref count and deallocates the heap-allocated value if the resulting ref-count is zero.</p>

<a name="Version.1:..inner-ref.handled.inline."></a>
<h2>Version 1: &ldquo;inner-ref handled inline&rdquo;</h2>

<p>One &ldquo;obvious way&rdquo; to do it is with something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version1&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">Inner</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">)</span> <span class="p">};</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">label</span><span class="o">:</span> <span class="n">char</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// reminder: concurrent actors may also be running drop, decrementing the ref-count...</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_sub</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Release</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// ... so at this point in control flow, if `pre_decr &gt; 1`,</span>
</span><span class='line'>        <span class="c1">// then someone else might be freeing `*inner` (or have</span>
</span><span class='line'>        <span class="c1">// already freed it). Now the only time it is safe to</span>
</span><span class='line'>        <span class="c1">// access `*inner` is if we can prove we are sole remaining</span>
</span><span class='line'>        <span class="c1">// owner (i.e. that `pre_decr == 1`).</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="n">pre_decr</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">unsafe</span> <span class="p">{</span> <span class="n">dealloc</span><span class="p">(</span><span class="n">inner</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;version1 dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This code is designed to deallocate the heap-allocated <code>Inner</code> on some paths. But at the same it does that, the local variable <code>inner: &amp;Inner</code> is still in (lexical) scope.</p>

<p>Is <em>this</em> okay?</p>

<p>In general within this document, when I write &ldquo;is <em>this</em> okay&rdquo;, it is meant as a rough short-hand for the following more elaborate text:</p>

<p>Does allowing a deallocation like <em>this</em> break any of:</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
(Of course items (b.) and (c.) should in principle be derived from (a.); but we do not have a specification on hand, while we do have concrete examples of compiler optimizations and unsafe code that people write in practice, so that is why I try to spell them out as explicit concerns to keep in mind.)
</span>
(a.) the memory model we hope to have for the language itself,
(b.) compiler optimizations today or tomorrow, or
(c.) <code>unsafe</code> code people write in practice today or tomorrow?</p>

<p>What is an example of a code transformation one might consider (for either compiler optimization or unsafe code authors)? Well: in version 1, we have code that looks like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kd">let</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">Inner</span> <span class="o">=</span> <span class="p">[...];</span>
</span><span class='line'>  <span class="kd">let</span> <span class="n">label</span><span class="o">:</span> <span class="n">char</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">;</span>
</span><span class='line'>  <span class="p">[...]</span>
</span><span class='line'>  <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A reasonable person might say &ldquo;clearly <code>*inner</code> has to be valid and immutable for its whole scope, and that <code>label</code> has only one use. So we should be able to transform it to this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kd">let</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">Inner</span> <span class="o">=</span> <span class="p">[...];</span>
</span><span class='line'>  <span class="p">[...]</span>
</span><span class='line'>  <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">inner</span><span class="p">.</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I tried to use a semi-novel name, specific to the example, because I don&rsquo;t want to get bogged down debating what optimization we&rsquo;re discussing, where it lives, and how it justifies its actions. So instead I&rsquo;m choosing something relatively self-contained, easy-to-explain, and potentially incorrect.
</span>
Let&rsquo;s call this the &ldquo;Label Code Motion&rdquo; transformation.</p>

<p>If version 1 of the <code>impl Drop for Handle</code> code is okay, then Label Code Motion cannot be applied here. Is <em>that</em> expected?</p>

<p>(Perhaps so; perhaps such code motion must be justified with deeper analysis of the other code I&rsquo;ve elided here, rather than be justifed
by the types alone.)</p>

<p>(As you might have guessed, the whole reason I put in the <code>scribble_then_println!</code> macro was to illustrate that things <em>do</em> go
wrong if you apply the Label Code Motion transformation to version 1.
So <em>something</em> is wrong; later we will try to establish whether version 1 itself is to blame or the Label Code Motion transformation.)</p>

<p>Nonetheless, let us assume that version 1 is okay, at least going into the
discussion of version 2.</p>

<p>(We will revisit the question of the correctness of each variant at
the end of the document.)</p>

<a name="Version.2:..inner-ref.handled.out-of-line."></a>
<h2>Version 2: &ldquo;inner-ref handled out-of-line&rdquo;</h2>

<p>Consider this different factoring of the code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version2&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">may_drop_inner</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">(</span><span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="n">Inner</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_sub</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Release</span><span class="p">);</span>
</span><span class='line'>    <span class="c1">// (at this point, `pre_decr &gt; 1` ==&gt; someone else might be freeing `*inner`)</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">pre_decr</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span> <span class="n">dealloc</span><span class="p">(</span><span class="n">inner</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version2&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">Inner</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">;</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">label</span><span class="o">:</span> <span class="n">char</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">;</span>
</span><span class='line'>            <span class="n">may_drop_inner</span><span class="p">(</span><span class="n">inner</span><span class="p">);</span>
</span><span class='line'>            <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;version2 dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we have <code>fn may_drop_inner</code> which takes a <code>&amp;'a Inner</code> as a function parameter.</p>

<p>My own intuition about function arguments in such cases is that &ldquo;obviously&rdquo;
the value <code>*inner</code> has to live as long as the lifetime <code>'a</code>, and that lifetime &ldquo;obviously&rdquo; has to be longer than the invocation of <code>may_drop_inner(inner)</code>, right?</p>

<p>The intuition in the previous paragraph implies that Version 2 (&ldquo;inner-ref handled out-of-line&rdquo;) is <em>not</em> correct.</p>

<p>So: Is my intuition wrong? (Maybe; we&rsquo;ll revisit that in a moment.)</p>

<p>If my intuition is right (and thus version 2 is not okay), then: Is the refactoring transformation from version 1 to version 2 wrong? Or does non-okay-ness for version 2 imply that version 1 is also not okay?</p>

<a name="Version.3:..atomic-ref.handled.inline."></a>
<h2>Version 3: &ldquo;atomic-ref handled inline&rdquo;</h2>

<p>Let us consider this variant on version 1.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version3&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ref_count</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AtomicUsize</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">ref_count</span> <span class="p">};</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">label</span><span class="o">:</span> <span class="n">char</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span> <span class="p">};</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_sub</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Release</span><span class="p">);</span>
</span><span class='line'>        <span class="c1">// (at this point, `pre_decr &gt; 1` ==&gt; someone else might be freeing `*self.ptr`)</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">pre_decr</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">unsafe</span> <span class="p">{</span> <span class="n">dealloc</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;version3 dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, instead of holding a whole <code>&amp;Inner</code> reference, we are holding &ldquo;just&rdquo; an <code>&amp;AtomicUsize</code> reference. It still is a pointer to storage that is deallocated on some control-flow paths, but we again are careful to never dereference it after the decrement (because after the decrement, concurrent actors could deallocate <code>*self.ptr</code>).</p>

<p>Clearly if version 1 is okay, then version 3 should be too, right?</p>

<p>But what about the other direction: can version 3 be okay even if version 1 is not okay?  Well, notably, now one cannot apply the Label Code Motion optimization: at the point where <code>println!</code> is called, there is no <code>&amp;Inner</code> in lexical scope to pull the label out of. So that may be evidence in favor of permitting version 3 while disallowing versions 1 and 2.</p>

<p>We have one more variant to consider in our matrix.</p>

<a name="Version.4:..atomic-ref.handled.out-of-line."></a>
<h2>Version 4: &ldquo;atomic-ref handled out-of-line&rdquo;</h2>

<p>Now let us take the refactoring we saw when we made version 2, and apply that refactoring to version 3.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version4&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">unsafe</span> <span class="k">fn</span> <span class="n">may_drop_owner</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ref_count</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="n">AtomicUsize</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">usize</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_sub</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Release</span><span class="p">);</span>
</span><span class='line'>    <span class="c1">// (at this point, `pre_decr &gt; 1` ==&gt; someone else might be freeing owner of `*ref_count`)</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">pre_decr</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;version4&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">label</span><span class="o">:</span> <span class="n">char</span><span class="p">;</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">ref_count</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">AtomicUsize</span> <span class="o">=</span> <span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">ref_count</span><span class="p">;</span>
</span><span class='line'>            <span class="n">label</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">;</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">may_drop_owner</span><span class="p">(</span><span class="n">ref_count</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="n">pre_decr</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">dealloc</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;version4 dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In short, we took the ref-count decrement and moved it into its own local function.</p>

<p>And we might take the same intuition about function arguments from version 2 and apply it to <code>fn may_drop_owner</code> in version 4: &ldquo;doesn&rsquo;t <code>*ref_count</code> have to outlive the lifetime <code>'a</code>? How can we allow a concurrent actor to free <code>*ref_count</code> here?&rdquo;</p>

<p>An important insight about version 4: the <code>fn may_drop_owner</code> is nearly a trivial wrapper around <code>AtomicUsize::fetch_sub</code>. So if <code>fn may_drop_owner</code> ends up classified as &ldquo;not okay&rdquo;, then under what mental model is <code>AtomicUsize::fetch_sub</code> &ldquo;okay&rdquo;? (In other words, how can one write any helper functions if something this simple is not okay.)</p>

<a name="Version.5:..out-of-band.ref-count."></a>
<h2>Version 5: &ldquo;out-of-band ref-count&rdquo;</h2>

<p>In the discussion on <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/252">UCG#252</a>, Ralf pointed out other corner cases
one might consider. In particular, so far the cases I&rsquo;ve shown here
have ref-count on the allocated memory block itself. But one can also imagine
scenarios where the ref-count is stored elsewhere.</p>

<p>However: I argue that an out-of-band ref-count does not hit the particular
problem I am concerned with. Since the ref-count is not stored with the heap-allocated
block, we are simply not going to encouter the issue described here.</p>

<p>(Such a system may encounter similar problems when it designs its
system for deallocating the out-of-band ref-counts themselves, but
without more concrete details about the proposal, it is hard to make
suggestions about how to handle it.)</p>

<p>See also: <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/88">https://github.com/rust-lang/unsafe-code-guidelines/issues/88</a></p>

<a name="Summary.of.versions"></a>
<h2>Summary of versions</h2>

<p>Here&rsquo;s a matrix summarizing the first four variants I posted above.</p>

<table>
<thead>
<tr>
<th>             </th>
<th>   in-line   </th>
<th> out-of-line </th>
</tr>
</thead>
<tbody>
<tr>
<td>  <code>&amp;Inner</code>   </td>
<td> (version 1) </td>
<td> (version 2) </td>
</tr>
<tr>
<td> <code>&amp;AtomicX</code>  </td>
<td> (version 3) </td>
<td> (version 4) </td>
</tr>
</tbody>
</table>


<a name="What.options.might.we.consider"></a>
<h2>What options might we consider</h2>

<a name="Option.1..Outlaw.them.all"></a>
<h3>Option 1. Outlaw them all</h3>

<p>Preface: This space held my preferred solution when I first started seriously looking at this months ago (but don&rsquo;t worry, I end up arguing against these &ldquo;outlaw them all&rdquo; variants).</p>

<p>When I first looked at this problem, I thought the right answer would be to outlaw all four versions. That is, I thought my intuition about function arguments should extend to all lexical scopes for all <code>&amp;T</code>, and therefore it was simply always wrong to let the ref-count decrement on something else in a <code>&amp;T</code> (whether <code>T</code> is <code>Inner</code> or <code>AtomicUsize</code>) drive the deallocations shown above.</p>

<p>At that time, the &ldquo;clear&rdquo; answer to my point of view was that all four cases should instead have been manipulating either a <code>*const Inner</code> or a <code>*const AtomicUsize</code> at all times. (This would trivially disallow the Label Code Motion transformation, since no <code>&amp;Inner</code> would be in scope at the point where <code>label</code> is printed.)</p>

<p>A critical problem with this point of view is that we don&rsquo;t offer any way for someone to decrement an atomic direectly on a <code>*const AtomicX</code> pointer.  Our atomics API for e.g. <code>AtomicUsize::fetch_sub</code> <em>forces</em> the developer to pass in a <code>&amp;AtomicX</code>.</p>

<p>So we have to refine this option in some way. Here are two variants I considered.</p>

<a name="L1a..Outlaw.them.all.and.stick.with.current.atomic.API"></a>
<h4>1a. Outlaw them all and stick with current atomic API</h4>

<p>Since the API forces the developer to pass an <code>&amp;AtomicUsize</code> to <code>fetch_sub</code>: Maybe the developer handles <code>*const AtomicX</code> in their code, but casts it via <code>as</code> back to <code>&amp;AtomicX</code> at the <code>fetch_sub</code> calls? But then can the developer similarly cast the <code>*const Inner</code> to a <code>&amp;Inner</code> and trust that the lifetimes will work out in their favor? (No, that doesn&rsquo;t work; one ends up in the same morass again.)</p>

<p>In short, I don&rsquo;t think this option is reasonable. Even if we could come up with a semantics for what people are supposed to do, I think it will be too confusing for people to understand what the ref-to-ptr and ptr-to-ref casts in each spot convey.</p>

<a name="L1b..Outlaw.them.all.and.put.in.alternative.atomic.API"></a>
<h4>1b. Outlaw them all and put in alternative atomic API</h4>

<p>Why not have variants of <code>AtomicUsize::fetch_sub</code> and similar atomic methods that take a <code>*const AtomicUsize</code> as their formal parameter? If the standard library provided that, then the developer could be advised to only manipulate <code>*const Inner</code> or <code>*const AtomicUsize</code> in code like this, and they would be able to pass <code>*const AtomicUsize</code> to the relevant methods.</p>

<p>There&rsquo;s a host of answers as to why we wouldn&rsquo;t want to do this:</p>

<ul>
<li><code>*const</code>-pointers are hard to work with (e.g. we don&rsquo;t support <code>*const
self</code>-methods);</li>
<li>it would force us to duplicate a large portion of the API surface and maintain it,</li>
<li>we would have to bikeshed whether these methods take <code>*const</code> or <code>*mut</code>, and</li>
<li>perhaps most importantly, it would be a ongoing source for  confusion with users as to when they should use the <code>&amp;AtomicX</code> methods versus when they should use the <code>*const AtomicX</code> methods,   (note in particular that we almost certainly wouldn&rsquo;t want to deprecate the <code>&amp;AtomicX</code> variants in favor of the <code>*const AtomicX</code> variants).</li>
</ul>


<p>So: Let us at least consider other options.</p>

<a name="Option.2..Allow.them.all"></a>
<h3>Option 2. Allow them all</h3>

<p>I wasn&rsquo;t going to talk about this option when I started writing, but after taking the time to develop the matrix of variants, I figure its worth at least talking about it.</p>

<p>If we were to allow all four variants, then the my own mental model about <code>&amp;T</code> would be incorrect.  The Label Code Motion optimization could not be applied via type-based reasoning; thus, people (or compilers) who used such reasoning to justify such transformations would be performing an incorrect transformation.</p>

<p>When I first started writing this section, I wanted to include this assertion:</p>

<blockquote><p>I suspect very little Rust code used in production today would actually fall into that category of &ldquo;unsound because incorrect reasoning was used to justify this code&rdquo;</p></blockquote>

<p>But I don&rsquo;t know if I believe that assertion anymore. Use-after-free bugs happen.  Code like the below (the result from applying Label Code Motion) is going to happen (and, as you might guess, you get a scribbled label due to the use-after-free here). But there&rsquo;s nothing in the <em>type structure</em> of how <code>Inner</code> holds its label field that would give you a hint that <code>inner.payload.label</code> could be invalid there.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(feature = </span><span class="s">&quot;locomotion&quot;</span><span class="cp">)]</span>
</span><span class='line'><span class="k">impl</span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Handle</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="nb">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">Inner</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">)</span> <span class="p">};</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">pre_decr</span> <span class="o">=</span> <span class="n">inner</span><span class="p">.</span><span class="n">ref_count</span><span class="p">.</span><span class="n">fetch_sub</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Ordering</span><span class="o">::</span><span class="n">Release</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">pre_decr</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">unsafe</span> <span class="p">{</span> <span class="n">dealloc</span><span class="p">(</span><span class="n">inner</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="n">Inner</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;locomotion dropped handle to {}&quot;</span><span class="p">,</span> <span class="n">inner</span><span class="p">.</span><span class="n">payload</span><span class="p">.</span><span class="n">label</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I do assert that the mental model for what <code>&amp;T</code> <strong>means</strong> becomes &ldquo;quite subtle&rdquo; (at best) if we allow all four variants.</p>

<p>I would like to do better.</p>

<a name="Option.3..Function.boundaries.are.special"></a>
<h3>Option 3. Function boundaries are special</h3>

<p>I put this in here because I figured there was some reason that <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/252">UCG#252</a> was focused on function arguments in particular. That is also why I have the in-line vs out-of-line distiction.</p>

<p>I think the heart of this would be something saying that <code>&amp;'a T</code> where <code>'a</code> is a lifetime parameter to the function (or any lifetime that outlives the function, really) gets treated specially: The compiler gets to assume that in such cases, the <code>T</code> will not be deallocated via an alias.</p>

<p>For the matrix, here&rsquo;s the outcome of this option</p>

<table>
<thead>
<tr>
<th>             </th>
<th>   in-line          </th>
<th> out-of-line        </th>
</tr>
</thead>
<tbody>
<tr>
<td>  <code>&amp;Inner</code>   </td>
<td> version1: okay     </td>
<td> version2: not okay </td>
</tr>
<tr>
<td> <code>&amp;AtomicX</code>  </td>
<td> version3: okay     </td>
<td> version4: not okay </td>
</tr>
</tbody>
</table>


<p>This isn&rsquo;t really satisfying, because it isn&rsquo;t actually coherent.</p>

<p>As discussed in the text below the presentation of version 4, we need to have some way to <em>at least</em> designate version4 as &ldquo;okay&rdquo;, even if its via some opt-in attribute or special casing in the compiler. If we cannot do that, then we might as well go back to option 1 (outlawing them all).</p>

<p>In short: There&rsquo;s a reason <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/252">UCG#252</a> is not trivial to resolve: in practice, we just cannot rule out all of the out-of-line column.</p>

<a name="Option.4..Put.deallocation.on.same.footing.as.mutation"></a>
<h3>Option 4. Put deallocation on same footing as mutation</h3>

<p>This option comes from a <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/252#issuecomment-709035408">UCG#252 comment</a>. As RalfJung put it:</p>

<blockquote><p>this is the key new property that unsafe code would get with your
proposal: if you are allowed to use a pointer for writes to some
memory, you are also allowed to deallocate that memory.</p></blockquote>

<p>This is the proposal I put at the outset of this document.</p>

<p>But what does it imply for our examples?</p>

<a name="interpretation.4A:.focus.on.Atomics.alone"></a>
<h4>interpretation 4A: focus on Atomics alone</h4>

<p>The proposal might be interpreted to mean:</p>

<blockquote><p>if you hold a <code>&amp;A</code>, where <code>A</code> is <code>UnsafeCell&lt;U&gt;</code> or some simple (e.g. <code>#[repr(transparent)]</code>) wrapper
around <code>UnsafeCell&lt;U&gt;</code> that merely adds alignment constraints (like <code>AtomicUsize</code>) then you must assume
that aliasing accesses could deallocate the <code>UnsafeCell&lt;U&gt;</code>.</p></blockquote>

<p>The main goal of this interpretation is to allow people to usually use their existing mental model of <code>&amp;T</code>: if you have a <code>&amp;T</code>, then in almost all cases you know its dereferencable for the entirety of its lexical scope. The only exception is when <code>T</code> itself is, in spirit, itself an <code>UnsafeCell</code>. Such cases are already a warning flag for developers: &ldquo;here be dragons&rdquo;, and we would just be adding a new wrinkle to the dragon&rsquo;s scaly skin.</p>

<p>For the matrix, here&rsquo;s the outcome of this interpetation</p>

<table>
<thead>
<tr>
<th>             </th>
<th>   in-line          </th>
<th> out-of-line        </th>
</tr>
</thead>
<tbody>
<tr>
<td>  <code>&amp;Inner</code>   </td>
<td> version1: not okay </td>
<td> version2: not okay </td>
</tr>
<tr>
<td> <code>&amp;AtomicX</code>  </td>
<td> version3: okay     </td>
<td> version4: okay     </td>
</tr>
</tbody>
</table>


<p>(again, &ldquo;not okay&rdquo; means it is unsound to write deallocation code in this manner.)</p>

<a name="interpretation.4B:.Blast.radius.includes.Buddy.fields"></a>
<h4>interpretation 4B: Blast radius includes Buddy fields</h4>

<p>The proposal might be interpreted to mean:</p>

<blockquote><p>if you hold an <code>&amp;T</code> where <code>T</code> has <em>any</em> <code>UnsafeCell&lt;U&gt;</code> within it,
then you must assume that aliasing accesses could deallocate the
whole <code>T</code>.</p></blockquote>

<p>In other words, sibling fields like <code>.label</code> in our example above would be deemed as potential casualties of a potential deallocation, and thus the Label Code Motion optimization</p>

<p>I think this ends up meaning the same thing as &ldquo;Option 2: Allow them all&rdquo;, except that we could at least say that my naive mental model about <code>&amp;T</code> is applicable when <code>T</code> holds no <code>UnsafeCode&lt;U&gt;</code></p>

<p>For the matrix, here&rsquo;s the outcome of this interpetation</p>

<table>
<thead>
<tr>
<th>             </th>
<th>   in-line      </th>
<th> out-of-line    </th>
</tr>
</thead>
<tbody>
<tr>
<td>  <code>&amp;Inner</code>   </td>
<td> version1: okay </td>
<td> version2: okay </td>
</tr>
<tr>
<td> <code>&amp;AtomicX</code>  </td>
<td> version3: okay </td>
<td> version4: okay </td>
</tr>
</tbody>
</table>


<p>(This wouldn&rsquo;t be the end of the world, and in fact, it might be our only real choice, depending on how much code in the wild we might expect to be broken by interpretation A (&ldquo;focus on Atomics&rdquo;). In particular, Interpretation 4B would classify the <code>Arc</code> code in the standard library as &ldquo;okay&rdquo;.)</p>

<a name="Option.5..Add.marker.to.indicate.that.struct.may.be.deallocated.in.a.volatile.manner."></a>
<h3>Option 5. Add marker to indicate that struct may be deallocated in a volatile manner.</h3>

<p>This is a refinement of option 4.</p>

<p>Essentially: If there is too much fallout from following option 4 (variants 4A or 4B, either applies), then we could narrow the focus of the change by having type definitions <em>declare</em> that they have this behavior.</p>

<p>Under this option, a developer of our ref-counted type would be expected to state that this type is deallocated via a protocol that can fire at times unpredictable to the compiler.</p>

<p>This opt-in could take the form of an attribute on the <code>struct Inner</code> definition. Or perhaps it would be a trait that <code>Inner</code> implements.
Or maybe its a wrapper type, similar to <code>UnsafeCell&lt;T&gt;</code>, that would wrap around the <code>AtomicUsize</code>.</p>

<p>In any case, that would then be used as a marker telling the compiler whether the &ldquo;Label Code Motion&rdquo; optimization applies.</p>

<p>(Another way of seeing this: instead of inferring from the presence of <code>UnsafeCell</code> that such deallocation might happen, we would be adding an alternative marker that developers would have to know about and use correctly if they are implementing a memory-management scheme like this.)</p>

<a name="Conclusion"></a>
<h3>Conclusion</h3>

<p>This is all a bunch of notes I wrote down to prepare for a language team meeting.
And at some point I wanted them to have executable code. (I use a literate programming system, tango, to write blog posts like this.)</p>

<p>And at some point after that, I realized this document was too long for the language team meeting.</p>

<p>So it became a blog post.</p>

<p>It deliberately does not have a conclusion, at this point. I thought I would come to one over the course of writing it, but all I&rsquo;ve determined so far is that I need to come up with a more succinct write-up of the problem.</p>

<a name="Appendix"></a>
<h3>Appendix</h3>

<p>Below is some code to just try driving the above things, to test them out.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">payload</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span> <span class="mi">128</span><span class="p">];</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">source</span> <span class="o">=</span> <span class="s">&quot;Hello World&quot;</span><span class="p">.</span><span class="n">as_bytes</span><span class="p">();</span>
</span><span class='line'>    <span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">payload</span><span class="p">[..</span><span class="n">source</span><span class="p">.</span><span class="n">len</span><span class="p">()]).</span><span class="n">copy_from_slice</span><span class="p">(</span><span class="n">source</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">h1</span> <span class="o">=</span> <span class="n">Handle</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="sc">&#39;h&#39;</span><span class="p">,</span> <span class="n">payload</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">_h2</span> <span class="o">=</span> <span class="n">h1</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span>
</span><span class='line'>    <span class="n">scribble_then_println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;h1 ref_count: {}&quot;</span><span class="p">,</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="p">(</span><span class="o">*</span><span class="n">h1</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">ref_count</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="nb">Ordering</span><span class="o">::</span><span class="n">SeqCst</span><span class="p">)</span> <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<!--

FYI here's how to run the thing on my local box:

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">(</span><span class="n">source</span> <span class="o">~/</span><span class="p">.</span><span class="n">cargo</span><span class="o">/</span><span class="n">env</span>  <span class="o">&amp;&amp;</span> <span class="n">cd</span> <span class="p">..</span> <span class="o">&amp;&amp;</span> <span class="k">for</span> <span class="n">F</span> <span class="k">in</span> <span class="n">version</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">}</span> <span class="p">;</span> <span class="k">do</span> <span class="n">cargo</span> <span class="o">+</span><span class="n">nightly</span> <span class="n">run</span> <span class="o">--</span><span class="n">features</span> <span class="err">$</span><span class="n">F</span>  <span class="p">;</span> <span class="n">done</span> <span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>

-->

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mentoring rust diagnostics issue 81658]]></title>
    <link href="http://blog.pnkfx.org/blog/2021/03/11/mentoring-rust-diagnostics-issue-81658/"/>
    <updated>2021-03-11T14:01:33-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2021/03/11/mentoring-rust-diagnostics-issue-81658</id>
    <content type="html"><![CDATA[<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This was originally a <a href="https://github.com/rust-lang/rust/issues/81658#issuecomment-795714938">github comment</a> that, due to my writing style (and
desire to teach), spun a bit out of control (or at least, didn&rsquo;t match the
overall style we try to follow for comments on <a href="https://github.com/rust-lang/rust/">rust-lang/rust repository</a>).</p>

<p></span></p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
So now, this is a blog post instead, where I get to do fun things like have
better control over formatting and whatnot. (Based on what feedback I get on the
post, maybe I will next work to promote it to a chapter in the <a href="https://rustc-dev-guide.rust-lang.org/">rustc dev guide</a>.)</p>

<p></span></p>

<p><a href="https://github.com/rust-lang/rust/issues/81658">Issue #81658</a>, &ldquo;Invalid `field is never read: ` lint warning&rdquo;, is a
bug filed against rustc.</p>

<p>These are mentorship instructions for how to go about fixing the bug.
They are also an overview of some steps I use to get started looking at a
bug like this.</p>

<!-- more -->


<a name="Context"></a>
<h2>Context</h2>

<p><a href="https://github.com/rust-lang/rust/issues/81658">Issue #81658</a>, &ldquo;Invalid `field is never read: ` lint warning&rdquo;, is a
bug filed against rustc. It was filed at the beginning of February 2021.</p>

<p>The heart of the problem is that a diagnostic lint was firing, saying a
particular field was never read, and mentioning the diagnostic resulted due to a
<code>warn(dead_code)</code> lint setting.
It was quickly prioritized as a medium priority issue (as lints often are).</p>

<p>The issue reporter was quite <a href="https://github.com/rust-lang/rust/issues/81658#issuecomment-778067614">concerned</a> that the issue reached the <code>rustc</code>
beta channel without being addressed, because they felt that the diagnostic text
could be misinterpreted as saying that the field in question <em>is</em> 100% dead
code, which would imply that it could be removed with no effect to the semantics
of the program.</p>

<p>The issue reporter asked for the lint to be narrowed in scope to not fire in
these cases, as they are false positives, and the <code>rustc</code> compiler has a
principle of eschewing lints that signal false positives.</p>

<p>The observable behavior of lints is under the purview of the Rust language
design team. the issue was nominated for discussion at one of the team&rsquo;s weekly
triage meetings.</p>

<p>After some discussion, the conclusion of the language design team was that we
were not going to revise the lint itself to be more restrictive in when it fires.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Of course the discussion was a bit more nuanced than what I&rsquo;ve written here.
There was a bit more discussion about what the lint would do in an ideal world,
in terms of firing only on &ldquo;truly dead&rdquo; code,
but the realities of systems programming (as well as the halting problem) mean
we do not live in that ideal world.
</span>
We saw the example code, and the collective reaction was
&ldquo;the lint is fine here. The right thing for the developer to do in such cases is
to prepend an underscore to their field or variable name&rdquo;.</p>

<p>But when I was reviewing the issue comment thread after the meeting, something
resonated with me: The issue reporter pointed out another principle of <code>rustc</code>:</p>

<blockquote><p>If rustc warns about something, it should mention a clear way how to fix the warning.</p></blockquote>

<p>I certainly agree with that. And, importantly: The end consensus of the language
team (&ldquo;prepend an underscore&rdquo;) is <em>not</em> reflected <strong>anywhere</strong> in the diagnostic text issued
by <code>rustc</code>.</p>

<p>So, I posted a note saying we should fix the latter aspect of the diagnostic.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
It is almost always easier to fine-tune the english text of a diagnostic rather than
revise when the diagnostic fires. (Or, at least, it is less risky to our users,
in terms of what impact a mistake might have in each of the two cases.)
</span>
It will be an easy bug to fix.
Its a good way for new contributors to get involved, and I&rsquo;ll mentor it.</p>

<p>Thus, these are my mentorship instructions.</p>

<a name="Mentorship.Instructions"></a>
<h1>Mentorship Instructions</h1>

<p>Our goal is to improve the diagnostic in this case to inform the user of their
options: If the field is truly unused, they can remove it. If the field is used
in some implicit way, then they can silence the lint itself, or they can prepend
its name with an underscore (which serves as a signal that the field has some
purpose, despite it not being read by expressions visible in the control flow of
the program).</p>

<a name="Test.driven.development"></a>
<h2>Test driven development</h2>

<p>There are a number of example usages of these &ldquo;unread fields&rdquo; given in the
comment thread.</p>

<p>It would be a good idea to start by writing simple test cases based on those
examples. The main ones I see discussed in this thread and thus might deserve
specific focus (both in test cases and in potentially variations in the
diagnostic output) are these two:</p>

<ol>
<li><p>Values whose types implement <code>Drop</code>, and where that drop has some
 side-effect beyond the value itself (e.g. mutexes that unlock on drop).</p></li>
<li><p>Unsafe code accesses, including (as a very important case), fields that end
up being referenced by foreign code that we reach via the foreign function
interface (FFI).</p></li>
</ol>


<a name="Hacking.on.the.diagnostic"></a>
<h2>Hacking on the diagnostic</h2>

<p>Now that you have made tests, you should be able to run the compiler on them and
observe the current (sub-par) diagnostic output, which will say something like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>warning: field is never read: `s`</span></code></pre></td></tr></table></div></figure>


<p>and</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>= note: `#[warn(dead_code)]` on by default</span></code></pre></td></tr></table></div></figure>


<p>There are different strategies for tracking down where to look in the rustc
source for where these diagnostics are emitted.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I do hold a special spot in my own heart for running <code>rustc</code>
under the <a href="https://rr-project.org/"><code>rr</code> reversible debugger</a>, a spot that is probably meme-worthy at
this point&hellip;
</span>
Some bad initial ideas include:</p>

<ol>
<li>fire up <code>rustc</code> under a debugger and step through its behavior, or</li>
<li>make a local build of <code>rustc</code> with debug logging <a href="https://github.com/rust-lang/rust/blob/a4d9624242df6bfe6c0a298867dd2bd527263424/config.toml.example#L406">turned on</a> and then use
<code>RUSTC_LOG=debug</code> to observe <em>all</em> of that logging output.</li>
</ol>


<p>The two options above are both bad ideas because they will take forever to wade
through.</p>

<p>Here&rsquo;s a better idea, though primitive: search the source code for the
diagnostic.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
preferably with a fast tool like <a href="https://blog.burntsushi.net/ripgrep/"><code>rg</code></a>
that has better defaults, like automatically recursing through subdirectories of the source tree
without needing to pass an extra option asking for that behavior.
</span>
Two immediate guesses for
patterns we can derive from the diagnostic are &ldquo;dead_code&rdquo; (the name of the
lint) and the text &ldquo;field is never read:&rdquo;</p>

<p>You&rsquo;ll quickly discover that grepping for the string &ldquo;dead_code&rdquo; yields a lot of
false-positives (because the lint is <code>#![allow]</code>&lsquo;ed heavily in the Rust source
tree). You can filter many of those out with a regexp pattern like:
<code>[^\(]dead_code</code>. But even then, its a lot to sift through.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
At least, I saw
something on the order of 56 matches, and I think we can do better.
</span></p>

<p>We could try to refine the pattern further, but before we try that, lets try the
other pattern that we saw.</p>

<p>The second pattern, &ldquo;field is never read&rdquo;, has far fewer false-positives:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rg "field is never read"
</span><span class='line'>
</span><span class='line'>Grep finished with no matches found at Wed Mar 10 11:34:47</span></code></pre></td></tr></table></div></figure>


<p>The problem now is that we don&rsquo;t have <em>any</em> positives. What happened?</p>

<p>Well, the diagnostic strings are constructed dynamically (so that they can
include information about the source code, like field names). And as part of
that construction, they are often abstracted in other ways, e.g. to treat the
word &ldquo;field&rdquo;/&ldquo;variable&rdquo; as just another parameter.</p>

<p>So, in this scenario, I recommend making the search pattern less specific: drop
the word &ldquo;field&rdquo;:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rg "is never read"
</span><span class='line'>rustc_passes/src/liveness.rs
</span><span class='line'>1451:                                lint.build(&format!("value captured by `{}` is never read", name))
</span><span class='line'>1480:                        format!("value passed to `{}` is never read", name)
</span><span class='line'>1619:                format!("value assigned to `{}` is never read", name)
</span><span class='line'>
</span><span class='line'>rustc_resolve/src/late.rs
</span><span class='line'>2261:                    // Since this res is a label, it is never read.
</span><span class='line'>
</span><span class='line'>Grep finished with matches found at Wed Mar 10 11:38:59</span></code></pre></td></tr></table></div></figure>


<p>More promising, but if you look carefully, none of these strings could actually
yield the diagnostic we&rsquo;re seeking. So our pattern is <em>still</em> too specific.</p>

<p>Searching for &ldquo;is never&rdquo; will work, but it ends up yielding 53 matches (and 53&asymp;56, which I
rejected above as being too many to wade through).</p>

<p>So here&rsquo;s the trick: Include the Rust formatting curly braces in the search string:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rg "\} is never \{"
</span><span class='line'>rustc_passes/src/dead.rs
</span><span class='line'>580:                lint.build(&format!("{} is never {}: `{}`", descr, participle, name)).emit()
</span><span class='line'>
</span><span class='line'>Grep finished with matches found at Wed Mar 10 11:41:54</span></code></pre></td></tr></table></div></figure>


<p>Now we have found what is almost certainly the exact place where we need to edit
the code to improve the diagnostic in question.</p>

<a name="What.kind.of.code.to.write"></a>
<h2>What kind of code to write</h2>

<p>Here is my short-term advice:</p>

<p>It would be good to focus first on a simple patch that is easy to backport to
beta.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
It <a href="https://zulip-archive.rust-lang.org/238009tcompilermeetings/27332weeklymeeting2021031154818.html#229869685">turns out</a>
that we are almost certainly going to revert <a href="https://github.com/rust-lang/rust/pull/81473">PR #81473</a> rather than backport other fixes to beta, but the advice about making the first version here simple still holds.
</span>
I.e. all the bells and whistles about inspecting <code>Drop</code> do not need to be in beta.</p>

<p>A simple general change to the diagnostic text is all I would want (and I would
expect the team to balk at approving a larger beta backport).</p>

<a name="After.the.code.is.written"></a>
<h2>After the code is written</h2>

<p>You need to run your tests. You&rsquo;ll probably discover that even if the tests you
added pass (which is pretty unlikely, unless you are <em>very</em> good at predicting
how the diagnostic you added will actually get emitted), a whole bunch of other
tests are going to fail.</p>

<p>Review them. Most of them are going to be failing because the diagnostic output you added is not
expected by the test.</p>

<p>You could try to update all those tests by hand. But that is not a good use of developer effort.
Instead, use <a href="https://rustc-dev-guide.rust-lang.org/tests/running.html#editing-and-updating-the-reference-files"><code>x.py test --bless</code></a> to automatically generate the new expected output, and then
manually review the output of <code>git diff</code> to double-check that the changes to the expected output
all make sense.</p>

<a name="What.next."></a>
<h2>What next?</h2>

<p>Ping me on Zulip if you want to help with this, and I&rsquo;ll be happy to provide
guidance (either here on github, or directly via text chat).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust Bug Minimization Patterns]]></title>
    <link href="http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/"/>
    <updated>2019-11-18T11:19:46+01:00</updated>
    <id>http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns</id>
    <content type="html"><![CDATA[<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
<em>Update 19 November 2019</em>: fixed miscellaneous typos and a <a href="https://www.reddit.com/r/rust/comments/dy6nk7/rust_bug_minimization_patterns/f804qsj/">bug</a> in the
<a href="#L..ADT-reduction.....in.general">invariance example</a> pointed out by
readers both privately and on <a href="https://www.reddit.com/r/rust/comments/dy6nk7/rust_bug_minimization_patterns/">reddit thread</a>.
I also added a <a href="#The.Rust.specifics">section</a> near the beginning
to draw attention to techniques
that are somewhat Rust-specific and may not be broadly known.
</span></p>

<p>Hey there again!</p>

<p>I have been pretty busy with Rust compiler tasks, so no there has not
been a blog post for a few months. But now, here we are!</p>

<p>While I was working some particularly nasty bugs recently, I put a
lot of effort into <em>bug minimization</em>: the process of taking a large
test case and finding ways to remove code from the test while
preserving the test&rsquo;s ability to expose the same bug.</p>

<p>As I worked, I realized that I was following a somewhat mechanical
process. I was using regular patterns for code transformation. At some
point, I said &ldquo;you know, I&rsquo;m not sure if everyone is aware of these
patterns. I only remember some of them while I am in the middle
of a bug minimization session.&rdquo;</p>

<p>Since the Rust compiler team always wants to help newcomers learn ways
they can contribute to the project, I realized this could be the ideal
subject for a blog post.</p>

<p>And, to try to keep things concrete, I&rsquo;m going to try to drive the
presentation by showing an actual bug being minimized. (Or rather, I&rsquo;m
going to recreate the minimization that I already did. So if it seems
like I am rather conveniently picking transformations that always seem
to work: You&rsquo;re right! I&rsquo;m cheating and not telling you about all the
false paths I went down during my first minimization odyssey on this bug.</p>

<!-- more -->


<a name="The.Rust.specifics"></a>
<h3>The Rust specifics</h3>

<p>Oh, and one other thing: A lot of the ideas here are applicable to
   many languages, and so its possible readers have already heard about them
   or discovered them independently.</p>

<p>However, a few of the techniques
leverage features that are not universal to languages outside of Rust.</p>

<p>Specifically:</p>

<ul>
<li><p><a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a> makes use of Rust&rsquo;s attribute system to
remove items in a lightway fashion.</p></li>
<li><p><a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> makes use of the fact that the Rust allows
the divergent expression <code>loop { }</code> to be assigned any type.</p></li>
<li><p><a href="#L..loopification.....via.pretty-printer">&ldquo;loopification&rdquo; via pretty-printer</a> leverages the compiler&rsquo;s
(unstable) ability to inject <code>loop { }</code> for all function bodies.</p></li>
<li><p><a href="#Bisecting.the.module.tree">Bisecting the module tree</a> makes use of Rust&rsquo;s support for
a mix of inline and out-of-line modules to allow one to quickly
swap code in and out.</p></li>
</ul>


<p>So, without further ado: here is the odyssey of my minimization of
<a href="https://github.com/rust-lang/rust/issues/65774">rust-lang/rust#65774</a></p>

<!-- rust-lang/rust#64872 --> 


<a name="Philosophical.meandering"></a>
<h2>Philosophical meandering</h2>

<a name="What.does..minimal..mean.anyway."></a>
<h3>What does &ldquo;minimal&rdquo; mean anyway?</h3>

<p>The objective of a &ldquo;minimal&rdquo; test case could mean minimize lines of code; or the number of characters. It
is also good to minimize the number of source files: one file,
cut-and-pastable into <a href="https://play.rust-lang.org/">play.rust-lang.org</a>, is especially desirable.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
One could even argue that the number of nodes in the abstract syntax tree
is a better metric to use than text-oriented metrics when minimizing.
</span></p>

<p>Minimizing the source test in this way can yield a good candidate
for a regression test to add to the compiler test suite when
the bug is (hopefully) eventually fixed.</p>

<p>But those syntactic metrics of minimality overlook something:
My own end goal when minimizing the code for a bug is a better
<em>understanding</em> of the bug: a better understanding for myself, and for other developers who are
reading the test case.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I am writing this post from the viewpoint of a <code>rustc</code> developer. So I may have a slightly skewed view on what is useful or minimal.
</span>
And for such understanding, there are other metrics to keep in mind:</p>

<ul>
<li><p>Minimize the amount of time the compiler runs before it hits the bug.</p>

<p>Minimizing the compiler&rsquo;s execution time before failure
serves two purposes:</p>

<ol>
<li><p>It makes every future run of this test faster,
which can accelerate your pace of minimization.</p></li>
<li><p>When the <code>rustc</code> developers themselves examine the behavior
of the compiler on the test, they will be grateful to have
a shorter execution trace of the compiler to analyze.</p></li>
</ol>


<p>(Such time reduction often occurs anyway when you remove lines of code and/or dependencies;
 I just want to point out that it has value in its own right.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
As a concrete example of how reducing imports may help expose a bug&rsquo;s root cause:
some people will have a bug that occurs with
some combination of <code>#[derive(Debug)]</code> and a call to <code>format!</code> or
<code>write</code>, and the test showing the problem may be only a few lines
long. But it hides a lot of complexity behind those uses of
<code>derive</code>, macros, and <code>std::io</code> trait machinery; a longer test that
defines its <em>own</em> trait, a local <code>impl</code> of that trait, and a small
function illustrating the same bug, may make the bug more
immediately apparent to a <code>rustc</code> developer.
</span></p></li>
<li><p>Minimize dependencies: reduce the number of language features in
use and the number of imports your test uses from other crates
(<em>including</em> the <code>std</code> library!).</p>

<p>This can help expose the essential cause of the bug, potentially
making it immediately apparent what is occurring.</p></li>
<li><p>Minimize your jumping around in the source code.</p>

<p>If you can fit all the code needed to recreate the bug
onto your monitor screen at once,
by any means necessary,
that is a serious accomplishment. Less time spent scrolling through
a file or switching editor windows is more time you can spend thinking about
the bug itself.</p></li>
</ul>


<p>To be clear: Often a minimum amount of code needed for
understanding does correlate with a minimum amount of code needed
for <em>reproduction</em>. (This explains why using lines-of-code or the size of the syntax tree as a
metric can be useful when reporting a bug.)</p>

<p>The over-arching goal in minification is to remove all distractions:
to reduce the problematic input (in this case, Rust source code) to
its essence: a minimal amount necessary to <em>understand</em> the problem.</p>

<a name="Why.not.build.it.up.from.scratch."></a>
<h3>Why not build it up from scratch?</h3>

<p>Its worth pointing out that at some point, maybe even at the outset,
you may have a sufficiently rich understanding of the bug that you can
go straight to building up a minimal example from scratch. And that&rsquo;s
<em>great</em> , go for it!</p>

<p>However, this post is dedicated to the problem of what you can do when
you <em>haven&rsquo;t</em> hit that level of understanding. When you&rsquo;re looking at
a set of files that make up over 90,000 lines of code, you want a set
of semi-mechanical techniques to take that test input and strip it
down to its essence.</p>

<p>To be honest, the most effective methodology is going to use a blend
of build-up and tear-down. As you are tearing down the 90,000 lines of
code, there should be a voice in the back of your head asking &ldquo;can we
<em>now</em> try what we&rsquo;ve learned to try to build up a minimal example?&rdquo;</p>

<a name="Assumptions.and.Conventions"></a>
<h2>Assumptions and Conventions</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Some of the techniques may also be applicable to cases where the compiler is
<em>accepting</em> code that it should be rejecting; but I am little wary of advertising these tools
for use in that context, which is why you&rsquo;re reading this in the margin and not the main text.
</span>
The tests I am talking about minimizing in this post are cases where
the compiler itself fails in some way: an ICE, a link failure, or
rejecting code that it should be accepting. Bugs that are witnessed by actually running the
generated code are, for the most part, <em>not</em> covered by the patterns
here. In particular: many of the patterns presented here rely on
making semantic changes to the input: changing values, or replacing
complex expressions with something trivial like <code>loop { }</code>.</p>

<p>I named each transformation, usually
with absurd made-up words like <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a>.
They are all in explicit quotation marks to try to
make it clear that I am speaking nonsense, deliberately.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I had originally planned to structure this post so that
all transformations for a given theme would be present together, so that you&rsquo;d see
all the transformations for that theme at once. But as I wrote, it
became clear over the course of actually <em>doing</em>
a reduction, then we often bounce around between transformations, and
it usually does not end up being nicely grouped with all transformations for one theme colocated
in time.
So rather than using that hierarchical presentation, I am instead just
going to try to <em>mention</em> the grouping by marking each as
transformation being part of a &ldquo;theme&rdquo;.
</span>
Several of the transformations serve similar goals, like &ldquo;delete the
unnecessary&rdquo;. I have attempted to categorize the different tranformations
according
to what purpose they serve in the minimization process. Over the course
of documenting these transformations, I identified the following
<em>themes</em>:</p>

<ul>
<li>Simplify Workflow: Make your own life easier.

<ul>
<li>Enable Incremental Steps</li>
</ul>
</li>
<li>Delete the Unnecessary: Remove items not related to bug!</li>
<li>Identify the Unnecessary: Eliminate accidental necessity.</li>
<li>Trivialize Content: Turn complex expressions to trivial ones.</li>
<li>Eliminate Coupling: Break links between items.</li>
</ul>


<a name="Notes.on.Notation"></a>
<h3>Notes on Notation</h3>

<p>In this post, I follow typical notation by using <code>...</code> as a placeholder for
(possibly relevant) code that will be kept approximately the same (modulo
mechanical updates like alpha-renaming) by a transformation.
However, I also use the non-standard notation of <code>----</code> for irrelevant code
that <em>removed</em> via a transformation. This is meant to draw attention to the
distinct kinds of code, so that you can more easily tell which code is being removed
by a particular transformation.</p>

<p>Sometimes I will show an explicit regexp that I am feeding to a tool
to do the transformation, but usually I will stick to informal patterns
with the aforementioned <code>...</code> and <code>----</code> placeholders.</p>

<p>When a given item or expression can appear within the context of a middle of a sequence
(e.g. consider <code>{ ... THING ... }</code>),
I often use the standard shorthand of just writing <code>{ THING ... }</code> or <code>{ ... THING }</code>,
to simplify the textual presentation and focus attention on the transformation itself.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Record.your.steps"></a>
<h3>Record your steps</h3>

<p>Before you do any reduction, move the test case into its own local <code>git</code> repository
(or whatever versioning tool you prefer: SVN, RCS, etc).
Being able to backtrack through previous reduction steps
is an incredibly important option when doing this kind of
of work.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Continuously.test.the.test."></a>
<h3>Continuously test the test.</h3>

<p>Finally: A crucial part of reduction is to <em>continuously</em> double-check
that the bug still reproduces after every reduction step. I&rsquo;ll show
the command line invocation on occasion, but not every command line
build invocation (the output is usually the same on every run, so it
would just clog up the flow of the presentation here). But even though
I don&rsquo;t show every invocation, you can believe that I was doing the
runs. (And in the cases where I tried to skip doing a run, I usually
regretted it and had to backtrace my steps to the state before an
attempted reduction.)</p>

<p>Make it easy to do your runs. Use your IDE. I use emacs, so I make a
<code>M-x compile</code> invocation that runs the compiler with the right
arguments, and then you can hit <code>g</code> in the <code>*compilation*</code> buffer to
re-run the compile.</p>

<a name="The.test.case"></a>
<h2>The test case</h2>

<p>As I mentioned at the start: The presentation here will be
driven by referencing a <a href="https://github.com/pnkfelix/demo-minimization/tree/f979a3718a9c4350530b9e8c5beb09937799f67a">concrete test case</a>
that I reduced recently:
we have been given a crate graph, and we can observe a bug when we
build as follows:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% <span class="o">(</span> <span class="nb">cd </span>tock/boards/arty-e21/ <span class="o">&amp;&amp;</span> <span class="se">\</span>
</span><span class='line'>    <span class="nv">RUSTFLAGS</span><span class="o">=</span><span class="s2">&quot;-C link-arg=-Tlayout.ld&quot;</span> <span class="se">\</span>
</span><span class='line'>    cargo build --target riscv32imac-unknown-none-elf <span class="o">)</span>
</span><span class='line'>   Compiling tock-registers v0.4.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-register-interface<span class="o">)</span>
</span><span class='line'>   Compiling tock-cells v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-cells<span class="o">)</span>
</span><span class='line'>   Compiling tock_rt0 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-rt0<span class="o">)</span>
</span><span class='line'>   Compiling enum_primitive v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/enum_primitive<span class="o">)</span>
</span><span class='line'>   Compiling kernel v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/kernel<span class="o">)</span>
</span><span class='line'>   Compiling riscv-csr v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/riscv-csr<span class="o">)</span>
</span><span class='line'>   Compiling rv32i v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/arch/rv32i<span class="o">)</span>
</span><span class='line'>   Compiling capsules v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/capsules<span class="o">)</span>
</span><span class='line'>   Compiling sifive v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/chips/sifive<span class="o">)</span>
</span><span class='line'>   Compiling arty_e21 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/chips/arty_e21<span class="o">)</span>
</span><span class='line'>   Compiling components v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/boards/components<span class="o">)</span>
</span><span class='line'>   Compiling arty-e21 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/boards/arty-e21<span class="o">)</span>
</span><span class='line'>error: internal compiler error: src/librustc/traits/codegen/mod.rs:127: Encountered errors <span class="sb">`</span><span class="o">[</span>FulfillmentError<span class="o">(</span>Obligation<span class="o">(</span><span class="nv">predicate</span><span class="o">=</span>Binder<span class="o">(</span>TraitPredicate<span class="o">(</span>&lt;<span class="o">()</span> as core::fmt::Display&gt;<span class="o">))</span>, <span class="nv">depth</span><span class="o">=</span>1<span class="o">)</span>,Unimplemented<span class="o">)]</span><span class="sb">`</span> resolving bounds after <span class="nb">type</span>-checking
</span></code></pre></td></tr></table></div></figure>


<p>In reality the command line was a little more complicated:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% <span class="o">(</span> <span class="nb">cd </span>tock/boards/arty-e21/ <span class="o">&amp;&amp;</span> <span class="se">\</span>
</span><span class='line'>    <span class="nv">RUSTFLAGS</span><span class="o">=</span><span class="s2">&quot;-C link-arg=-Tlayout.ld -C linker=rust-lld -C linker-flavor=ld.lld -C relocation-model=dynamic-no-pic -C link-arg=-zmax-page-size=512&quot;</span> <span class="se">\</span>
</span><span class='line'>    cargo build --target riscv32imac-unknown-none-elf   <span class="o">)</span>
</span><span class='line'>...
</span><span class='line'>error: internal compiler error: src/librustc/traits/codegen/mod.rs:127: Encountered errors <span class="sb">`</span><span class="o">[</span>FulfillmentError<span class="o">(</span>Obligation<span class="o">(</span><span class="nv">predicate</span><span class="o">=</span>Binder<span class="o">(</span>TraitPredicate<span class="o">(</span>&lt;<span class="o">()</span> as core::fmt::Display&gt;<span class="o">))</span>, <span class="nv">depth</span><span class="o">=</span>1<span class="o">)</span>,Unimplemented<span class="o">)]</span><span class="sb">`</span> resolving bounds after <span class="nb">type</span>-checking
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
An eagle-eyed reader might look at that ICE
message and immediately consider grepping the source
code, such as uses of the trait bound <code>core::fmt::Display</code>. A
fine idea, but intuitive jumping to an
answer is <em>not</em> what I&rsquo;m focusing on here.
</span></p>

<p>but for the purposes of the experiments presented in this blog post I
will use the simplified invocation. (The difference only matters once
we hit cases where the bug goes away.)</p>

<p>Remember that 90,000 lines of code number that I mentioned a
few paragraphs ago? It didn&rsquo;t come out of nowhere:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% find tock/ -name *.rs <span class="p">|</span> xargs wc
</span><span class='line'>...
</span><span class='line'>   <span class="m">91958</span>  <span class="m">317229</span> <span class="m">3150451</span> total
</span></code></pre></td></tr></table></div></figure>


<p>So this is an excellent example of an input that we really want to
reduce down to something smaller.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Tactic:.Reduce.the.driving.code.first"></a>
<h2>Tactic: Reduce the driving code first</h2>

<p>We have many input files, and they make up a crate graph with at least
13 crates in it.</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>




<!--
<div id="target_anchor1"></div>
<script>
    var dot_source = 'digraph {\
        rankdir="TB";\
        bgcolor="transparent"; \
        "boards/arty-e21" -> kernel;\
        "boards/arty-e21" -> "chips/arty_e21";\
        "chips/arty_e21" -> "chips/sifive";\
        "chips/arty_e21" -> kernel;\
        "chips/sifive" -> "arch/rv32i";\
        "arch/rv32i" -> kernel;\
        "arch/rv32i" -> "libraries/tock-r0";\
        "arch/rv32i" -> "libraries/tock-register-interface";\
        "arch/rv32i" -> "libraries/riscv-csr";\
        "libraries/riscv-csr" -> "libraries/tock-register-interface";\
        kernel -> "libraries/tock-register-interface";\
        kernel -> "libraries/tock-cells";\
    }';
    var elem = document.getElementById("target_anchor1");
    elem.innerHTML = Viz(dot_source, "svg");
</script>
-->


<p>We know from our command line invocation that it is the build of
<code>boards/arty-e21</code> that is exposing the ICE.
It would be good to remove unnecessary crates from the crate graph
for <code>boards/arty-e21</code>. But to do that most effectively, we need to
first discard as many imports as possible from  <code>boards/arty-e21</code>, and then
work our way backwards through the dependency chain.</p>

<p>So, will start by reducing the <code>boards/arty-e21</code> crate to the minimum
necessary to reproduce the bug.</p>

<p>This single crate is a much easier thing to work with:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% find tock/boards/arty-e21/ -name <span class="s1">&#39;*.rs&#39;</span> <span class="p">|</span> xargs wc
</span><span class='line'>       <span class="m">4</span>       <span class="m">6</span>     <span class="m">124</span> tock/boards/arty-e21//build.rs
</span><span class='line'>      <span class="m">27</span>      <span class="m">68</span>     <span class="m">565</span> tock/boards/arty-e21//src/timer_test.rs
</span><span class='line'>      <span class="m">40</span>     <span class="m">101</span>     <span class="m">959</span> tock/boards/arty-e21//src/io.rs
</span><span class='line'>     <span class="m">279</span>     <span class="m">667</span>    <span class="m">9135</span> tock/boards/arty-e21//src/main.rs
</span><span class='line'>     <span class="m">350</span>     <span class="m">842</span>   <span class="m">10783</span> total
</span></code></pre></td></tr></table></div></figure>


<p>However, we <em>still</em> want to reduce it as much as we can: Every import
we can remove from <code>arty-e21</code> represents swaths of code that we
might be able to remove in the rest of the crate graph.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Technique:..mod-inlining."></a>
<h2>Technique: &ldquo;mod-inlining&rdquo;</h2>

<p>This technique may surprise some: I like to reduce the number of files
involved early in the game, if I can. An easy way to do this is to
replace the out-of-line <code>mod foo;</code> item with its inline counterpart:
<code>mod foo { ... }</code>. Here the out-of-line module file content has been
cut-and-pasted into an inline <code>mod</code> item.</p>

<p>Strictly speaking, moving from <code>mod foo;</code> to <code>mod foo { ... }</code>does not
reduce the input: You still have all the same content that you started
with, the compiler has to do the same amount of work, et cetera.</p>

<p>However, I still prefer to do it, because I find that it helps with
later reduction steps if I can do my transformations on a single file.</p>

<p>There two techniques I use for <a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a>:</p>

<ol>
<li><p>Manually cut-and-paste:
take each instance of <code>mod foo;</code> in the root file, and find that
module&rsquo;s
contents. Then replace the <code>;</code> with <code>{</code> and <code>}</code>, and finally paste
the contents in between the curly brackets you just added. You
don&rsquo;t even have to re-indent<label for='not-python' class='margin-toggle'> &#8853;</label><input type='checkbox' id='not-python' class='margin-toggle'/><span class='marginnote'>Its not like this is Python! </span>
it if you don&rsquo;t want to.</p>

<p>For a small module tree, such as we find in <code>boards/arty-e21</code>,
manually cut-and-pasting is entirely reasonable. But if you have a
large module tree, with many directories and files, it can become
tedious and error-prone.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Warning: this will not only expand the module tree: it will also
expand all the macro invocations, including <code>#[derive]</code> attributes.
This can be a bit overwhelming. (I am continually tempted to add a
new unstable <code>--pretty</code> variant that <em>just</em> expands the module tree
but does <em>not</em> expand the macros otherwise.)
</span></p></li>
<li><p>Alternative: use <code>rustc</code> to expand the module-tree.
You can add <code>--verbose</code> to the <code>cargo build</code> invocation to see the actual <code>rustc</code> command line invocation <code>cargo</code> is using, and then
you can add <code>-Z unstable-options --pretty=expanded</code> to that <code>rustc</code> invocation, piping the output
to a new rust source</p></li>
</ol>


<p>I will show a concrete example of using <code>rustc</code> in this way later in
the blog post. But for now I will just <a href="https://github.com/pnkfelix/demo-minimization/commit/600c31d2643ac0c44e03f345b390eed2a0210e2d">manually cut-and-paste</a> the
contents of <code>boards/arty-e21/src/timer_test.rs</code> and
<code>boards/arty-e21/src/io.rs</code> into <code>main.rs</code></p>

<p>After doing the inline, make sure the bug reproduces.</p>

<p>It is up to you whether you want to delete the out-of-line module files.
Today, Rust does not treat their presence as some sort of conflict with the
inline definition<label for='modfilelint' class='margin-toggle'> &#8853;</label><input type='checkbox' id='modfilelint' class='margin-toggle'/><span class='marginnote'>Checking for unused out-of-line module files might be a nice lint for someone to add to <code>rustc</code> </span>. You will see later in the post cases where keeping them around
on the file-system can be useful. But for the case of
<code>boards/arty-e21</code>, I will go ahead and delete them.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% find tock/boards/arty-e21/ -name *.rs <span class="p">|</span> xargs wc
</span><span class='line'>       <span class="m">4</span>       <span class="m">6</span>     <span class="m">124</span> tock/boards/arty-e21//build.rs
</span><span class='line'>     <span class="m">348</span>     <span class="m">840</span>   <span class="m">10665</span> tock/boards/arty-e21//src/main.rs
</span><span class='line'>     <span class="m">352</span>     <span class="m">846</span>   <span class="m">10789</span> total
</span></code></pre></td></tr></table></div></figure>


<p>As expected, this didn&rsquo;t reduce the line count. But it <em>did</em> make it so
we can work with a single file at the leaf. That simplifies my own
workflow.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Delete the Unnecessary
</span></p>

<a name="Tactic:..Decommentification."></a>
<h2>Tactic: &ldquo;Decommentification&rdquo;</h2>

<p>This may be obvious, but it is a step that I often forget to do at the
outset of test reduction, even though it is easy and pays off
handsomely.</p>

<p>Comments in code are typically there to explain or justify some detail
of the implementation. When diagnosing compiler bugs, the purpose of
the original code is usually not relevant. You are better off
increasing the number of lines of actual code that you can
fit on your screen at once.</p>

<p>In short, the transformation looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="o">^</span>        <span class="c1">//...$</span>
</span></code></pre></td></tr></table></div></figure>


<p>to <code>&lt;empty-string&gt;</code></p>

<p>In this case, I have used <code>^</code> and <code>$</code> as markers for the beginning and end
of lines (just like in regexps).</p>

<p>Or, as an Emacs <code>M-x query-replace-regexp</code>
input: <code>^ *//.*^J*</code><label for='ctrl-j' class='margin-toggle'> &#8853;</label><input type='checkbox' id='ctrl-j' class='margin-toggle'/><span class='marginnote'>The <code>^J</code> there is a carriage-return inserted via <code>M-x quoted-insert</code> (aka <code>C-q</code>) in Emacs. </span>
(and empty string as replacement text).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Why I use <code>M-x query-replace-regexp</code>: it previews the matches, I verify a few by eye, and then hit <code>!</code> to do all the remaining replacements.
</span></p>

<p>Another related transformation: get rid of the other blank lines that
are not preceded by comments. I leave that regexp as an exercise for
the reader.</p>

<p>In the case of <code>boards/arty-e21</code>, this <a href="https://github.com/pnkfelix/demo-minimization/commit/fb6daad45a09e3cd44376e232698af4c76a01df7">got rid of 53 lines</a> of
comments (and blank lines succeeding them):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>     <span class="m">295</span>     <span class="m">575</span>    <span class="m">8551</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Tactic:..Body.Loopification."></a>
<h2>Tactic: &ldquo;Body Loopification&rdquo;</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
see also: <a href="#Technique:..None-defaulting.">&ldquo;none-defaulting&rdquo;</a>
</span>
<a href="#Tactic:..Body.Loopification.">&ldquo;Loopification&rdquo;</a> removes the body of a given function or method item,
replacing it with <code>loop { }</code>.</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(...)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(...)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
You might choose to use alternatives like <code>unimplemented!()</code>. I personally
like <code>loop { }</code> because its something you almost never see in other people&rsquo;s
code, so its easy to search for and be pretty certain that it was introduced as part
of reduction. Also <code>loop { }</code> relies on less machinery from the <code>core</code> library than
<code>unimplemented!</code> does.
</span>
The use of <code>loop { }</code> is deliberate: since <code>loop { }</code> is known by the
compiler to diverge, it can be assigned any type at all. So this
transformation can be performed blindly.</p>

<ul>
<li><p>Note that this does not work for <code>const fn</code>; the compiler currently
rejects <code>const fn foo() { loop { } }</code>  as invaild syntax.</p></li>
<li><p>Also, it generally will not work for <code>impl Trait</code> in return position: the compiler needs a
concrete type to assign to the <code>impl Trait</code>, and <code>loop { }</code> will not suffice for that
unless you ascribed it a non-<code>!</code> type in some manner.</p></li>
</ul>


<p>When it comes to replacing a function body with <code>loop { }</code>, you may be able to get help
from your IDE.
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
 More specifically, I have used Emacs to define a keyboard macro (via <code>C-x (</code>) that:
   1. searches for the next occurrence of <code>fn</code>,
   2. searches forward from there for the first <code>{</code>, which often (but <em>not always</em>) corresponds to the start of the function&rsquo;s body,
   3. runs <code>M-x kill-sexp</code> to delete the <code>{ ---- }</code> and
   4. types in <code>{ loop { } }</code>, replacing the method body.
This is incredibly satisfying to watch in action.
</span>
In my own case, I have often used Emacs <code>M-x kill-sexp</code> to delete the
<code>{ ---- }</code> block in <code>fn foo { ---- }</code></p>

<p>If you want to take a risk, you can ask <code>rustc</code> to do the replacement
of <code>fn</code> bodies with <code>loop { }</code> for you as part of pretty-printing via
the <code>-Z unpretty=everybody_loops</code> flag.
I&rsquo;ll <a href="#L..loopification.....via.pretty-printer">speak more on that later</a>.</p>

<p>Once the body has been removed, you can optionally replace all of the
formal parameters with <code>_</code>:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="n">A</span><span class="p">,</span> <span class="n">b</span><span class="o">:</span> <span class="n">B</span><span class="p">,</span> <span class="p">...)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="n">A</span><span class="p">,</span> <span class="n">_</span><span class="o">:</span> <span class="n">B</span><span class="p">,</span> <span class="p">...)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
These explicit marks can be useful as hints for future reduction steps; see <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a>)
</span>
This is essentially a special case of <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a>; we do not
delete the parameters outright yet (see <a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a> for that), but we
mark them as completely useless by writing them as <code>_: ParamType</code>.</p>

<p>In the case of <code>board/argy-e21/main.rs</code>, there was one <code>const fn</code>, and you cannot <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> that.
For the other <code>fn</code>&rsquo;s, I <a href="https://github.com/pnkfelix/demo-minimization/commit/58118ddd3d806d0d2a8f66f5633a49eeb3615fc4">was able to</a> replace all but
the last <code>fn</code> body with <code>loop { }</code>. (Replacing the last one made the
bug go away.)</p>

<ul>
<li><p>In practice, the ICE diangostic often gives me some hint
about <em>which</em> <code>fn</code> is the problem, and therefore I can blindly
replace the other <code>fn</code> bodies with <code>loop { }</code>.</p></li>
<li><p>But even without such a hint, once can often <em>bisect</em> over the
set of <code>fn</code>&rsquo;s to try to identify a maximal subset that can
have their bodies replaced with <code>loop { }</code>. We will talk
more about <a href="#Reduction.via.Bisection">how to do such bisection later</a>.</p></li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>     <span class="m">262</span>     <span class="m">523</span>    <span class="m">7584</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<p>(Okay, only removing 33 lines of code might not be very impressive. The technique
will pay off more as we move further along.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Tactic:..Expr-elimination."></a>
<h2>Tactic: &ldquo;Expr-elimination&rdquo;</h2>

<p>Even if you were not able to replace a whole <code>fn</code> body with <code>loop { }</code>,
you can usually simplify the <code>fn</code> bodies that remain now.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
themes: Trivialize Content, Identify the Unnecessary
</span></p>

<a name="Technique:.Suffix-bisection"></a>
<h3>Technique: Suffix-bisection</h3>

<p>In this case, I recommend a form of bisection where you first
comment out
the bottom half of the original <code>fn</code>-body, and see if the problem reproduces.</p>

<ul>
<li><p>Why comment out the latter half? Well, if you comment out the top
half, you&rsquo;re almost certainly going to comment out <code>let</code>-bindings
that the bottom half relies on. The top half very rarely relies
on items in the bottom half.</p></li>
<li><p>If the <code>fn</code> in question has a return type, then you can usually use
a <code>loop { }</code> as a tail-expression at the end of the <code>fn</code>-body to
satisfy the return-type; a natural variant of <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a>.</p></li>
</ul>


<p>If it does reproduce without the bottom half,
then you can delete that half, and recursively process
the top half.</p>

<p>If it <em>doesn&rsquo;t</em> reproduce,
then the bug relies on something in the bottom half. If you&rsquo;re
lucky, it <em>only</em> relies on stuff in the latter half, and you can try deleting the top half now.
But even if
you&rsquo;re <em>&ldquo;unlucky&rdquo;</em> and the bottom half relies on stuff in the top half,
you leave the top half in place (at least for now)
and recursively process the bottom half, narrowing the code until you can identify
a single statement whose presence or absence is the line between triggering the ICE or not.</p>

<p>If the <code>fn</code> is too large for fit on one screen, then I
use <code>M-x forward-sexp</code> to identify the start and end of the <code>fn</code>-body.
Then I jump to a line in the middle, and search around for the start
of a statment in the body, and then comment out everything
from that statement forward in <code>/* ... */</code></p>

<p>In the case of <code>boards/arty-e21/src/main.rs</code>, this meant
commenting out from line 191 through 263.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm">    let gpio_pins = static_init!(</span>
</span><span class='line'><span class="cm">    ...</span>
</span><span class='line'>
</span><span class='line'><span class="cm">    board_kernel.kernel_loop(&amp;artye21, chip, None, &amp;main_loop_cap);</span>
</span><span class='line'><span class="cm">*/</span>
</span></code></pre></td></tr></table></div></figure>


<p>And, &ldquo;darn&rdquo;: It didn&rsquo;t work. The bug disappeared.
But: This is okay! We still have learned something: Something in the
latter half is causing the bug. So bisect that latter half (again, favoring
commenting out second halves).</p>

<p>Eventually, by recursively processing the suffix statements,
we <a href="https://github.com/pnkfelix/demo-minimization/commit/cd73c2659e59ac8fa4a1b1ff01fdc3634972f271">identify</a> that the bug does not reproduce with this code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm">    kernel::procs::load_processes(</span>
</span><span class='line'><span class="cm">        board_kernel,</span>
</span><span class='line'><span class="cm">        chip,</span>
</span><span class='line'><span class="cm">        &amp;_sapps as *const u8,</span>
</span><span class='line'><span class="cm">        &amp;mut APP_MEMORY,</span>
</span><span class='line'><span class="cm">        &amp;mut PROCESSES,</span>
</span><span class='line'><span class="cm">        FAULT_RESPONSE,</span>
</span><span class='line'><span class="cm">        &amp;process_mgmt_cap,</span>
</span><span class='line'><span class="cm">    );</span>
</span><span class='line'>
</span><span class='line'><span class="cm">    board_kernel.kernel_loop(&amp;artye21, chip, None, &amp;main_loop_cap);</span>
</span><span class='line'><span class="cm">*/</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>but <em>does</em> reproduce with this code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'>    <span class="n">kernel</span><span class="o">::</span><span class="n">procs</span><span class="o">::</span><span class="n">load_processes</span><span class="p">(</span>
</span><span class='line'>        <span class="n">board_kernel</span><span class="p">,</span>
</span><span class='line'>        <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="n">_sapps</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="n">APP_MEMORY</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="n">PROCESSES</span><span class="p">,</span>
</span><span class='line'>        <span class="n">FAULT_RESPONSE</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="n">process_mgmt_cap</span><span class="p">,</span>
</span><span class='line'>    <span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm">    board_kernel.kernel_loop(&amp;artye21, chip, None, &amp;main_loop_cap);</span>
</span><span class='line'><span class="cm">*/</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, now we have identified a function call to <code>load_processes</code>
that seems to be intimately related to the bug.</p>

<p>Unfortunately, <code>load_processes</code> is an item defined in an external
crate. (We will deal with that eventually.)</p>

<p>Now that we&rsquo;ve identified this function call to <code>load_processes</code> as part of the
cause of the bug, the new goal is to simplify
the earlier part of the function to the bare minimum necessary
to support this function call.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In all of these cases, if an otherwise unused
statement or expression influences the type-inference for the body, you may
need to keep it around, or some variant of it.
</span></p>

<ul>
<li><p>Get rid of all non-binding statements. (We should not need any
side-effecting computations to reproduce the bug.)</p></li>
<li><p>Initialize things to their default values (see <a href="#Tactic:..Defaultification.">&ldquo;Defaultification&rdquo;</a> below).</p></li>
<li><p>Eliminate unused <code>let</code>s (see <a href="#Tactic:..Unusedification.">&ldquo;Unusedification&rdquo;</a> below).</p></li>
</ul>


<p>After applying those steps repeatedly, and further <a href="#Tactic:..Decommentification.">&ldquo;decommentification&rdquo;</a>,
we are left with this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[no_mangle]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">reset_handler</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">chip</span> <span class="o">=</span> <span class="n">static_init</span><span class="o">!</span><span class="p">(</span><span class="n">arty_e21</span><span class="o">::</span><span class="n">chip</span><span class="o">::</span><span class="n">ArtyExx</span><span class="p">,</span> <span class="n">arty_e21</span><span class="o">::</span><span class="n">chip</span><span class="o">::</span><span class="n">ArtyExx</span><span class="o">::</span><span class="n">new</span><span class="p">());</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">process_mgmt_cap</span> <span class="o">=</span> <span class="n">create_capability</span><span class="o">!</span><span class="p">(</span><span class="n">capabilities</span><span class="o">::</span><span class="n">ProcessManagementCapability</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">board_kernel</span> <span class="o">=</span> <span class="n">static_init</span><span class="o">!</span><span class="p">(</span><span class="n">kernel</span><span class="o">::</span><span class="n">Kernel</span><span class="p">,</span> <span class="n">kernel</span><span class="o">::</span><span class="n">Kernel</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">PROCESSES</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">kernel</span><span class="o">::</span><span class="n">procs</span><span class="o">::</span><span class="n">load_processes</span><span class="p">(</span>
</span><span class='line'>        <span class="n">board_kernel</span><span class="p">,</span>
</span><span class='line'>        <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="mi">0</span><span class="k">u8</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="mi">0</span><span class="p">;</span> <span class="mi">8192</span><span class="p">],</span> <span class="c1">// APP_MEMORY,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="n">PROCESSES</span><span class="p">,</span>
</span><span class='line'>        <span class="n">kernel</span><span class="o">::</span><span class="n">procs</span><span class="o">::</span><span class="n">FaultResponse</span><span class="o">::</span><span class="n">Panic</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="n">process_mgmt_cap</span><span class="p">,</span>
</span><span class='line'>    <span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Just checking: the bug still reproduces, and we now have:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>     <span class="m">111</span>     <span class="m">289</span>    <span class="m">2807</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<p>Its not 100% minimized yet, but its about as far as we can go in
changes to <code>fn reset_handler</code> without making changes to crates
upstream in dependency graph.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Delete the Unnecessary
</span></p>

<a name="Tactic:..Unusedification."></a>
<h2>Tactic: &ldquo;Unusedification&rdquo;</h2>

<p>Another way to remove distractions: remove them.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">non_pub_locally_unused_item</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to <code>&lt;empty-string&gt;</code></p>

<p>At this point, after our initial round of <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a>, we should
have a <strong>lot</strong> of unused stuff: variables, struct fields, imports,
etc. And even better, the compiler is probably already telling you about
all of them!</p>

<p>In the specific case of <code>arty-e21</code>, I am currently seeing 25 warnings:
13 unused import warnings, 4 unused variable warnings,
2 static item is never used warnings, 1 constant item is never used warning,
and 5 field is never used warnings.</p>

<p>If you&rsquo;re doing the compilation runs in your IDE, then you should be
able to just jump to each unused item and remove it in some way.</p>

<ul>
<li>In the case of <code>fn</code> parameters, you can replace it with <code>_</code>
as previously discussed.</li>
<li>ADT contents (struct and enum fields) may require more subtlety;
see <a href="#Technique:..ADT-reduction.">&ldquo;ADT-reduction&rdquo;</a> below. For now, you can prefix their names with <code>_</code>.</li>
<li>Warning: Items with attributes like <code>#[no_mangle]</code> or <code>#[link_section]</code> may
also want special treatment: you may be able to remove them without
causing the bug to go away, but once the bug <em>does</em> go away,
their absence may cause a confusing linker error.</li>
</ul>


<p>Make sure to check periodically that the bug still reproduces
(Sometimes supposedly unused things still matter)!</p>

<p><a href="https://github.com/pnkfelix/demo-minimization/commit/72412f6ce7e1ba13fc1f71a7f08ad4eed47f4524">This</a> got <code>boards/arty-e21</code> down to 95 lines:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="o">%</span> <span class="n">wc</span> <span class="n">tock</span><span class="o">/</span><span class="n">boards</span><span class="o">/</span><span class="n">arty</span><span class="o">-</span><span class="n">e21</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">main</span><span class="p">.</span><span class="n">rs</span>
</span><span class='line'>      <span class="mi">95</span>     <span class="mi">254</span>    <span class="mi">2382</span> <span class="n">tock</span><span class="o">/</span><span class="n">boards</span><span class="o">/</span><span class="n">arty</span><span class="o">-</span><span class="n">e21</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">main</span><span class="p">.</span><span class="n">rs</span>
</span></code></pre></td></tr></table></div></figure>


<p>Again, not so impressive yet. But as with optimizations, sometimes
the effect of these techniques only becomes apparent when they
are combined together.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Delete the Unnecessary
</span></p>

<a name="Technique:..Cfgments."></a>
<h2>Technique: &ldquo;Cfgments&rdquo;</h2>

<p>As a note: As a test run, you can easilly preview the effects of
<a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a> and <a href="#Tactic:..Demodulification.">&ldquo;demodulification&rdquo;</a> (discussed below)
transformations without actually deleting code. (After all, you may
quickly discover that you need to put it back.) One classic approach
for this is a comment block:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm">non_pub_locally_unused_item(----) { ---- }</span>
</span><span class='line'><span class="cm">*/</span>
</span></code></pre></td></tr></table></div></figure>


<p>But it not always easy to toggle such comments on and off, since you
need add and remove the <code>/*</code> and matching <code>*/</code> each time you want to
toggle it. Some IDEs help with this, but I still prefer to use more
local changed if I can.</p>

<p>A less used option that is more specific to Rust (and that I use <em>all
the time</em>), is to use a <code>#[cfg]</code> attribute to temporarily remove the code:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">unused_or_little_used_item</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(not_now)]</span>
</span><span class='line'><span class="n">unused_or_little_used_item</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
No, I do not know how to pronounce &ldquo;cfgment&rdquo;; I have only typed it, never uttered it.
<em>Iä! Sheol-Nugganoth!</em>
</span>
I call this <a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a> out code (as opposed to &ldquo;<em>commenting</em> out code&rdquo;).</p>

<p>Whether or not you choose to use comments, <a href="#Technique:..Cfgments.">&ldquo;cfgments&rdquo;</a>, or just delete
code outright is up to you, (though I do recommend you <em>eventually</em>
delete the lines in question, as discussed in <a href="#Tactic:..Decommentification.">&ldquo;decommentification&rdquo;</a>).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Delete the Unnecessary
</span></p>

<a name="Tactic:..Demodulification."></a>
<h2>Tactic: &ldquo;Demodulification&rdquo;</h2>

<p>In addition to <a href="#Tactic:..Unusedification.">&ldquo;unusedifying&rdquo;</a> each identified unused item, you might
try this: You may <em>also</em> be lucky enough to be able to just remove
whole modules from this crate at this point. If the compiler is telling
you that a lot of the items in a given module are unused, maybe you
can get rid of the whole module. Go ahead and try it!</p>

<p>There can be a bit of guesswork involved here. For various reasons the
compiler&rsquo;s lints do not identify some definitions as unused even
though it may seem obvious that they are not used.</p>

<ul>
<li><p>This can be a consequence of the <code>impl</code>s in the source; see <a href="#Tactic:..Deimplificiation.">&ldquo;Deimplification&rdquo;</a> below.</p></li>
<li><p>Also some cases are only identified after doing
<a href="#Tactic:..Depublification.">&ldquo;depublification&rdquo;</a> of the contents of such modules, which is also discussed below.</p></li>
</ul>


<p>In the case of <code>boards/arty-e21</code> I was able to identify <code>mod timer_test</code>
as entirely unsed.</p>

<p>After <a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a> it <a href="https://github.com/pnkfelix/demo-minimization/commit/564145229124075a23eb8967a80ce9d65ac0aa2a">out</a> and further  <a href="#Tactic:..Decommentification.">&ldquo;decommentification&rdquo;</a>, we have this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>      <span class="m">73</span>     <span class="m">191</span>    <span class="m">1967</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<p>(For now we have to keep the <code>mod io { ... }</code>; it defines a panic-handler, and we won&rsquo;t
be able to get rid of that until we do more reduction elsewhere.)</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Delete the Unnecessary
</span></p>

<a name="Technique:..ADT-reduction."></a>
<h2>Technique: &ldquo;ADT-reduction&rdquo;</h2>

<p>What more is there to reduce here? Well, there is a <code>struct ArtyE21</code> all of whose fields are unused:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">ArtyE21</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">_console</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">capsules</span><span class="o">::</span><span class="n">console</span><span class="o">::</span><span class="n">Console</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="n">_gpio</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">capsules</span><span class="o">::</span><span class="n">gpio</span><span class="o">::</span><span class="n">GPIO</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="n">_alarm</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">capsules</span><span class="o">::</span><span class="n">alarm</span><span class="o">::</span><span class="n">AlarmDriver</span><span class="o">&lt;</span>
</span><span class='line'>        <span class="k">&#39;static</span><span class="p">,</span>
</span><span class='line'>        <span class="n">VirtualMuxAlarm</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="p">,</span> <span class="n">rv32i</span><span class="o">::</span><span class="n">machine_timer</span><span class="o">::</span><span class="n">MachineTimer</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="o">&gt;&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="n">_led</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">capsules</span><span class="o">::</span><span class="n">led</span><span class="o">::</span><span class="n">LED</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="n">_button</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">capsules</span><span class="o">::</span><span class="n">button</span><span class="o">::</span><span class="n">Button</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We got lucky here: This <code>struct</code> has no lifetime or type parameters, so we can just
do a trivial replacement, like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span> <span class="p">{</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="https://github.com/pnkfelix/demo-minimization/commit/a41a1c17ea77a4e67ec86b8bda593f9d65e51946">This</a>, combined with <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a> of a now-unused import, leaves us with:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>      <span class="m">63</span>     <span class="m">170</span>    <span class="m">1549</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<a name="L..ADT-reduction.....in.general"></a>
<h3><a href="#Technique:..ADT-reduction.">&ldquo;ADT-reduction&rdquo;</a> in general</h3>

<p>In the general case, if there is a generic parameter on the struct,
you will need it to retain a field (to allow the compiler to compute
the variance of the parameter).</p>

<p>Usually lifetime parameters are (co)variant, in which case this suffices:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">{</span> <span class="n">_inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">()</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
<code>struct S&lt;'a&gt;(Cell&lt;&amp;'a ())</code>
is another option for encoding invariance,
note it imports <code>std::cell::Cell</code>.
</span>
If you need an <em>invariant</em> lifetime parameter to reproduce the bug, then you
can do it this way:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">{</span> <span class="n">_inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="k">mut</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">()</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Likewise, type parameters can usually be encoded like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">_inner</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>If the type parameter has the <code>?Sized</code> (anti)bound, then you can use
this variant:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="n">T</span><span class="o">:</span> <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">_inner</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Often if there is both a lifetime and a type parameter, then I will combine them into one field:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">_inner</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;a</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>but in general that might not reflect the
contents<label for='outlives-inference' class='margin-toggle'> &#8853;</label><input type='checkbox' id='outlives-inference' class='margin-toggle'/><span class='marginnote'>for example, it implicitly requires that <code>T</code> outlive <code>'a</code>, which may not have been the case originaly </span>
of the original struct, and thus may cause the
original bug to be masked. So in general you may have to do:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">S</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">_inner1</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">(),</span> <span class="n">_inner2</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>or some variation thereof.</p>

<p>Having said that, its pretty rare that <code>struct S&lt;'a, T&gt; { _inner: Option&lt;&amp;'a T&gt; }</code> doesn&rsquo;t suffice.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
themes: Delete the Unnecessary, Identify the Unnecessary
</span></p>

<a name="Tactic:..Deimplificiation."></a>
<h2>Tactic: &ldquo;Deimplificiation&rdquo;</h2>

<p>After <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a>, often whole <code>impl</code> blocks can be eliminated.</p>

<p>In the case of <code>arty-e21</code>, we have this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Write</span> <span class="k">for</span> <span class="nb">Writer</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="o">:</span> <span class="o">&amp;</span><span class="kt">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">::</span><span class="n">core</span><span class="o">::</span><span class="n">fmt</span><span class="o">::</span><span class="nb">Result</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which is entirely unused.</p>

<p>So we can <a href="#Technique:..Cfgments.">&ldquo;cfgment&rdquo;</a> it out, and now the compiler identifies two unused
imports (since this <code>impl</code>-block was their only use); more
importantly, it now also identifies that the <code>struct Writer</code> is never
constructed. (Which we already knew since we were able to revise its
fields at will during <a href="#Technique:..ADT-reduction.">&ldquo;ADT-reduction&rdquo;</a>; but the point is that we
couldn&rsquo;t have removed its definition without first removing all of its
associated <code>impl</code> blocks. Thus, <a href="#Tactic:..Deimplificiation.">&ldquo;deimplification&rdquo;</a> is an important
step in our reduction odysssey.</p>

<p><a href="https://github.com/pnkfelix/demo-minimization/commit/c11012b6729b6f4a197a9f6e08a08797a2ecdd90">That</a>, plus more <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a> gets us to 55 lines:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/boards/arty-e21/src/main.rs
</span><span class='line'>      <span class="m">55</span>     <span class="m">146</span>    <span class="m">1396</span> tock/boards/arty-e21/src/main.rs
</span></code></pre></td></tr></table></div></figure>


<a name="Fine-grained...deimplification...."></a>
<h3>Fine-grained <a href="#Tactic:..Deimplificiation.">&ldquo;deimplification&rdquo;</a></h3>

<p>In general you may not be able to remove the whole <code>impl</code> block.
But you can still try to remove individual items from it, like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>   <span class="k">fn</span> <span class="n">method</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span><span class='line'>   <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>   <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<a name="Technique:..split-impls."></a>
<h4>Technique: &ldquo;split-impls&rdquo;</h4>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka Regroup <code>fn</code> items in inherent <code>impl</code>s.
</span>
I sometimes like to employ
As a special technique to remove individual methods from an inherent <code>impl</code>: Rust lets you define
<em>multiple</em> inherent impls for a given type. So rather than deleting code
or using <a href="#Technique:..Cfgments.">&ldquo;cfgments&rdquo;</a> for each item, I will instead take an impl and
break it into two, where one of them is <a href="#Technique:..Cfgments.">&ldquo;cfgmented&rdquo;</a> out:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method1</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method2</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method3</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[cfg(not_now)]</span>
</span><span class='line'><span class="k">impl</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method1</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">impl</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method2</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method3</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here, you can now move items freely between the <a href="#Technique:..Cfgments.">&ldquo;cfgmented&rdquo;</a>-out <code>impl</code>
and the still present <code>impl</code>. It has a similar effect to <a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a>
out the individual items, but in practice it feels a lot more like an
easy bisection process, at least for my fingers.</p>

<ul>
<li>Especially since you can start with the whole <code>impl</code> <a href="#Technique:..Cfgments.">&ldquo;cfgmented&rdquo;</a>-out,
and let the compiler tell you which methods you need to put back (e.g.
due to downstream uses.)</li>
</ul>


<p>You can also sometimes do this <code>impl</code> as a way to make more fine-grained
<code>impl</code>-blocks that have looser constraints, like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">X</span><span class="o">:</span> <span class="n">Bound</span><span class="o">&gt;</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method1</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method2</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method3</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">X</span><span class="o">:</span> <span class="n">Bound</span><span class="o">&gt;</span> <span class="n">Foo</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method1</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="n">Foo</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method2</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">method3</span><span class="p">(...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(where here we assume <code>method2</code> and <code>method3</code> do not require the <code>X: Bound</code>).</p>

<a name="A.pause"></a>
<h1>A pause</h1>

<p>This is about as far as we can usefully get in reducing <code>arty-e21</code> on its own.</p>

<p>To make further progress, we need to start making changes to upstream
dependencies.</p>

<p>Lets look at the situation there.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Identify the Unnecessary
</span></p>

<a name="Tactic:..dep-reduction."></a>
<h2>Tactic: &ldquo;dep-reduction&rdquo;</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka &ldquo;eliminate upstream dependencies&rdquo;
</span>
We have not yet changed anything about the crate graph as a whole.
Technicaly, building <code>arty-e21</code> still builds 12 crates before starting
on <code>arty-e21</code>. (Maybe <code>cargo</code> has some flag to inform you about unused
dependencies?)</p>

<p>In any case, from inspecting <code>arty-e21</code>, we can see that it directly
uses only two dependencies now: <code>kernel</code> and <code>chips/arty_e21</code>.</p>

<p>We can <a href="https://github.com/pnkfelix/demo-minimization/commit/71b8fd41c5f9b8b5802e6e580c53f678a46bb8db">remove other dependencies</a> from the <code>Cargo.toml</code> and see where
it gets us:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='toml'><span class='line'><span class="p">[</span><span class="n">dependencies</span><span class="p">]</span>
</span><span class='line'><span class="n">kernel</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;../../kernel&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="n">arty_e21</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;../../chips/arty_e21&quot;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A build after a <code>cargo clean</code> now shows just nine crates being built before
<code>arty-e21</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>   Compiling tock-registers v0.4.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-register-interface<span class="o">)</span>
</span><span class='line'>   Compiling tock-cells v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-cells<span class="o">)</span>
</span><span class='line'>   Compiling tock_rt0 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/tock-rt0<span class="o">)</span>
</span><span class='line'>   Compiling arty-e21 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/boards/arty-e21<span class="o">)</span>
</span><span class='line'>   Compiling riscv-csr v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/libraries/riscv-csr<span class="o">)</span>
</span><span class='line'>   Compiling kernel v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/kernel<span class="o">)</span>
</span><span class='line'>   Compiling rv32i v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/arch/rv32i<span class="o">)</span>
</span><span class='line'>   Compiling sifive v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/chips/sifive<span class="o">)</span>
</span><span class='line'>   Compiling arty_e21 v0.1.0 <span class="o">(</span>/Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/chips/arty_e21<span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>If we want to make more progress here, we&rsquo;ll need to start working on upstream crates.</p>

<p>Looking at <code>chips/arty_e21/Cargo.toml</code>, we can see it <em>also</em> depends on the <code>kernel</code> crate:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='toml'><span class='line'><span class="p">[</span><span class="n">dependencies</span><span class="p">]</span>
</span><span class='line'><span class="n">sifive</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;../sifive&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="n">rv32i</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;../../arch/rv32i&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="n">kernel</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;../../kernel&quot;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So this gives us a hint where to go next: Simplify <code>chips/arty_e21</code> as much as we can,
before we tackle trying to simplify the (hopefully root) <code>kernel</code> crate.</p>

<p>So lets see what we need from <code>chips/arty_e21</code>. It has a very small <code>lib.rs</code> file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="c-Doc">//! Drivers and chip support for the E21 soft core.</span>
</span><span class='line'>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">feature</span><span class="p">(</span><span class="n">asm</span><span class="p">,</span> <span class="n">concat_idents</span><span class="p">,</span> <span class="n">const_fn</span><span class="p">)]</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">feature</span><span class="p">(</span><span class="n">exclusive_range_pattern</span><span class="p">)]</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">no_std</span><span class="p">]</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_name</span> <span class="o">=</span> <span class="s">&quot;arty_e21&quot;</span><span class="p">]</span>
</span><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">crate_type</span> <span class="o">=</span> <span class="s">&quot;rlib&quot;</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="kn">mod</span> <span class="n">interrupts</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">chip</span><span class="p">;</span>
</span><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">gpio</span><span class="p">;</span>
</span><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">uart</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now I have a choice: do I go ahead and inline these module defintions
like we did with <code>boards/arty-e21</code>? Well, lets figure out if we can
first isolate its exports to a bare minimum before doing that.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Identify the Unnecessary
</span></p>

<a name="Tactic:..Depublification."></a>
<h2>Tactic: &ldquo;Depublification&rdquo;</h2>

<p>As I already mentioned, the compiler is probably already tellling you
about some of these (see <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a>).</p>

<p>But if you want to maximize the set of unused things that the compiler
will identify for you, you might need to help it along the way by
removing <code>pub</code> annotations, like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">foo</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">foo</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="kn">use</span> <span class="n">foo</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">foo</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>or <code>struct</code>, <code>enum</code>, <code>type</code>, <code>trait</code>, <code>fn</code>, etc; basically any <code>pub</code> item.</p>

<p>This can help compiler see that items or imports are in fact not used
outside of the current crate, and thus can be eliminated.</p>

<p>For <code>chips/arty_e21</code>, I was able to successfully do <a href="https://github.com/pnkfelix/demo-minimization/commit/e0a22e4d07731f4f41a81606588ff3a9ad1d019a">this replacement</a>:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">chip</span><span class="p">;</span>
</span><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">gpio</span><span class="p">;</span>
</span><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">uart</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="kn">mod</span> <span class="n">chip</span><span class="p">;</span>
</span><span class='line'><span class="kn">mod</span> <span class="n">gpio</span><span class="p">;</span>
</span><span class='line'><span class="kn">mod</span> <span class="n">uart</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>and everything still built.</p>

<p>After this point, I attempted blind <a href="#Tactic:..Demodulification.">&ldquo;demodulification&rdquo;</a>
each of <code>mod interrupts</code>, <code>mod gpio</code>, and <code>mod uart</code>
(since its so easy to try when they are declared as out-of-line modules). Unfortunately,
<code>pub mod chip;</code> currently depends on all of them being present.</p>

<p>So that&rsquo;s when I went ahead and <a href="https://github.com/pnkfelix/demo-minimization/commit/76a8d5f8289ad4b974e2aebad219e424ac283b59">inlined</a> the module definitions, leaving me with a 371-line <code>lib.rs</code>
for <code>chips/arty_e21</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/chips/arty_e21/src/lib.rs
</span><span class='line'>     <span class="m">371</span>    <span class="m">1354</span>   <span class="m">12137</span> tock/chips/arty_e21/src/lib.rs
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Maybe this argues
for a strategy where one should attempt targetted <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> on
your reachable (<code>pub</code>) modules in the crate, and then do subsequent
<a href="#Tactic:..Demodulification.">&ldquo;demodulification&rdquo;</a> of the out-of-line modules before jumping into
<a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a>. I have not tried that workflow too seriously yet,
though; its not that hard to <a href="#Tactic:..Demodulification.">&ldquo;demodulify&rdquo;</a> a module, since its just a matter
of <a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a> out the <code>mod</code> declaration.
</span>
Then I <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> it; in this case, I was lucky and was able to <a href="https://github.com/pnkfelix/demo-minimization/commit/9381c62b9ade2d82709a86ff57ef64c7acb312d7">loopify <em>everything</em></a>
in <code>chips/arty_e21</code>, and the bug still reproduces.</p>

<p>After <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a>, I was able to successfully <a href="#Tactic:..Demodulification.">&ldquo;demodulify&rdquo;</a> <em>all</em>
of <a href="https://github.com/pnkfelix/demo-minimization/commit/1187a5bd7dbf6e7e2734ccb7787592d2778aa1f1"><code>mod interrupts</code>, <code>mod gpio</code>, and <code>mod uart</code></a>.</p>

<p>Finally, I did some <a href="#Tactic:..Deimplificiation.">&ldquo;deimplification&rdquo;</a>, and managed to remove everything
except for a <code>impl kernel::Chip for ArtyExx { ... }</code> and
one inherent method on <code>struct ArtyExx</code>.</p>

<p>Those steps, plus <a href="#Tactic:..Decommentification.">&ldquo;decommentification&rdquo;</a>, removed about 320 lines.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/chips/arty_e21/src/lib.rs
</span><span class='line'>      <span class="m">52</span>     <span class="m">163</span>    <span class="m">1180</span> tock/chips/arty_e21/src/lib.rs
</span></code></pre></td></tr></table></div></figure>


<p>Perhaps most importantly, it got the source code to the point where
it fits on a screen.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
themes: Enable Incremental Steps, Identify the Unnecessary
</span></p>

<a name="Tactic:..simpl-impl."></a>
<h3>Tactic: &ldquo;simpl-impl&rdquo;</h3>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka use trait defaults
</span>
I did just mention that I had to keep an <code>impl kernel::Chip for ArtyExx { ... }</code>.</p>

<p>In general, the <code>impl</code> blocks we are trying to eliminate may be trait
impls rather than inherent ones. In those cases,
we cannot just remove methods from the <code>impl</code>s willy-nilly, as that
would cause the compiler to reject the trait implementation.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Did you see this coming?
</span>
So, you have to keep that <code>impl</code> entirely intact&hellip;
unless you do some work up front &hellip;</p>

<p>Here&rsquo;s the trick around that.
First add a trait default implementation:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">trait</span> <span class="n">Tr</span> <span class="p">{</span> <span class="p">...</span> <span class="k">fn</span> <span class="n">m</span><span class="p">();</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">trait</span> <span class="n">Tr</span> <span class="p">{</span> <span class="p">...</span> <span class="k">fn</span> <span class="n">m</span><span class="p">()</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This enables the subsequent transformation:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Tr</span> <span class="k">for</span> <span class="n">C</span> <span class="p">{</span> <span class="p">...</span> <span class="k">fn</span> <span class="n">m</span><span class="p">()</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">Tr</span> <span class="k">for</span> <span class="n">C</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Thats right, you can turn a non-default trait method into a <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a>
default trait method, and that enables you to freely remove instances of that
method from all of that trait&rsquo;s <code>impl</code>s.
You can do this transformation piecewise, or for
the whole trait definition, as you like.</p>

<p>And (I think) you can do it
pretty much as freely as you like: you should not need to worry about
changing a trait method to a <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> default causing breakage
elsewhere when compiling the crate graph (unless there is some
potential interaction with specialization that I have not considered).</p>

<p>If you apply the transformation repeatedly, it can often result in</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">trait</span> <span class="n">Tr</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span> <span class="c1">// all methods loopified</span>
</span><span class='line'><span class="k">impl</span> <span class="n">Tr</span> <span class="k">for</span> <span class="n">C</span> <span class="p">{</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which is simply awesome.</p>

<p>In our specific case, the trait in question is upstream: <code>impl kernel::Chip for ArtyExx { ... }</code></p>

<p>So we are going to make an
exception to our earler rule about trying to work at the leaves first: Here, we are
justified in jumping upstream, to <code>kernel/src/platform/mod.rs</code>,
and changing the definition of <code>kernel::Chip</code>, doing <code>M-x query-replace</code> of <code>;</code> with <code>{ loop { } }</code> to easily jump through the <code>fn</code>-items and add
a <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> body to each one.</p>

<p>(In my case, I&rsquo;m going to decommentify the relevant file first too.)</p>

<p>After adding <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> default methods <a href="https://github.com/pnkfelix/demo-minimization/commit/c62a7b05755321ec7e6876d34d8aae7fb90d68df">to the traits in <code>kernel::platform</code></a>, we can return
to <code>chips/arty_e21</code> and <a href="https://github.com/pnkfelix/demo-minimization/commit/02d13aef0478443858d4a7bb13238858f183b4d7">further simplify</a> the <code>impl</code> there to this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">kernel</span><span class="o">::</span><span class="n">Chip</span> <span class="k">for</span> <span class="n">ArtyExx</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">MPU</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">UserspaceKernelBoundary</span> <span class="o">=</span> <span class="n">rv32i</span><span class="o">::</span><span class="n">syscall</span><span class="o">::</span><span class="n">SysCall</span><span class="p">;</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">SysTick</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we need to apply a bit of artistry.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Tactic:..Type-trivialization."></a>
<h2>Tactic: &ldquo;Type-trivialization&rdquo;</h2>

<p>This associated type in <code>impl kernel::Chip for ArtyExx</code> is forcing dependency on <code>rv32i</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">type</span> <span class="n">UserspaceKernelBoundary</span> <span class="o">=</span> <span class="n">rv32i</span><span class="o">::</span><span class="n">syscall</span><span class="o">::</span><span class="n">SysCall</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>But we have removed all the methods! Chances are actually quite good that
there is no longer anyone that relies on that type defintion.
(Its not a <em>certainty</em>, of course; clients of the trait might be extracting the type directly,
and the associated may have trait bounds that will force us to use a non-trivial type there.)</p>

<p>But lets try it and see:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span> <span class="n">kernel</span><span class="o">::</span><span class="n">Chip</span> <span class="k">for</span> <span class="n">ArtyExx</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">MPU</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">UserspaceKernelBoundary</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">SysTick</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>yields:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">error</span><span class="p">[</span><span class="n">E0277</span><span class="p">]</span><span class="o">:</span> <span class="n">the</span> <span class="k">trait</span> <span class="n">bound</span> <span class="err">`</span><span class="p">()</span><span class="o">:</span> <span class="n">kernel</span><span class="o">::</span><span class="n">syscall</span><span class="o">::</span><span class="n">UserspaceKernelBoundary</span><span class="err">`</span> <span class="n">is</span> <span class="n">not</span> <span class="n">satisfied</span>
</span><span class='line'>  <span class="o">--&gt;</span> <span class="o">/</span><span class="n">Users</span><span class="o">/</span><span class="n">felixklock</span><span class="o">/</span><span class="n">Dev</span><span class="o">/</span><span class="n">Mozilla</span><span class="o">/</span><span class="n">issue65774</span><span class="o">/</span><span class="n">demo</span><span class="o">-</span><span class="n">minimization</span><span class="o">/</span><span class="n">tock</span><span class="o">/</span><span class="n">chips</span><span class="o">/</span><span class="n">arty_e21</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">lib</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">22</span><span class="o">:</span><span class="mi">6</span>
</span><span class='line'>   <span class="o">|</span>
</span><span class='line'><span class="mi">22</span> <span class="o">|</span> <span class="k">impl</span> <span class="n">kernel</span><span class="o">::</span><span class="n">Chip</span> <span class="k">for</span> <span class="n">ArtyExx</span> <span class="p">{</span>
</span><span class='line'>   <span class="o">|</span>      <span class="o">^^^^^^^^^^^^</span> <span class="n">the</span> <span class="k">trait</span> <span class="err">`</span><span class="n">kernel</span><span class="o">::</span><span class="n">syscall</span><span class="o">::</span><span class="n">UserspaceKernelBoundary</span><span class="err">`</span> <span class="n">is</span> <span class="n">not</span> <span class="n">implemented</span> <span class="k">for</span> <span class="err">`</span><span class="p">()</span><span class="err">`</span>
</span><span class='line'>
</span><span class='line'><span class="n">error</span><span class="o">:</span> <span class="n">aborting</span> <span class="n">due</span> <span class="n">to</span> <span class="n">previous</span> <span class="n">error</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, what to do about this?</p>

<p>Honestly, I figure this is another case where we are justified in going upstream and removing
the bound in question, just to see what happens:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gh">diff --git a/tock/kernel/src/platform/mod.rs b/tock/kernel/src/platform/mod.rs</span>
</span><span class='line'><span class="gh">index 9544899..dd107dd 100644</span>
</span><span class='line'><span class="gd">--- a/tock/kernel/src/platform/mod.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/platform/mod.rs</span>
</span><span class='line'><span class="gu">@@ -13,7 +13,7 @@ pub trait Platform {</span>
</span><span class='line'> pub trait Chip {
</span><span class='line'>     type MPU: mpu::MPU;
</span><span class='line'>
</span><span class='line'><span class="gd">-    type UserspaceKernelBoundary: syscall::UserspaceKernelBoundary;</span>
</span><span class='line'><span class="gi">+    type UserspaceKernelBoundary;</span>
</span><span class='line'>
</span><span class='line'>     type SysTick: systick::SysTick;
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>And the answer is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'>error[E0277]: the trait bound `&lt;C as platform::Chip&gt;::UserspaceKernelBoundary: syscall::UserspaceKernelBoundary` is not satisfied
</span><span class='line'>   --&gt; /Users/felixklock/Dev/Mozilla/issue65774/demo-minimization/tock/kernel/src/process.rs:468:5
</span><span class='line'>    |
</span><span class='line'>468 | /     stored_state:
</span><span class='line'>469 | |         Cell&lt;&lt;&lt;C as Chip&gt;::UserspaceKernelBoundary as UserspaceKernelBoundary&gt;::StoredState&gt;,
</span><span class='line'>    | |____________________________________________________________________________________________^ the trait `syscall::UserspaceKernelBoundary` is not implemented for `&lt;C as platform::Chip&gt;::UserspaceKernelBoundary`
</span><span class='line'>    |
</span><span class='line'>    = help: consider adding a `where &lt;C as platform::Chip&gt;::UserspaceKernelBoundary: syscall::UserspaceKernelBoundary` bound
</span><span class='line'>
</span><span class='line'>error: aborting due to previous error
</span></code></pre></td></tr></table></div></figure>


<p>Darn.
(We could take the compilers advice and add the aforementioned <code>where</code> clause, but that stands a good chance of just shifting the blame around without actually helping us make progress on reduction itself.)</p>

<p>You might think: &ldquo;Lets try removing that field from the <code>struct</code>&rdquo;; but
note that the <code>struct Process</code> lives in the <code>kernel</code> crate, and that
code has not yet been <a href="#Tactic:..Body.Loopification.">&ldquo;loopified.&rdquo;</a> So there&rsquo;s a good chance that
there&rsquo;s existing code that relies on that field being there, and we
have to get rid of that code first.</p>

<p>Well, we did a good job getting <code>chips/arty_e21</code> as small as we did.
Let us take this as a sign that we should keep moving up, to now focus
on reducing the <code>kernel</code> crate.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Technique:...mod-inlining.....and...loopification.....via.pretty-printer"></a>
<h2>Technique: <a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a> and <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> via pretty-printer</h2>

<p>I want to simplify the kernel crate.</p>

<p>However, its module hierarchy is a bit larger than the other two crates we&rsquo;ve looked at so far:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% find tock/kernel -name <span class="s1">&#39;*.rs&#39;</span>
</span><span class='line'>tock/kernel/src/tbfheader.rs
</span><span class='line'>tock/kernel/src/ipc.rs
</span><span class='line'>tock/kernel/src/memop.rs
</span><span class='line'>tock/kernel/src/lib.rs
</span><span class='line'>tock/kernel/src/platform/mod.rs
</span><span class='line'>tock/kernel/src/platform/systick.rs
</span><span class='line'>tock/kernel/src/platform/mpu.rs
</span><span class='line'>tock/kernel/src/callback.rs
</span><span class='line'>tock/kernel/src/common/static_ref.rs
</span><span class='line'>tock/kernel/src/common/list.rs
</span><span class='line'>tock/kernel/src/common/peripherals.rs
</span><span class='line'>tock/kernel/src/common/queue.rs
</span><span class='line'>tock/kernel/src/common/ring_buffer.rs
</span><span class='line'>tock/kernel/src/common/dynamic_deferred_call.rs
</span><span class='line'>tock/kernel/src/common/mod.rs
</span><span class='line'>tock/kernel/src/common/math.rs
</span><span class='line'>tock/kernel/src/common/deferred_call.rs
</span><span class='line'>tock/kernel/src/common/utils.rs
</span><span class='line'>tock/kernel/src/hil/symmetric_encryption.rs
</span><span class='line'>tock/kernel/src/hil/dac.rs
</span><span class='line'>tock/kernel/src/hil/rng.rs
</span><span class='line'>tock/kernel/src/hil/i2c.rs
</span><span class='line'>tock/kernel/src/hil/pwm.rs
</span><span class='line'>tock/kernel/src/hil/sensors.rs
</span><span class='line'>tock/kernel/src/hil/watchdog.rs
</span><span class='line'>tock/kernel/src/hil/led.rs
</span><span class='line'>tock/kernel/src/hil/time.rs
</span><span class='line'>tock/kernel/src/hil/crc.rs
</span><span class='line'>tock/kernel/src/hil/ninedof.rs
</span><span class='line'>tock/kernel/src/hil/entropy.rs
</span><span class='line'>tock/kernel/src/hil/spi.rs
</span><span class='line'>tock/kernel/src/hil/nonvolatile_storage.rs
</span><span class='line'>tock/kernel/src/hil/mod.rs
</span><span class='line'>tock/kernel/src/hil/usb.rs
</span><span class='line'>tock/kernel/src/hil/adc.rs
</span><span class='line'>tock/kernel/src/hil/gpio_async.rs
</span><span class='line'>tock/kernel/src/hil/analog_comparator.rs
</span><span class='line'>tock/kernel/src/hil/gpio.rs
</span><span class='line'>tock/kernel/src/hil/radio.rs
</span><span class='line'>tock/kernel/src/hil/eic.rs
</span><span class='line'>tock/kernel/src/hil/flash.rs
</span><span class='line'>tock/kernel/src/hil/uart.rs
</span><span class='line'>tock/kernel/src/hil/ble_advertising.rs
</span><span class='line'>tock/kernel/src/driver.rs
</span><span class='line'>tock/kernel/src/component.rs
</span><span class='line'>tock/kernel/src/sched.rs
</span><span class='line'>tock/kernel/src/introspection.rs
</span><span class='line'>tock/kernel/src/debug.rs
</span><span class='line'>tock/kernel/src/process.rs
</span><span class='line'>tock/kernel/src/syscall.rs
</span><span class='line'>tock/kernel/src/returncode.rs
</span><span class='line'>tock/kernel/src/grant.rs
</span><span class='line'>tock/kernel/src/capabilities.rs
</span><span class='line'>tock/kernel/src/mem.rs
</span></code></pre></td></tr></table></div></figure>


<p>I don&rsquo;t want to manually-inline all those modules into <code>kernel</code>.</p>

<p>I&rsquo;m also not too eager to manually <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> it (though that would be
easier if the <a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a> were done).</p>

<p>Luckily, we can leverage the compiler here.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="L..mod-inlining.....via.pretty-printer"></a>
<h3><a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a> via pretty-printer</h3>

<p>As mentioned earlier, we can add <code>-Z unstable-options --pretty=expanded</code> to the relevant <code>rustc</code> invocation
(in ths case, the one compiling <code>kernel/src/lib.rs</code>)
to get the content of the crate as one module tree.</p>

<ul>
<li>(Unfortunately for our immediate purposes, the macros in it are also
 expanded. But since macros could expand into <code>mod</code>-declarations, this
 is tough to avoid in the general case for solving this problem.)</li>
</ul>


<p>Pipe that output to a file, copy that file to
<code>tock/kernel/src/lib.rs</code>, and you&rsquo;re don- &hellip; well, no; you&rsquo;re not done yet.</p>

<p>If you try to compile that as is, you get a slew of errors. Because some of the macros that
expanded came from Rust&rsquo;s <code>core</code> library, and make use of features that are not available
in stable Rust. So you have to add feature-gates to enable each one. Luckily, the nightly compiler
tells us which gates to add, so I was able to get away with adding this line to the top
of the generated file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="err">#</span><span class="o">!</span><span class="p">[</span><span class="n">feature</span><span class="p">(</span><span class="n">derive_clone_copy</span><span class="p">,</span> <span class="n">compiler_builtins_lib</span><span class="p">,</span> <span class="n">fmt_internals</span><span class="p">,</span> <span class="n">core_panic</span><span class="p">,</span> <span class="n">derive_eq</span><span class="p">)]</span>
</span></code></pre></td></tr></table></div></figure>


<p><em>Then</em> the compilation of this expanded <code>kernel</code> <a href="https://github.com/pnkfelix/demo-minimization/commit/00bb383f27ced7463263868dd36857c6e47ffbc6">worked</a>, and the downstream problem continued to reproduce.
Success!</p>

<p>At least, success if your definition of success is this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>% wc tock/kernel/src/lib.rs
</span><span class='line'>   <span class="m">10238</span>   <span class="m">40254</span>  <span class="m">540987</span> tock/kernel/src/lib.rs
</span></code></pre></td></tr></table></div></figure>


<p>Yikes, 10K lines.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="L..loopification.....via.pretty-printer"></a>
<h3><a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> via pretty-printer</h3>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka <code>-Z everybody_loops</code>
</span>
Well, that&rsquo;s okay: There are some steps we haven&rsquo;t taken yet. Specifically, we haven&rsquo;t done <a href="#Tactic:..Body.Loopification.">&ldquo;loopification.&rdquo;</a></p>

<p>Now, its not so much fun to <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> a file like this by hand. The keyboard macro I described above
isn&rsquo;t <em>tha</em> robust; it can end up really messing up the code if you apply it blindly.</p>

<p>But luckily, we have another option:</p>

<p><code>rustc -Z unpretty=everybody_loops</code> is your friend.</p>

<p>Basically, take the command line we used up above for macro-expanding
pretty-printing, but replace the <code>--pretty=expanded</code> with
<code>-Zunpretty=everybody_loops</code>.</p>

<p>As before, pipe the output to a temporary file, and then copy that
over to <code>kernel/src/lib.rs</code>.</p>

<p>And then we build &hellip; and &hellip; oh. The bug didn&rsquo;t replicate.</p>

<ul>
<li>This is okay. It is <em>not</em> a disaster.</li>
</ul>


<p>It in fact motivates another technique: bisecting <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a>.</p>

<a name="Bisecting.the.module.tree"></a>
<h3>Bisecting the module tree</h3>

<p>Warning: this technique may seem&hellip; strange. But I love it so.</p>

<p>The three steps are as follows:</p>

<ol>
<li><p>Unify modules into a single source file (which we did up above, via the pretty-printer).
But in particular, <em>leave</em> leave the original source files for the mod tree in
place. (You&rsquo;ll see why in a moment.)</p></li>
<li><p>Replace all function bodies with
<code>loop { }</code><label for='congrats-same-failure' class='margin-toggle'> &#8853;</label><input type='checkbox' id='congrats-same-failure' class='margin-toggle'/><span class='marginnote'>If after doing this, you still get the same failure again, then congratulations: You have a single file (with a potentially huge module tree) and all of its function bodies are trivial <code>loop { }</code>. But of course, in our case of <code>kernel</code>, we know that we are not in this scenario. </span>
(which we just did, again via the pretty-printer).</p></li>
<li><p>Finally, swap modules in and out via <a href="#Technique:..Cfgments.">&ldquo;cfgmenting&rdquo;</a>.</p></li>
</ol>


<p>Remember <a href="#Technique:..mod-inlining.">up above</a> when I suggested leaving the source files in place?
This is where that comes into play.</p>

<p>A relatively tiny (and easily mechanized) change to the source
code readily reverts individual modules back to their prior form:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">child_mod_1</span> <span class="p">{</span>
</span><span class='line'>    <span class="kn">use</span> <span class="n">import</span><span class="o">::</span><span class="n">stuff</span><span class="p">;</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">some_function</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="kn">mod</span> <span class="n">even_more_inner</span> <span class="p">{</span>
</span><span class='line'>       <span class="p">...</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">child_mod_1</span><span class="p">;</span>
</span><span class='line'><span class="cp">#[cfg(commented_out_for_bisection)]</span>
</span><span class='line'><span class="kn">mod</span> <span class="n">child_mod_1</span> <span class="p">{</span>
</span><span class='line'>    <span class="kn">use</span> <span class="n">import</span><span class="o">::</span><span class="n">stuff</span><span class="p">;</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">some_function</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="kn">mod</span> <span class="n">even_more_inner</span> <span class="p">{</span>
</span><span class='line'>       <span class="p">...</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This effectively puts back in the original code for <code>child_mod_1</code>.</p>

<p>You can search through your single <code>lib.rs</code> (or <code>main.rs</code>) file that
holds the whole module tree (where function bodies are replaced with
<code>loop { }</code>), and then choose a subset of these modules and apply the
above transformation to point them at their original source file.</p>

<p>You can do this for, e.g., the first half the modules, and then re-run
the compiler to see if the failure re-arises. If so, huzzah!</p>

<p>I successfully used this methodology to identify <em>which</em> <code>mod</code> in <code>kernel</code>
we <a href="https://github.com/pnkfelix/demo-minimization/commit/b9c47edced44c33c5362137040acbb814ddd70b5">needed to keep</a> in non-loopified form
in order to reproduce the bug: <code>mod process;</code>.</p>

<p>And that gets us down to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>wc tock/kernel/src/lib.rs
</span><span class='line'>    <span class="m">3253</span>   <span class="m">11085</span>  <span class="m">112858</span> tock/kernel/src/lib.rs
</span></code></pre></td></tr></table></div></figure>


<p>Yeah, still 3K lines. But that&rsquo;s a lot better than 10K, and there&rsquo;s
plenty more stuff to remove.</p>

<p>First, lets see if we can further narrow down which methods in <code>mod
process</code> are the ones that we need for replicating the bug. For this,
we can do bisection over the <code>fn</code> items within the (still
out-of-line) <code>mod process</code>.</p>

<a name="Reduction.via.Bisection"></a>
<h2>Reduction via Bisection</h2>

<p>Sometimes you cannot simply remove all (or all but one) of the method
bodies. For one reason or another (e.g. <code>impl Trait</code> in return position)
you need to preserve the bodies of one or more methods that are not
directly relevant to the bug at hand.</p>

<p>In this scenario, it can stil be useful to use the techniques above to
eliminate irrelevant details in the <em>other</em> methods. But what is the
best way to identify which methods are relevant and which aren&rsquo;t?
Well, that&rsquo;s a fine segue to our original topic.</p>

<p>(&hellip; a significant amount of time has passed.)</p>

<p>Okay: after spending a lot of time doing pseudo-bisection, I managed
to <a href="https://github.com/pnkfelix/demo-minimization/commit/62ebace8bfb317e4419d7939e66b9d99c4edcc28">isolate <em>three</em> methods</a> in process.rs that are necessary to
reproduce the issue.</p>

<p>Part of my own process here (not <code>process</code>, ha ha) was to switch mindset away from trying to
bisect to find the &ldquo;one fn body&rdquo; that causes the faiure. Instead, I
had to focus on identifying a minimal subset of bodies that are
necessary to cause it to <em>arise</em>.</p>

<p>That is, starting with N <code>fn</code> items, I&rsquo;d <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> N/2 of them, and if
the bug went away on that half, I&rsquo;d put back in the previous bodies,
cut that set in in half, and repeat until the bug came back. This
tended to narrow things down to one <code>fn</code> item that, when <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a>,
made the bug go away.</p>

<p>Then I&rsquo;d mark that one <code>fn</code> as strictly necessary, and repeat the
process on the N-1 <code>fn</code>-items that still remained.</p>

<p>To be clear: this switch in mindset changes so-called &ldquo;bisection&rdquo; from
a O(log&nbsp;n) process to an O(n&nbsp;log&nbsp;n) one: because you are going to do a
separate O(log&nbsp;n) bisection step on O(n) <code>fn</code>-items. But on the plus
side, its still a pretty mindless process (and probably could be
mechanically automated).</p>

<p>Eventually, this led me to identify the three functions in <code>process.rs</code>
whose non-<a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> definitions are needed to witness the bug:</p>

<ul>
<li><code>load_processes</code></li>
<li><code>&lt;Process as ProcessType&gt;::process_detail_fmt</code>, and</li>
<li><code>Process::create</code>.</li>
</ul>


<p>With that done, I redid the <a href="#Technique:..mod-inlining.">&ldquo;mod-inlining&rdquo;</a> of <code>mod process</code> into <code>kernel</code>.</p>

<a name="Popping.the.stack"></a>
<h1>Popping the stack</h1>

<p>Now, as a reminder: the reason we dived into <code>kernel</code> was to see if we could
remove the <code>stored_state</code> field from <code>struct Process</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">stored_state</span><span class="o">:</span>
</span><span class='line'>    <span class="n">Cell</span><span class="o">&lt;&lt;&lt;</span><span class="n">C</span> <span class="k">as</span> <span class="n">Chip</span><span class="o">&gt;::</span><span class="n">UserspaceKernelBoundary</span> <span class="k">as</span> <span class="n">UserspaceKernelBoundary</span><span class="o">&gt;::</span><span class="n">StoredState</span><span class="o">&gt;</span><span class="p">,</span>
</span></code></pre></td></tr></table></div></figure>


<p>The answer is unfortuately still no: two of the three methods we kept from <code>mod process</code>
refer to that field.</p>

<p>But we can do some <a href="https://github.com/pnkfelix/demo-minimization/commit/84e6e3d9ecf746e16480d827a5eadacb55246720">directed editing</a> to see if the bug repreoduces after <em>removing</em> those references:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -3067,12 +3067,6 @@ impl&lt;C: Chip&gt; ProcessType for Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>             flash_start
</span><span class='line'>         ));
</span><span class='line'>
</span><span class='line'><span class="gd">-        self.chip.userspace_kernel_boundary().process_detail_fmt(</span>
</span><span class='line'><span class="gd">-            self.sp(),</span>
</span><span class='line'><span class="gd">-            &amp;self.stored_state.get(),</span>
</span><span class='line'><span class="gd">-            writer,</span>
</span><span class='line'><span class="gd">-        );</span>
</span><span class='line'><span class="gd">-</span>
</span><span class='line'>         self.mpu_config.map(|config| {
</span><span class='line'>             let _ = writer.write_fmt(format_args!(&quot;{}&quot;, config));
</span><span class='line'>         });
</span><span class='line'><span class="gu">@@ -3205,7 +3199,7 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>
</span><span class='line'>             process.flash = slice::from_raw_parts(app_flash_address, app_flash_size);
</span><span class='line'>
</span><span class='line'><span class="gd">-            process.stored_state = Cell::new(Default::default());</span>
</span><span class='line'><span class="gi">+            // process.stored_state = Cell::new(Default::default());</span>
</span><span class='line'>             process.state = Cell::new(State::Unstarted);
</span><span class='line'>             process.fault_response = fault_response;
</span><span class='line'>
</span><span class='line'><span class="gu">@@ -3246,6 +3240,7 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>                 }));
</span><span class='line'>             });
</span><span class='line'>
</span><span class='line'><span class="gi">+            /*</span>
</span><span class='line'>             let mut stored_state = process.stored_state.get();
</span><span class='line'>             match chip.userspace_kernel_boundary().initialize_new_process(
</span><span class='line'>                 process.sp(),
</span><span class='line'><span class="gu">@@ -3263,6 +3258,7 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>                     return (None, app_flash_size, 0);
</span><span class='line'>                 }
</span><span class='line'>             };
</span><span class='line'><span class="gi">+             */</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the answer is: YES. The bug reproduces!</p>

<p>And <em>now</em> we can move forward
with <a href="https://github.com/pnkfelix/demo-minimization/commit/1e6f3af833a5e84f94fefccaacc41cc473af1a55">removing that field</a>&hellip; YES, still reproduces:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2809,9 +2809,6 @@ pub struct Process&lt;&#39;a, C: &#39;static + Chip&gt; {</span>
</span><span class='line'>
</span><span class='line'>     header: tbfheader::TbfHeader,
</span><span class='line'>
</span><span class='line'><span class="gd">-    stored_state:</span>
</span><span class='line'><span class="gd">-        Cell&lt;&lt;&lt;C as Chip&gt;::UserspaceKernelBoundary as UserspaceKernelBoundary&gt;::StoredState&gt;,</span>
</span><span class='line'><span class="gd">-</span>
</span><span class='line'>     state: Cell&lt;State&gt;,
</span><span class='line'>
</span><span class='line'>     fault_response: FaultResponse,
</span></code></pre></td></tr></table></div></figure>


<p>And then see about
<a href="https://github.com/pnkfelix/demo-minimization/commit/454e113532cded34be70fd11ab729785db061c20">removed the bound</a> on the associated type that sent us on this path&hellip; YES</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2525,7 +2525,7 @@ mod platform {</span>
</span><span class='line'>         type
</span><span class='line'>         MPU: mpu::MPU;
</span><span class='line'>         type
</span><span class='line'><span class="gd">-        UserspaceKernelBoundary: syscall::UserspaceKernelBoundary;</span>
</span><span class='line'><span class="gi">+        UserspaceKernelBoundary;</span>
</span><span class='line'>         type
</span><span class='line'>         SysTick: systick::SysTick;
</span><span class='line'>         fn service_pending_interrupts(&amp;self) { loop  { } }
</span></code></pre></td></tr></table></div></figure>


<p>So <em>now</em> we can pop our stack: We can go back to <code>chips/arty_e21</code>,
and apply <a href="#Tactic:..Type-trivialization.">&ldquo;type-trivialization&rdquo;</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/chips/arty_e21/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/chips/arty_e21/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -21,7 +21,7 @@ impl ArtyExx {</span>
</span><span class='line'>
</span><span class='line'> impl kernel::Chip for ArtyExx {
</span><span class='line'>     type MPU = ();
</span><span class='line'><span class="gd">-    type UserspaceKernelBoundary = rv32i::syscall::SysCall;</span>
</span><span class='line'><span class="gi">+    type UserspaceKernelBoundary = ();</span>
</span><span class='line'>     type SysTick = ();
</span><span class='line'> }
</span></code></pre></td></tr></table></div></figure>


<p>We did it!</p>

<p><a href="https://github.com/pnkfelix/demo-minimization/commit/b9abaf69418a2cb94c508586c35f4c340221d596">With that in place, we can do</a> more <a href="#Tactic:..dep-reduction.">&ldquo;dep-reduction&rdquo;</a>, by removing the <code>rv32i</code> dependency from <code>chips/arty_e21</code>.</p>

<p>At this point, we could continue with the above transformations to further reduce <code>kernel</code>.</p>

<p>But I want to switch to showing a different kind of minimization transformation, one that will
let us make further simplifications to <code>boards/arty-e21</code>.</p>

<a name="Simplfying.the.existing.code"></a>
<h2>Simplfying the existing code</h2>

<p>Looking again at <code>boards/arty-e21</code>, we have this method body:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="cp">#[no_mangle]</span>
</span><span class='line'><span class="k">pub</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">reset_handler</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">chip</span> <span class="o">=</span> <span class="n">static_init</span><span class="o">!</span><span class="p">(</span><span class="n">arty_e21</span><span class="o">::</span><span class="n">chip</span><span class="o">::</span><span class="n">ArtyExx</span><span class="p">,</span> <span class="n">arty_e21</span><span class="o">::</span><span class="n">chip</span><span class="o">::</span><span class="n">ArtyExx</span><span class="o">::</span><span class="n">new</span><span class="p">());</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">process_mgmt_cap</span> <span class="o">=</span> <span class="n">create_capability</span><span class="o">!</span><span class="p">(</span><span class="n">capabilities</span><span class="o">::</span><span class="n">ProcessManagementCapability</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">board_kernel</span> <span class="o">=</span> <span class="n">static_init</span><span class="o">!</span><span class="p">(</span><span class="n">kernel</span><span class="o">::</span><span class="n">Kernel</span><span class="p">,</span> <span class="n">kernel</span><span class="o">::</span><span class="n">Kernel</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">PROCESSES</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">kernel</span><span class="o">::</span><span class="n">procs</span><span class="o">::</span><span class="n">load_processes</span><span class="p">(</span>
</span><span class='line'>        <span class="n">board_kernel</span><span class="p">,</span>
</span><span class='line'>        <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="mi">0</span><span class="k">u8</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="mi">0</span><span class="p">;</span> <span class="mi">8192</span><span class="p">],</span> <span class="c1">// APP_MEMORY,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="k">mut</span> <span class="n">PROCESSES</span><span class="p">,</span>
</span><span class='line'>        <span class="n">kernel</span><span class="o">::</span><span class="n">procs</span><span class="o">::</span><span class="n">FaultResponse</span><span class="o">::</span><span class="n">Panic</span><span class="p">,</span>
</span><span class='line'>        <span class="o">&amp;</span><span class="n">process_mgmt_cap</span><span class="p">,</span>
</span><span class='line'>    <span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>It would be nice to figure out which parts of this are actually relevant.</p>

<p>Unfortunately, <code>kernel::procs::load_processes</code> was one of the functions
where we could not apply <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> without masking the <code>rustc</code> bug.</p>

<p>Let us see if we can at least simplfify the API of <code>load_processes</code> itself.</p>

<p>It currently looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">load_processes</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">(</span>
</span><span class='line'>    <span class="n">kernel</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">Kernel</span><span class="p">,</span>
</span><span class='line'>    <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="n">start_of_flash</span><span class="o">:</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>    <span class="n">app_memory</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="kt">u8</span><span class="p">],</span>
</span><span class='line'>    <span class="n">procs</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="k">mut</span> <span class="p">[</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span><span class="o">&gt;</span><span class="p">],</span>
</span><span class='line'>    <span class="n">fault_response</span><span class="o">:</span> <span class="n">FaultResponse</span><span class="p">,</span>
</span><span class='line'>    <span class="n">_capability</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">dyn</span> <span class="n">ProcessManagementCapability</span><span class="p">,</span>
</span><span class='line'><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">apps_in_flash_ptr</span> <span class="o">=</span> <span class="n">start_of_flash</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">app_memory_ptr</span> <span class="o">=</span> <span class="n">app_memory</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">app_memory_size</span> <span class="o">=</span> <span class="n">app_memory</span><span class="p">.</span><span class="n">len</span><span class="p">();</span>
</span><span class='line'>    <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mf">0.</span><span class="p">.</span><span class="n">procs</span><span class="p">.</span><span class="n">len</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="p">(</span><span class="n">process</span><span class="p">,</span> <span class="n">flash_offset</span><span class="p">,</span> <span class="n">memory_offset</span><span class="p">)</span> <span class="o">=</span> <span class="n">Process</span><span class="o">::</span><span class="n">create</span><span class="p">(</span>
</span><span class='line'>                <span class="n">kernel</span><span class="p">,</span>
</span><span class='line'>                <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>                <span class="n">apps_in_flash_ptr</span><span class="p">,</span>
</span><span class='line'>                <span class="n">app_memory_ptr</span><span class="p">,</span>
</span><span class='line'>                <span class="n">app_memory_size</span><span class="p">,</span>
</span><span class='line'>                <span class="n">fault_response</span><span class="p">,</span>
</span><span class='line'>                <span class="n">i</span><span class="p">,</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">if</span> <span class="n">process</span><span class="p">.</span><span class="n">is_none</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="n">flash_offset</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">memory_offset</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">{</span>
</span><span class='line'>                    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">procs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">process</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">apps_in_flash_ptr</span> <span class="o">=</span> <span class="n">apps_in_flash_ptr</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">flash_offset</span><span class="p">);</span>
</span><span class='line'>            <span class="n">app_memory_ptr</span> <span class="o">=</span> <span class="n">app_memory_ptr</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">memory_offset</span><span class="p">);</span>
</span><span class='line'>            <span class="n">app_memory_size</span> <span class="o">-=</span> <span class="n">memory_offset</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The fact that <code>Process::create</code> was <em>another</em> function that we could
not <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> gives us a hint has to how to simplfy this further: can we
<a href="https://github.com/pnkfelix/demo-minimization/commit/4b60bdd00f670d55c3508ad5cee9d1f4778e361d">reduce this method body</a> to <em>just</em> a <code>Process::create</code> call, and see
if the bug persists?</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2586,31 +2586,17 @@ pub fn load_processes&lt;C: Chip&gt;(</span>
</span><span class='line'>     let mut apps_in_flash_ptr = start_of_flash;
</span><span class='line'>     let mut app_memory_ptr = app_memory.as_mut_ptr();
</span><span class='line'>     let mut app_memory_size = app_memory.len();
</span><span class='line'><span class="gd">-    for i in 0..procs.len() {</span>
</span><span class='line'>         unsafe {
</span><span class='line'><span class="gd">-            let (process, flash_offset, memory_offset) = Process::create(</span>
</span><span class='line'><span class="gi">+            Process::create(</span>
</span><span class='line'>                 kernel,
</span><span class='line'>                 chip,
</span><span class='line'>                 apps_in_flash_ptr,
</span><span class='line'>                 app_memory_ptr,
</span><span class='line'>                 app_memory_size,
</span><span class='line'>                 fault_response,
</span><span class='line'><span class="gd">-                i,</span>
</span><span class='line'><span class="gi">+                0,</span>
</span><span class='line'>             );
</span><span class='line'><span class="gd">-</span>
</span><span class='line'><span class="gd">-            if process.is_none() {</span>
</span><span class='line'><span class="gd">-                if flash_offset == 0 &amp;&amp; memory_offset == 0 {</span>
</span><span class='line'><span class="gd">-                    break;</span>
</span><span class='line'><span class="gd">-                }</span>
</span><span class='line'><span class="gd">-            } else {</span>
</span><span class='line'><span class="gd">-                procs[i] = process;</span>
</span><span class='line'><span class="gd">-            }</span>
</span><span class='line'><span class="gd">-</span>
</span><span class='line'><span class="gd">-            apps_in_flash_ptr = apps_in_flash_ptr.add(flash_offset);</span>
</span><span class='line'><span class="gd">-            app_memory_ptr = app_memory_ptr.add(memory_offset);</span>
</span><span class='line'><span class="gd">-            app_memory_size -= memory_offset;</span>
</span><span class='line'>         }
</span><span class='line'><span class="gd">-    }</span>
</span><span class='line'> }
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>And <em>yes</em>, the bug still reproduces.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Simplify Workflow
</span></p>

<a name="Tactic:..RHS-inlining."></a>
<h2>Tactic: &ldquo;RHS-inlining&rdquo;</h2>

<p>This is just the classic transformation of taking the right-hand side
of a <code>let</code> or <code>const</code> and copying it into the usage sites for the
variable defined by the <code>let</code> or <code>const</code>. Once all uses of the
variable have been replaced, you can try removing the <code>let</code> or <code>const</code>
itself (i.e. <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a>)</p>

<p>In our specific case, we <a href="https://github.com/pnkfelix/demo-minimization/commit/f80808f057c22d0b8bbdee6765cbef6304565fe5">can apply this</a> to <code>load_processes</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2583,16 +2583,13 @@ pub fn load_processes&lt;C: Chip&gt;(</span>
</span><span class='line'>     fault_response: FaultResponse,
</span><span class='line'>     _capability: &amp;dyn ProcessManagementCapability,
</span><span class='line'> ) {
</span><span class='line'><span class="gd">-    let mut apps_in_flash_ptr = start_of_flash;</span>
</span><span class='line'><span class="gd">-    let mut app_memory_ptr = app_memory.as_mut_ptr();</span>
</span><span class='line'><span class="gd">-    let mut app_memory_size = app_memory.len();</span>
</span><span class='line'>         unsafe {
</span><span class='line'>             Process::create(
</span><span class='line'>                 kernel,
</span><span class='line'>                 chip,
</span><span class='line'><span class="gd">-                apps_in_flash_ptr,</span>
</span><span class='line'><span class="gd">-                app_memory_ptr,</span>
</span><span class='line'><span class="gd">-                app_memory_size,</span>
</span><span class='line'><span class="gi">+                start_of_flash,</span>
</span><span class='line'><span class="gi">+                app_memory.as_mut_ptr(),</span>
</span><span class='line'><span class="gi">+                app_memory.len(),</span>
</span><span class='line'>                 fault_response,
</span><span class='line'>                 0,
</span><span class='line'>             );
</span></code></pre></td></tr></table></div></figure>


<p>However, this technique on its own does not tend to actually reduce
the problem at hand, in terms of making it possible for us to remove
imports or simplify <code>fn</code> API signatures.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Tactic:..Defaultification."></a>
<h2>Tactic: &ldquo;Defaultification&rdquo;</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka &ldquo;Scalars Gotta Scale&rdquo;
</span>
If you really want to <em>simplify</em>, then you should replace the
occurences of the variable with some &ldquo;obvious&rdquo; value based on its
type.</p>

<p>(This is the obvious alternative to <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> when it comes to simplifying <code>const fn</code>.)</p>

<p>More specifically: frequently, the return type of a <code>const fn</code> (or the
type of a <code>const</code> item) is some scalar type (like <code>u32</code>, <code>f64</code>, or
<code>bool</code>). These all have &ldquo;obvious&rdquo; values that you can just plug in
(respectively <code>0</code>, <code>0.0</code>, or <code>false</code>).</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kr">const</span> <span class="k">fn</span> <span class="n">cfoo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">u32</span> <span class="p">{</span> <span class="o">----</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kr">const</span> <span class="k">fn</span> <span class="n">cfoo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">u32</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In the case of <code>load_processes</code>, <a href="#Tactic:..Defaultification.">&ldquo;defaultification&rdquo;</a> <a href="https://github.com/pnkfelix/demo-minimization/commit/c6ed070fc55ce2ca5364f477154f53174eec5849">yields this</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2587,9 +2587,9 @@ pub fn load_processes&lt;C: Chip&gt;(</span>
</span><span class='line'>             Process::create(
</span><span class='line'>                 kernel,
</span><span class='line'>                 chip,
</span><span class='line'><span class="gd">-                start_of_flash,</span>
</span><span class='line'><span class="gd">-                app_memory.as_mut_ptr(),</span>
</span><span class='line'><span class="gd">-                app_memory.len(),</span>
</span><span class='line'><span class="gi">+                0 as *const u8,</span>
</span><span class='line'><span class="gi">+                (&amp;mut []).as_mut_ptr(),</span>
</span><span class='line'><span class="gi">+                0,</span>
</span><span class='line'>                 fault_response,
</span><span class='line'>                 0,
</span><span class='line'>             );
</span></code></pre></td></tr></table></div></figure>


<p>That means we&rsquo;ve gotten rid of the uses of three <code>fn</code> parameters in
the body of <code>load_processes</code>. Lets see what that can buy us for
further reduction.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Technique:..Genertrification."></a>
<h2>Technique: &ldquo;Genertrification&rdquo;</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
aka &ldquo;Type Freedom&rdquo;
</span>
Once you remove all uses of parameter (which is readily identifiable
via either lint diagnostics or if the parameter has just
<code>_: ParamType</code> for its declaration), you can <a href="#Technique:..Genertrification.">&ldquo;genertrify&rdquo;</a> it to get rid of the
use of <code>ParamType</code>.</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="n">ParamType</span><span class="p">,</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="n">A</span><span class="p">,</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>or even more simply (in terms of locality of the transformation):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The beauty of this is that it can almost always be applied even if
there remain uses of <code>foo</code> elsewhere in the code.</p>

<p>Therefore, I tend to recommend it over
<a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a>, described below.</p>

<ul>
<li><p>However, this transformation does not work if <code>fn foo</code> must not carry
any generic type parameters; e.g., if <code>fn foo</code> needs to be
object-safe, then you cannot add the type parameteter <code>A</code>.</p></li>
<li><p>The other case where it cannot be applied is when an existing
use is relying on the existing type for inference purposes.
We will <a href="#L.you.can.t.always.genertrify.what.you.want.">see an example of this below</a>.</p></li>
</ul>


<p>In the case of <code>load_processes</code>, <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a> allows <a href="https://github.com/pnkfelix/demo-minimization/commit/25dbbfbe418263460e671bbb6401c290e191d226">this change</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2577,11 +2577,11 @@ use core::cmp::max;</span>
</span><span class='line'> pub fn load_processes&lt;C: Chip&gt;(
</span><span class='line'>     kernel: &amp;&#39;static Kernel,
</span><span class='line'>     chip: &amp;&#39;static C,
</span><span class='line'><span class="gd">-    start_of_flash: *const u8,</span>
</span><span class='line'><span class="gd">-    app_memory: &amp;mut [u8],</span>
</span><span class='line'><span class="gd">-    procs: &amp;&#39;static mut [Option&lt;&amp;&#39;static dyn ProcessType&gt;],</span>
</span><span class='line'><span class="gi">+    _: impl Sized,</span>
</span><span class='line'><span class="gi">+    _: impl Sized,</span>
</span><span class='line'><span class="gi">+    _: impl Sized,</span>
</span><span class='line'>     fault_response: FaultResponse,
</span><span class='line'><span class="gd">-    _capability: &amp;dyn ProcessManagementCapability,</span>
</span><span class='line'><span class="gi">+    _: impl Sized,</span>
</span><span class='line'> ) {
</span><span class='line'>         unsafe {
</span><span class='line'>             Process::create(
</span></code></pre></td></tr></table></div></figure>


<p>And once we do <em>that</em>, we can revise any calls to <code>load_processes</code> and
pass any value we like for the <code>impl Sized</code> arguments. So we&rsquo;ve opened
up new opportunities for <a href="#Tactic:..Expr-elimination.">&ldquo;expr-elimination&rdquo;</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/boards/arty-e21/src/main.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/boards/arty-e21/src/main.rs</span>
</span><span class='line'><span class="gu">@@ -39,17 +39,16 @@ impl Platform for ArtyE21 {</span>
</span><span class='line'> #[no_mangle]
</span><span class='line'> pub unsafe fn reset_handler() {
</span><span class='line'>     let chip = static_init!(arty_e21::chip::ArtyExx, arty_e21::chip::ArtyExx::new());
</span><span class='line'><span class="gd">-    let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);</span>
</span><span class='line'>     let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&amp;PROCESSES));
</span><span class='line'>
</span><span class='line'>     kernel::procs::load_processes(
</span><span class='line'>         board_kernel,
</span><span class='line'>         chip,
</span><span class='line'><span class="gd">-        &amp;0u8 as *const u8,</span>
</span><span class='line'><span class="gd">-        &amp;mut [0; 8192], // APP_MEMORY,</span>
</span><span class='line'><span class="gd">-        &amp;mut PROCESSES,</span>
</span><span class='line'><span class="gi">+        (),</span>
</span><span class='line'><span class="gi">+        (),</span>
</span><span class='line'><span class="gi">+        (),</span>
</span><span class='line'>         kernel::procs::FaultResponse::Panic,
</span><span class='line'><span class="gd">-        &amp;process_mgmt_cap,</span>
</span><span class='line'><span class="gi">+        (),</span>
</span><span class='line'>     );
</span><span class='line'>
</span><span class='line'> }
</span></code></pre></td></tr></table></div></figure>


<p>We would like to continue simplifying the APIs by applying <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a> elsewhere.
For example, <code>load_processes</code> calls <code>Process::create</code>, so it would be useful to simplify
its API.</p>

<p>The body of <code>Process::create</code> is currently over 150 lines of code. But after
bisection-based <a href="#Tactic:..Expr-elimination.">&ldquo;expr-elimination&rdquo;</a>, coupled with <a href="#Tactic:..RHS-inlining.">&ldquo;RHS-inlining&rdquo;</a>, <a href="#Tactic:..Defaultification.">&ldquo;defaultification&rdquo;</a>, and <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a>,
we can get the body down to this far more managable 20 lines:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">kernel</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">Kernel</span><span class="p">,</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>        <span class="n">app_flash_address</span><span class="o">:</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>        <span class="n">remaining_app_memory</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>        <span class="n">remaining_app_memory_size</span><span class="o">:</span> <span class="n">usize</span><span class="p">,</span>
</span><span class='line'>        <span class="n">fault_response</span><span class="o">:</span> <span class="n">FaultResponse</span><span class="p">,</span>
</span><span class='line'>        <span class="n">index</span><span class="o">:</span> <span class="n">usize</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">usize</span><span class="p">,</span> <span class="n">usize</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span>
</span><span class='line'>                <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="p">((</span><span class="o">&amp;</span><span class="k">mut</span> <span class="p">[]).</span><span class="n">as_mut_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">process</span><span class="p">.</span><span class="n">debug</span> <span class="o">=</span> <span class="n">MapCell</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">ProcessDebug</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">app_heap_start_pointer</span><span class="o">:</span> <span class="nb">None</span><span class="p">,</span>
</span><span class='line'>                <span class="n">app_stack_start_pointer</span><span class="o">:</span> <span class="nb">None</span><span class="p">,</span>
</span><span class='line'>                <span class="n">min_stack_pointer</span><span class="o">:</span> <span class="mi">0</span> <span class="k">as</span> <span class="o">*</span><span class="kr">const</span> <span class="kt">u8</span><span class="p">,</span>
</span><span class='line'>                <span class="n">syscall_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>                <span class="n">last_syscall</span><span class="o">:</span> <span class="nb">None</span><span class="p">,</span>
</span><span class='line'>                <span class="n">dropped_callback_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>                <span class="n">restart_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>                <span class="n">timeslice_expiration_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>                <span class="nb">Some</span><span class="p">(</span><span class="n">process</span><span class="p">),</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And now we can apply <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -3065,13 +3065,13 @@ fn exceeded_check(size: usize, allocated: usize) -&gt; &amp;&#39;static str { loop { } }</span>
</span><span class='line'> impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {
</span><span class='line'>     #[allow(clippy::cast_ptr_alignment)]
</span><span class='line'>     crate unsafe fn create(
</span><span class='line'><span class="gd">-        kernel: &amp;&#39;static Kernel,</span>
</span><span class='line'><span class="gi">+        kernel: impl Sized,</span>
</span><span class='line'>         chip: &amp;&#39;static C,
</span><span class='line'><span class="gd">-        app_flash_address: *const u8,</span>
</span><span class='line'><span class="gi">+        app_flash_address: impl Sized,</span>
</span><span class='line'>         remaining_app_memory: *mut u8,
</span><span class='line'><span class="gd">-        remaining_app_memory_size: usize,</span>
</span><span class='line'><span class="gd">-        fault_response: FaultResponse,</span>
</span><span class='line'><span class="gd">-        index: usize,</span>
</span><span class='line'><span class="gi">+        remaining_app_memory_size: impl Sized,</span>
</span><span class='line'><span class="gi">+        fault_response: impl Sized,</span>
</span><span class='line'><span class="gi">+        index: impl Sized,</span>
</span><span class='line'>     ) -&gt; (Option&lt;&amp;&#39;static dyn ProcessType&gt;, usize, usize) {
</span><span class='line'>             let mut process: &amp;mut Process&lt;C&gt; =
</span><span class='line'>                 &amp;mut *((&amp;mut []).as_mut_ptr() as *mut Process&lt;&#39;static, C&gt;);
</span></code></pre></td></tr></table></div></figure>


<a name="L.you.can.t.always.genertrify.what.you.want."></a>
<h4>&ldquo;you can&rsquo;t always genertrify what you want&rdquo;</h4>

<p>Unfortunately, I was not able to <a href="#Technique:..Genertrification.">&ldquo;genertrify&rdquo;</a> the <code>remaining_app_memory</code>
formal parameter, even though it is unused in the function body. Why
is this? Because the current call-site is <em>relying</em> on the type of the
formal parameter for inference purposes. So in this case, we need to
update the API in tandem with the call site:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2588,7 +2588,7 @@ pub fn load_processes&lt;C: Chip&gt;(</span>
</span><span class='line'>                 (),
</span><span class='line'>                 chip,
</span><span class='line'>                 (),
</span><span class='line'><span class="gd">-                (&amp;mut []).as_mut_ptr(),</span>
</span><span class='line'><span class="gi">+                (),</span>
</span><span class='line'>                 0,
</span><span class='line'>                 (),
</span><span class='line'>                 0,
</span><span class='line'><span class="gu">@@ -3068,7 +3068,7 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>         kernel: impl Sized,
</span><span class='line'>         chip: &amp;&#39;static C,
</span><span class='line'>         app_flash_address: impl Sized,
</span><span class='line'><span class="gd">-        remaining_app_memory: *mut u8,</span>
</span><span class='line'><span class="gi">+        remaining_app_memory: impl Sized,</span>
</span><span class='line'>         remaining_app_memory_size: impl Sized,
</span><span class='line'>         fault_response: impl Sized,
</span><span class='line'>         index: impl Sized,
</span></code></pre></td></tr></table></div></figure>


<p>This allows further <a href="#Tactic:..Expr-elimination.">&ldquo;expr-elimination&rdquo;</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -3076,17 +3076,6 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>             let mut process: &amp;mut Process&lt;C&gt; =
</span><span class='line'>                 &amp;mut *((&amp;mut []).as_mut_ptr() as *mut Process&lt;&#39;static, C&gt;);
</span><span class='line'>
</span><span class='line'><span class="gd">-            process.debug = MapCell::new(ProcessDebug {</span>
</span><span class='line'><span class="gd">-                app_heap_start_pointer: None,</span>
</span><span class='line'><span class="gd">-                app_stack_start_pointer: None,</span>
</span><span class='line'><span class="gd">-                min_stack_pointer: 0 as *const u8,</span>
</span><span class='line'><span class="gd">-                syscall_count: 0,</span>
</span><span class='line'><span class="gd">-                last_syscall: None,</span>
</span><span class='line'><span class="gd">-                dropped_callback_count: 0,</span>
</span><span class='line'><span class="gd">-                restart_count: 0,</span>
</span><span class='line'><span class="gd">-                timeslice_expiration_count: 0,</span>
</span><span class='line'><span class="gd">-            });</span>
</span><span class='line'><span class="gd">-</span>
</span><span class='line'>             return (
</span><span class='line'>                 Some(process),
</span><span class='line'>                 0usize,
</span></code></pre></td></tr></table></div></figure>


<p>and we bave gotten <code>Process::create</code> down to something that actually is close to minimal,
at least with given the transformations we have covered so far:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">kernel</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>        <span class="n">app_flash_address</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>        <span class="n">remaining_app_memory</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>        <span class="n">remaining_app_memory_size</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>        <span class="n">fault_response</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>        <span class="n">index</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">usize</span><span class="p">,</span> <span class="n">usize</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span>
</span><span class='line'>                <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="p">((</span><span class="o">&amp;</span><span class="k">mut</span> <span class="p">[]).</span><span class="n">as_mut_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>                <span class="nb">Some</span><span class="p">(</span><span class="n">process</span><span class="p">),</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>But of course, we can go further!</p>

<a name="Once.all.the.code.is.gone...."></a>
<h2>Once all the code is gone &hellip;</h2>

<p>The applicability of many of the remaining patterns <em>depends on</em>
whether you have successfully trivialized all or most method bodies.
That is, if you have gotten rid of most of the complex expressions in
the program, then you can usually remove things like struct field
declarations or any &ldquo;interesting&rdquo; types on formal parameters.</p>

<p>So, lets see if we can further reduce the complexity of our example
by simplifying the APIs of the functions involved.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Technique:..Param-elimination."></a>
<h2>Technique: &ldquo;Param-elimination&rdquo;</h2>

<p>If you have successfully eliminated all uses of a method <code>foo</code>,
then you can apply this transformation:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="n">ArgType</span><span class="p">,</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In some rare cases, the compiler bug will requires a method signature
to keep the same number of arguments; for that scenario, you can
instead use <a href="#Tactic:..Type-trivialization.">&ldquo;type-trivialization&rdquo;</a> for the parameter:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="n">ArgType</span><span class="p">,</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="p">(),</span> <span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Either way, these transformations can only be applied if all <em>uses</em> of
<code>foo</code> have been eliminated via trivialization of bodies as described
above (or if you are willing to update them all accordingly). Thus, I
tend to recommend applying <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a> instead: that transformation
can be applied without concern about the usage sites.</p>

<p>Of course, if you have already applied <a href="#Technique:..Genertrification.">&ldquo;genertrification&rdquo;</a> and also updated
all call sites to pass something trivial like <code>()</code>, then you can readily
apply either <a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a> or <a href="#Tactic:..Type-trivialization.">&ldquo;type-trivialization&rdquo;</a>: it really should be
easy to update the call-sites in that scenario.</p>

<p>In our particular case of <code>Process::create</code>, we currently have a <code>fn</code>-signature that looks
like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>    <span class="n">kernel</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="n">app_flash_address</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="n">remaining_app_memory</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="n">remaining_app_memory_size</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="n">fault_response</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'>    <span class="n">index</span><span class="o">:</span> <span class="k">impl</span> <span class="nb">Sized</span><span class="p">,</span>
</span><span class='line'><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">usize</span><span class="p">,</span> <span class="n">usize</span><span class="p">)</span> <span class="p">{</span>
</span></code></pre></td></tr></table></div></figure>


<p>And we already updated the single call-site to pass <code>()</code> or <code>0</code> for each of the parameters of type <code>impl Sized</code>,
so now <a href="https://github.com/pnkfelix/demo-minimization/commit/540231a22733485eef87bdfe1314f079821d7abc">we can just remove them entirely</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2585,13 +2585,7 @@ pub fn load_processes&lt;C: Chip&gt;(</span>
</span><span class='line'> ) {
</span><span class='line'>         unsafe {
</span><span class='line'>             Process::create(
</span><span class='line'><span class="gd">-                (),</span>
</span><span class='line'>                 chip,
</span><span class='line'><span class="gd">-                (),</span>
</span><span class='line'><span class="gd">-                (),</span>
</span><span class='line'><span class="gd">-                0,</span>
</span><span class='line'><span class="gd">-                (),</span>
</span><span class='line'><span class="gd">-                0,</span>
</span><span class='line'>             );
</span><span class='line'>         }
</span><span class='line'> }
</span><span class='line'><span class="gu">@@ -3065,13 +3059,7 @@ fn exceeded_check(size: usize, allocated: usize) -&gt; &amp;&#39;static str { loop { } }</span>
</span><span class='line'> impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {
</span><span class='line'>     #[allow(clippy::cast_ptr_alignment)]
</span><span class='line'>     crate unsafe fn create(
</span><span class='line'><span class="gd">-        kernel: impl Sized,</span>
</span><span class='line'>         chip: &amp;&#39;static C,
</span><span class='line'><span class="gd">-        app_flash_address: impl Sized,</span>
</span><span class='line'><span class="gd">-        remaining_app_memory: impl Sized,</span>
</span><span class='line'><span class="gd">-        remaining_app_memory_size: impl Sized,</span>
</span><span class='line'><span class="gd">-        fault_response: impl Sized,</span>
</span><span class='line'><span class="gd">-        index: impl Sized,</span>
</span><span class='line'>     ) -&gt; (Option&lt;&amp;&#39;static dyn ProcessType&gt;, usize, usize) {
</span><span class='line'>             let mut process: &amp;mut Process&lt;C&gt; =
</span><span class='line'>                 &amp;mut *((&amp;mut []).as_mut_ptr() as *mut Process&lt;&#39;static, C&gt;);
</span></code></pre></td></tr></table></div></figure>


<p>And compiling still hits the same ICE, so this <a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a> was a legitimate reduction
of the problem.</p>

<p>Next we&rsquo;ll consider a related transformation on the <code>fn</code>-signature.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Technique:..Ret-elimination."></a>
<h2>Technique: &ldquo;Ret-elimination&rdquo;</h2>

<p>If you have successfully eliminated all uses of the value returned from calls to <code>foo</code>,
then you can apply this transformation:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>If <code>fn foo</code> still has a body, then you can just turn every return point in the body into
a normal expression:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">if</span> <span class="n">A</span> <span class="p">{</span> <span class="k">return</span> <span class="n">B</span><span class="p">;</span> <span class="p">}</span> <span class="n">TailReturn</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="n">A</span> <span class="p">{</span> <span class="n">B</span><span class="p">;</span> <span class="p">}</span> <span class="n">TailReturn</span><span class="p">;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our case, the sole call to <code>Process::create</code> now looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'>    <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">Process</span><span class="o">::</span><span class="n">create</span><span class="p">(</span>
</span><span class='line'>            <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>        <span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So we can directly apply <a href="#Technique:..Ret-elimination.">&ldquo;ret-elimination&rdquo;</a> to the definition of <code>Process::create</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -3060,11 +3060,11 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>     #[allow(clippy::cast_ptr_alignment)]
</span><span class='line'>     crate unsafe fn create(
</span><span class='line'>         chip: &amp;&#39;static C,
</span><span class='line'><span class="gd">-    ) -&gt; (Option&lt;&amp;&#39;static dyn ProcessType&gt;, usize, usize) {</span>
</span><span class='line'><span class="gi">+    ) {</span>
</span><span class='line'>             let mut process: &amp;mut Process&lt;C&gt; =
</span><span class='line'>                 &amp;mut *((&amp;mut []).as_mut_ptr() as *mut Process&lt;&#39;static, C&gt;);
</span><span class='line'>
</span><span class='line'><span class="gd">-            return (</span>
</span><span class='line'><span class="gi">+            (</span>
</span><span class='line'>                 Some(process),
</span><span class='line'>                 0usize,
</span><span class='line'>                 0usize,
</span></code></pre></td></tr></table></div></figure>


<p>But&hellip; Ah ha! Doing this causes the compilation error to disappear!</p>

<p>What happened?</p>

<p>Well, inspecting the return type, we can see that <a href="#Technique:..Ret-elimination.">&ldquo;Ret-elimination&rdquo;</a> in this
case has gotten rid of the type: <code>(Option&lt;&amp;'static dyn ProcessType&gt;, usize, usize)</code>.
Nested within that tuple, we see the type <code>&amp;'static dyn ProcessType</code>.
So, the attemtpt to return <code>(Some(process), 0, 0)</code> is causing the generated
code to coerce the <code>process: &amp;mut Process&lt;C&gt;</code> into a <em>trait-object</em> of
type <code>&amp;dyn ProcessType</code>. And apparently this is part of generating the bug!</p>

<p>So, do not look at this reduction-failure as a set-back: It in fact may
serve as a clue as to the root cause of the bug.</p>

<a name="Final.reduction.touches.on..code.Process::create..code."></a>
<h2>Final reduction touches on <code>Process::create</code></h2>

<p>For <code>Process::create</code>, we have:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">usize</span><span class="p">,</span> <span class="n">usize</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span>
</span><span class='line'>                <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="p">((</span><span class="o">&amp;</span><span class="k">mut</span> <span class="p">[]).</span><span class="n">as_mut_ptr</span><span class="p">()</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="k">&#39;static</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>                <span class="nb">Some</span><span class="p">(</span><span class="n">process</span><span class="p">),</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>                <span class="mi">0</span><span class="k">u</span><span class="n">size</span><span class="p">,</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We can <a href="https://github.com/pnkfelix/demo-minimization/commit/27540630839cf2efc4a52dee42657fca35dce0f0">simplfy this API</a> by reducing the return type to the core element that matters: the trait object:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -3045,15 +3045,11 @@ impl&lt;C: &#39;static + Chip&gt; Process&lt;&#39;a, C&gt; {</span>
</span><span class='line'>     #[allow(clippy::cast_ptr_alignment)]
</span><span class='line'>     crate unsafe fn create(
</span><span class='line'>         chip: &amp;&#39;static C,
</span><span class='line'><span class="gd">-    ) -&gt; (Option&lt;&amp;&#39;static dyn ProcessType&gt;, usize, usize) {</span>
</span><span class='line'><span class="gi">+    ) -&gt; &amp;&#39;static dyn ProcessType {</span>
</span><span class='line'>             let mut process: &amp;mut Process&lt;C&gt; =
</span><span class='line'>                 &amp;mut *((&amp;mut []).as_mut_ptr() as *mut Process&lt;&#39;static, C&gt;);
</span><span class='line'>
</span><span class='line'><span class="gd">-            return (</span>
</span><span class='line'><span class="gd">-                Some(process),</span>
</span><span class='line'><span class="gd">-                0usize,</span>
</span><span class='line'><span class="gd">-                0usize,</span>
</span><span class='line'><span class="gd">-            );</span>
</span><span class='line'><span class="gi">+            process</span>
</span><span class='line'>     }
</span><span class='line'>
</span><span class='line'>     #[allow(clippy::cast_ptr_alignment)]
</span></code></pre></td></tr></table></div></figure>


<p>In fact, we can do even better. The initialization expression on the right-hand side
of <code>let mut process = ...</code> is ugly, and its actually completely irrelevant.</p>

<p>In cases like these where we are hitting an ICE, we can use a special kind of <a href="#Tactic:..Defaultification.">&ldquo;defaultification&rdquo;</a>
to conjure up types without needing any knowledge of their expression.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Trivialize Content
</span></p>

<a name="Technique:..None-defaulting."></a>
<h2>Technique: &ldquo;None-defaulting&rdquo;</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This is yet another case where the fact that we are debugging a compile-time issue is
crucial. You obviously cannot be tossing <code>None.unwrap()</code> into code you expect to run
usefully.
</span>
The idea of <a href="#Technique:..None-defaulting.">&ldquo;none-defaulting&rdquo;</a> is simple: You need the compiler to think you have a value of type
<code>T</code>. But the steps to make an instance of <code>T</code> are not relevant to reproducing the bug.
So just make a <code>None::&lt;T&gt;</code>, and unwrap it.</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kd">let</span> <span class="n">x</span><span class="o">:</span> <span class="n">T</span> <span class="o">=</span> <span class="o">----</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kd">let</span> <span class="n">x</span><span class="o">:</span> <span class="n">T</span> <span class="o">=</span> <span class="nb">None</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our case, <a href="https://github.com/pnkfelix/demo-minimization/commit/c52b9f55c95c55723a32077c72451c772e00e618">applying this technique</a> to <code>Process::create</code> yields this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nb">None</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">process</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And compiling this, the ICE still reproduces!</p>

<a name="So..where.are.we.now"></a>
<h1>So, where are we now</h1>

<p>We&rsquo;ve still got a set of three crates, one of which is over 3,000 lines long.</p>

<p>But we&rsquo;ve also reduced the set of non-trival functions in that big crate to just
three:</p>

<ul>
<li><code>Process::create</code>,</li>
<li><code>load_processes</code>, and</li>
<li><code>&lt;Process as ProcessType&gt;::process_detail_fmt</code>.</li>
</ul>


<p>If you think for a momeent, you can see how everything is tying together here:
This ICE is occurring in the midst of some step of code-generation. We previously
established that in order to observe the ICE,
the compiler needs to handle code-generation for the coercion from
<code>&amp;Process</code> to a trait object <code>&amp;dyn ProcessType</code> .
A method like <code>&lt;Process as ProcessType&gt;::process_detail_fmt</code> is part of the virtual-methods
that get their code generated as part of that coercion.</p>

<p>We already showed <code>Process::create</code> is now pretty trivial.</p>

<p>As for <code>load_processes</code>,
after doing some additional <a href="#Tactic:..Unusedification.">&ldquo;unusedification&rdquo;</a> and <a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a>
we can get it down to this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">load_processes</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">(</span>
</span><span class='line'>    <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">Process</span><span class="o">::</span><span class="n">create</span><span class="p">(</span>
</span><span class='line'>                <span class="n">chip</span><span class="p">,</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which we might as well rewrite into the one-liner:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">load_processes</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">(</span><span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">)</span> <span class="p">{</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="n">Process</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">chip</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That just leaves <code>&lt;Process as ProcessType&gt;::process_detail_fmt</code>, which we have not looked at yet.</p>

<p>As part of the earlier (undocumented) bisection process on the out-of-line <code>mod process;</code>, I
already <a href="#Tactic:..simpl-impl.">&ldquo;simpl-impled&rdquo;</a> the <code>ProcessType</code> trait declaration, so it looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">trait</span> <span class="n">ProcessType</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">appid</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">AppId</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This means we can remove all of the irrelevant methods from the <code>impl&lt;C: Chip&gt; ProcessType for Process&lt;'a, C&gt;</code>,
leaving us with just the single method:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">ProcessType</span> <span class="k">for</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">...</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And since this is now the <em>only</em> <code>impl</code> of <code>ProcessType</code>, we can also
remove the other methods from the <code>ProcessType</code> trait itself:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">trait</span> <span class="n">ProcessType</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I cannot stress how satisfying it is to be able to <em>retest</em> the ICE in
between each of these steps. It gives you excellent points to pause,
get up from the keyboard and take a walk (which is another
surprisingly effective debugging methodology).</p>

<p>But we still have the body of <code>fn process_detail_fmt</code> itself, which is
about 175 lines of code. So lets try to winnow that down.</p>

<p><a href="#Technique:.Suffix-bisection">&ldquo;Suffix-bisection&rdquo;</a> ends up revealing that the ICE is triggered by this bit of code
in the method.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'>    <span class="bp">self</span><span class="p">.</span><span class="n">mpu_config</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">config</span><span class="o">|</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="p">.</span><span class="n">write_fmt</span><span class="p">(</span><span class="n">format_args</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">config</span><span class="p">));</span>
</span><span class='line'>    <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>And so we can <a href="#Tactic:..Expr-elimination.">&ldquo;expr-eliminate&rdquo;</a> all the rest, leaving this defintion of the method:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">ProcessType</span> <span class="k">for</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="bp">self</span><span class="p">.</span><span class="n">mpu_config</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">config</span><span class="o">|</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="p">.</span><span class="n">write_fmt</span><span class="p">(</span><span class="n">format_args</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">config</span><span class="p">));</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That <em>looks</em> pretty simple (after all, its a a three line body).
But its still doing some relatively interesting stuff: there&rsquo;s that
<code>format_args!</code> macro in there, and a closure being constructed.</p>

<p>We might try to simplify the body further: turn the closure body into
the main body of <code>process_detail_fmt</code> itself.</p>

<p>The closure takes an input of type <code>config</code>; a quick inspect of the <code>map</code> method
shows that should have the same type as is fed into the <code>MapCell</code> here:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">mpu_config</span><span class="o">:</span> <span class="n">MapCell</span><span class="o">&lt;&lt;&lt;</span><span class="n">C</span> <span class="k">as</span> <span class="n">Chip</span><span class="o">&gt;::</span><span class="n">MPU</span> <span class="k">as</span> <span class="n">MPU</span><span class="o">&gt;::</span><span class="n">MpuConfig</span><span class="o">&gt;</span><span class="p">,</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately, we quickly discover that just moving the closure body into the <code>process_detail_fmt</code>
method is not a valid reduction. That is, I tried compiling with this definition instead:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">ProcessType</span> <span class="k">for</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">config</span> <span class="o">=</span> <span class="nb">None</span><span class="o">::&lt;&lt;&lt;</span><span class="n">C</span> <span class="k">as</span> <span class="n">Chip</span><span class="o">&gt;::</span><span class="n">MPU</span> <span class="k">as</span> <span class="n">MPU</span><span class="o">&gt;::</span><span class="n">MpuConfig</span><span class="o">&gt;</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="p">.</span><span class="n">write_fmt</span><span class="p">(</span><span class="n">format_args</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">config</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>and got this ICE:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">error</span><span class="o">:</span> <span class="n">internal</span> <span class="n">compiler</span> <span class="n">error</span><span class="o">:</span> <span class="n">src</span><span class="o">/</span><span class="n">librustc</span><span class="o">/</span><span class="n">traits</span><span class="o">/</span><span class="n">codegen</span><span class="o">/</span><span class="kn">mod</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">53</span><span class="o">:</span> <span class="n">Encountered</span> <span class="n">error</span> <span class="err">`</span><span class="n">Unimplemented</span><span class="err">`</span> <span class="n">selecting</span> <span class="err">`</span><span class="n">Binder</span><span class="p">(</span><span class="o">&lt;</span><span class="p">()</span> <span class="k">as</span> <span class="n">core</span><span class="o">::</span><span class="n">fmt</span><span class="o">::</span><span class="n">Display</span><span class="o">&gt;</span><span class="p">)</span><span class="err">`</span> <span class="n">during</span> <span class="n">codegen</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
When reduction uncovers a <em>different</em> bug, it is of course
good practice to record that distinct state of the test source code
somewhere. E.g. you could make a separate <code>git</code> branch for it, and come back to
later.
</span>
That is certainly a <em>similar</em> looking ICE. But if we want to be sure
about our reduction, we really need to see the <em>same</em> error: if we
don&rsquo;t see <code>[FulfillmentError(Obligation(...))]</code>, then we should not be
satisifed.</p>

<p>So, we apparently have to keep more of the original code from <code>process_detail_fmt</code>.</p>

<p>At this point we must note that <code>MapCell</code> is a type that <code>kernel</code> is pulling in
from another crate, <code>tock-cells</code>.</p>

<p>So we might need to go and modify code over in <code>tock-cells</code> if we want to fully reduce this code.</p>

<p>Or we might be able to get away with just copying its definition locally, avoiding the hassle of
the full process of reducing the <code>tock-cells</code> crate itself.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
themes: Eliminate Coupling, Identify the Unnecessary
</span></p>

<a name="Tactic:..Cut-spaghetti-imports."></a>
<h3>Tactic: &ldquo;Cut-spaghetti-imports&rdquo;</h3>

<p>This is pretty easy: If you&rsquo;ve <a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a> most of your code, you can often
do this replacement.</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="p">...</span><span class="o">::</span><span class="n">Type</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">Type</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>or, if applicable:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">type</span> <span class="n">Type</span> <span class="o">=</span> <span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you haven&rsquo;t done full <a href="#Tactic:..Body.Loopification.">&ldquo;loopification&rdquo;</a> everywhere (our situation), then you may need
to do this.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">Type</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> <span class="c1">// (adapt definition from elsewhere, potentially via cut-and-paste).</span>
</span><span class='line'><span class="k">impl</span> <span class="n">Type</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note: may need to add (potentially artificial) generic parameters, like so:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="p">...</span><span class="o">::</span><span class="n">Type</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">Type</span><span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">(),</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">type</span> <span class="n">Type</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">(),</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our case, we are going to <a href="https://github.com/pnkfelix/demo-minimization/commit/a01b629c084ca3a0baa8ba81d179451008f67c66">make a local version</a> of <code>tock_cells::MapCell</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">MapCell</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">val</span><span class="o">:</span> <span class="n">core</span><span class="o">::</span><span class="n">cell</span><span class="o">::</span><span class="n">UnsafeCell</span><span class="o">&lt;</span><span class="n">core</span><span class="o">::</span><span class="n">mem</span><span class="o">::</span><span class="n">MaybeUninit</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">,</span>
</span><span class='line'>    <span class="n">occupied</span><span class="o">:</span> <span class="n">Cell</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">MapCell</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">is_some</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="p">{</span>
</span><span class='line'>        <span class="bp">self</span><span class="p">.</span><span class="n">occupied</span><span class="p">.</span><span class="n">get</span><span class="p">()</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">closure</span><span class="o">:</span> <span class="n">F</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">R</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="n">where</span>
</span><span class='line'>        <span class="n">F</span><span class="o">:</span> <span class="n">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">R</span><span class="p">,</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">is_some</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>            <span class="bp">self</span><span class="p">.</span><span class="n">occupied</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">valref</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">val</span><span class="p">.</span><span class="n">get</span><span class="p">()</span> <span class="p">};</span>
</span><span class='line'>            <span class="c1">// TODO: change to valref.get_mut() once stabilized [#53491](https://github.com/rust-lang/rust/issues/53491)</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">res</span> <span class="o">=</span> <span class="n">closure</span><span class="p">(</span><span class="k">unsafe</span> <span class="p">{</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">*</span><span class="n">valref</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">()</span> <span class="p">});</span>
</span><span class='line'>            <span class="bp">self</span><span class="p">.</span><span class="n">occupied</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</span><span class='line'>            <span class="nb">Some</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="nb">None</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I got this by cut-and-pasting the definiton for <code>struct MapCell&lt;T&gt;</code> (and then fixing its types so I could avoid
adding use statements elsewhere), and then cut-and-pasting its <code>fn map</code> method, and finally cut-and-pasting
its <code>fn is_some</code> method after a compilation attempt said that was missing.</p>

<p>With that done, compilation continues to show the ICE.</p>

<p>If you <a href="#Tactic:..Body.Loopification.">&ldquo;loopify&rdquo;</a> the body of <code>MapCell::map</code>, the ICE goes away. There is something relevant inside there.</p>

<p>Some intelligent (as in, non-mechanical) <a href="#Tactic:..Expr-elimination.">&ldquo;expr-elimination&rdquo;</a> and <a href="#Technique:..None-defaulting.">&ldquo;none-defaulting&rdquo;</a>
gets <code>MapCell::map</code> down to this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">MapCell</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">closure</span><span class="o">:</span> <span class="n">F</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">R</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="n">where</span>
</span><span class='line'>        <span class="n">F</span><span class="o">:</span> <span class="n">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">R</span><span class="p">,</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>            <span class="n">closure</span><span class="p">(</span><span class="nb">None</span><span class="o">::&lt;&amp;</span><span class="k">mut</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">.</span><span class="n">unwrap</span><span class="p">());</span>
</span><span class='line'>            <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Compilation still shows the same ICE here, so we haven&rsquo;t lost anything yet.</p>

<p>And yet, this version of <code>map</code> does not use <code>self</code> at all!</p>

<p>This brings us to another kind of simplification: going from object methods to top-level functions.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
themes: Identify the Unnecessary, Trivialize Content
</span></p>

<a name="Tactic:..Deobjectification."></a>
<h2>Tactic: &ldquo;Deobjectification&rdquo;</h2>

<p>The goal of &ldquo;deobjectification&rdquo; is to replace a method defined in an
<code>impl</code> with a top-level function.
Moving some necessary component for reproducing the bug out of the <code>impl</code>
can make the <code>impl</code> itself unnecessary, and thus removable.</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="n">Type</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="o">:</span> <span class="o">---</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="o">---</span> <span class="p">}</span> <span class="c1">// where `---` does not use `Self`/`self`</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">top_foo</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="o">:</span> <span class="o">---</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="o">---</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our case, lets <a href="https://github.com/pnkfelix/demo-minimization/commit/4eb3e7ef3cb4737d23b5dc1b88ffba8a356d9230">try to pull</a> <code>MapCell::map</code> out of <code>MapCell</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- a/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ b/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2577,6 +2577,13 @@ impl&lt;T&gt; MapCell&lt;T&gt; {</span>
</span><span class='line'>             loop { }
</span><span class='line'>     }
</span><span class='line'> }
</span><span class='line'><span class="gi">+</span>
</span><span class='line'><span class="gi">+fn mapcell_map&lt;T, F, R&gt;(closure: F) -&gt; Option&lt;R&gt; where F: FnOnce(&amp;mut T) -&gt; R</span>
</span><span class='line'><span class="gi">+{</span>
</span><span class='line'><span class="gi">+    closure(None::&lt;&amp;mut T&gt;.unwrap());</span>
</span><span class='line'><span class="gi">+    loop { }</span>
</span><span class='line'><span class="gi">+}</span>
</span><span class='line'><span class="gi">+</span>
</span><span class='line'> use crate::common::{Queue, RingBuffer};
</span><span class='line'> use crate::mem::{AppSlice, Shared};
</span><span class='line'> use crate::platform::mpu::{self, MPU};
</span><span class='line'><span class="gu">@@ -2719,7 +2726,7 @@ pub struct Process&lt;&#39;a, C: &#39;static + Chip&gt; {</span>
</span><span class='line'>
</span><span class='line'> impl&lt;C: Chip&gt; ProcessType for Process&lt;&#39;a, C&gt; {
</span><span class='line'>     unsafe fn process_detail_fmt(&amp;self, writer: &amp;mut dyn Write) {
</span><span class='line'><span class="gd">-        self.mpu_config.map(|config| {</span>
</span><span class='line'><span class="gi">+        mapcell_map(|config: &amp;mut &lt;&lt;C as Chip&gt;::MPU as MPU&gt;::MpuConfig| {</span>
</span><span class='line'>             let _ = writer.write_fmt(format_args!(&quot;{}&quot;, config));
</span><span class='line'>         });
</span><span class='line'>     }
</span></code></pre></td></tr></table></div></figure>


<p>Success: compilation still ICE&rsquo;s in the same way.</p>

<p>And now that we&rsquo;ve remove the last uses of fields in <code>self</code> for <code>Process</code>, we can
simplify its definition considerably:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="n">tasks</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">(),</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(And that simplification lets us remove the <code>struct MapCell</code> we added a few steps ago,
since we no longer need it for the now-eliminated <code>mpu_config</code> field.)</p>

<p>So now we&rsquo;ve reduced all three methods to pretty simple bodies; we had
to add a fourth method (<code>mapcell_map</code>) in the process; but that method
was always there all along as part of the puzzle. It had just been
waiting for us in the upstream <code>tock-cells</code> crate.</p>

<p>Furthermore, we can apply <a href="#Technique:..Ret-elimination.">&ldquo;ret-elimination&rdquo;</a> to <code>mapcell_map</code>, both on the <code>fn mapcell_map</code> itself,
and on its closure argument:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">--- INDEX/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gi">+++ WORKDIR/tock/kernel/src/lib.rs</span>
</span><span class='line'><span class="gu">@@ -2564,10 +2564,9 @@ use core::{mem, ptr, slice, str};</span>
</span><span class='line'>
</span><span class='line'> use crate::callback::{AppId, CallbackId};
</span><span class='line'> use crate::capabilities::ProcessManagementCapability;
</span><span class='line'><span class="gd">-fn mapcell_map&lt;T, F, R&gt;(closure: F) -&gt; Option&lt;R&gt; where F: FnOnce(&amp;mut T) -&gt; R</span>
</span><span class='line'><span class="gi">+fn mapcell_map&lt;T, F&gt;(closure: F) where F: FnOnce(&amp;mut T)</span>
</span><span class='line'> {
</span><span class='line'>     closure(None::&lt;&amp;mut T&gt;.unwrap());
</span><span class='line'><span class="gd">-    loop { }</span>
</span><span class='line'> }
</span><span class='line'>
</span><span class='line'> use crate::common::{Queue, RingBuffer};
</span></code></pre></td></tr></table></div></figure>


<p>We have now gotten ourself down to the following core set of methods:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">mapcell_map</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;</span><span class="p">(</span><span class="n">closure</span><span class="o">:</span> <span class="n">F</span><span class="p">)</span> <span class="n">where</span> <span class="n">F</span><span class="o">:</span> <span class="n">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">T</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">closure</span><span class="p">(</span><span class="nb">None</span><span class="o">::&lt;&amp;</span><span class="k">mut</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">.</span><span class="n">unwrap</span><span class="p">());</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">...</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">load_processes</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">(</span><span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">)</span> <span class="p">{</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="n">Process</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">chip</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="n">tasks</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="p">(),</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">trait</span> <span class="n">ProcessType</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span> <span class="k">loop</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">...</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">ProcessType</span> <span class="k">for</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">process_detail_fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span> <span class="n">writer</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">dyn</span> <span class="n">Write</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">mapcell_map</span><span class="p">(</span><span class="o">|</span><span class="n">config</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="o">&lt;&lt;</span><span class="n">C</span> <span class="k">as</span> <span class="n">Chip</span><span class="o">&gt;::</span><span class="n">MPU</span> <span class="k">as</span> <span class="n">MPU</span><span class="o">&gt;::</span><span class="n">MpuConfig</span><span class="o">|</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="p">.</span><span class="n">write_fmt</span><span class="p">(</span><span class="n">format_args</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">config</span><span class="p">));</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">...</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nb">None</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">process</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
theme: Eliminate Coupling
</span></p>

<a name="Technique:..Ret-ascription."></a>
<h2>Technique: &ldquo;Ret-ascription&rdquo;</h2>

<p>We could further reduce <code>Process::create</code> a tiny bit: We <em>can</em> remove
its return type, as long as we ensure that the coercion implied by the
return type still happens in the code.</p>

<p>This is a variant on <a href="#Technique:..Ret-elimination.">&ldquo;ret-elimination&rdquo;</a>: we again want to remove the return type from
the <code>fn</code> signature, but this time we will <em>also</em> ensure that any coercions implied
by the return type still occur:</p>

<p>Change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ReturnType</span> <span class="p">{</span> <span class="k">if</span> <span class="n">A</span> <span class="p">{</span> <span class="k">return</span> <span class="n">B</span><span class="p">;</span> <span class="p">}</span> <span class="n">TailReturn</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="o">----</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="n">A</span> <span class="p">{</span> <span class="kd">let</span> <span class="n">_</span><span class="o">:</span> <span class="n">ReturnType</span> <span class="o">=</span> <span class="n">B</span><span class="p">;</span> <span class="p">}</span> <span class="kd">let</span> <span class="n">_</span><span class="o">:</span> <span class="n">ReturnType</span> <span class="o">=</span> <span class="n">TailReturn</span><span class="p">;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>For <code>Process::create</code>, this looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span> <span class="n">Process</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[allow(clippy::cast_ptr_alignment)]</span>
</span><span class='line'>    <span class="n">crate</span> <span class="k">unsafe</span> <span class="k">fn</span> <span class="n">create</span><span class="p">(</span>
</span><span class='line'>        <span class="n">chip</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">,</span>
</span><span class='line'>    <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="k">mut</span> <span class="n">process</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nb">None</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="kd">let</span> <span class="n">_</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span> <span class="o">=</span> <span class="n">process</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And furthermore, we can apply <a href="#Tactic:..Deobjectification.">&ldquo;deobjectification&rdquo;</a> and
<a href="#Technique:..Param-elimination.">&ldquo;param-elimination&rdquo;</a> here; this method doesn&rsquo;t even have a <code>self</code>
parameter.</p>

<p>That <a href="https://github.com/pnkfelix/demo-minimization/commit/71c6e538854171b043b7628b15e4fe4f23a056a8">gets us here</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">load_processes</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">C</span><span class="p">)</span> <span class="p">{</span> <span class="n">process_create</span><span class="o">::&lt;</span><span class="n">C</span><span class="o">&gt;</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">process_create</span><span class="o">&lt;</span><span class="n">C</span><span class="o">:</span> <span class="k">&#39;static</span> <span class="o">+</span> <span class="n">Chip</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">_</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="n">dyn</span> <span class="n">ProcessType</span> <span class="o">=</span> <span class="nb">None</span><span class="o">::&lt;&amp;</span><span class="k">mut</span> <span class="n">Process</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;&gt;</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<a name="Take.a.breath"></a>
<h1>Take a breath</h1>

<p>Now that all of the involved methods seem relatively small, this seems like a good
time to take a breath.</p>

<p>At this point, we could try to take these pieces and build-up a new
example from scratch, preserving the core elements identified above.
That&rsquo;s not a bad idea at all, at this point; it could be worth
spending a half-hour or so on. Either building up an example from scratch
will work, or it won&rsquo;t. Let&rsquo;s assume for now that we are not able to jump
to a minimal example, even with the pieces we have identified as core to the problem
up above?</p>

<p>What now?</p>

<p>We could attempt to remove large swaths of code from the example as it stands:
After all, we know we just need these methods; can we just comment everything else out?</p>

<p>Well, no. You can&rsquo;t just comment random things out.
The interdependencies in
the crate graph will frustrate attempts to do so.</p>

<p>For example, I tried commenting out
most of the code after the <code>mod process { ... }</code>, in the <code>lib.rs</code>, and
got a slew of &ldquo;unresolved import&rdquo; errors. So, if you want to continue
reducing this exmaple, we need to do it in a more directed fashion.</p>

<p>In the interest of trying to follow a semi-mindless process here, lets look at what we
need to do in order to really minimize <code>kernel</code> to its core:</p>

<ol>
<li><p>We have to finish minimizing the leaves. There are crates unrelated to the ICE still
being pulled into the build here, and they rely on things in <code>kernel</code> that we will
not be able to remove until those crates are themselves reduced or otherwise eliminated
from the crate graph.</p>

<p>For us, we can apply some of the other techniques we have learned about to the leaf
crates, such as using <a href="#Technique:..None-defaulting.">&ldquo;none-defaulting&rdquo;</a> to create an instance of <code>arty_e21::chip::ArtyExx</code>
in <code>board/argy-e21/main.rs</code>.</p></li>
<li><p>We have to reducing the coupling within <code>kernel</code> itself. It can be maddening
trying to comment out modules at random. When that madness becomes too much for me,
I force myself to adopt a more disciplined
approach: I use the <a href="#Tactic:..Cut-spaghetti-imports.">&ldquo;cut-spaghetti-imports&rdquo;</a> tactic to replace the existing <code>use</code> imports
with local definitions. (Remember: since most <code>fn</code>-items in every module are
<a href="#Tactic:..Body.Loopification.">&ldquo;loopified&rdquo;</a>, the <a href="#Tactic:..Cut-spaghetti-imports.">&ldquo;cut-spaghetti-imports&rdquo;</a> tactic will work fairly often.</p></li>
<li><p>This goes hand-in-hand with the general point above about reducing coupling within <code>kernel</code>:
We have to finish mimimizing <code>mod process { ... }</code> itself within <code>kernel</code>.
All of the interesting functions for reproducing the bug live there, so we know
we cannot <a href="#Technique:..Cfgments.">&ldquo;cfgment&rdquo;</a> out that module for now. But if we have to keep <code>mod process</code>,
we won&rsquo;t be able to remove the other modules until we remove the dependencies that
it has on those modules.</p></li>
</ol>


<p>I hope to return to this richly-documented minimization of <a href="https://github.com/rust-lang/rust/issues/65774">rust-lang/rust#65774</a> the future;
and when I do, I hope to cover all three of the points above.</p>

<p>But for now, I hope this was a helpful tour of various minimization
technique that you can employ for reducing ICEs and other static
analysis bugs in <code>rustc</code>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Breaking News: Non-Lexical Lifetimes arrives for everyone]]></title>
    <link href="http://blog.pnkfx.org/blog/2019/06/26/breaking-news-non-lexical-lifetimes-arrives-for-everyone/"/>
    <updated>2019-06-26T12:54:29+02:00</updated>
    <id>http://blog.pnkfx.org/blog/2019/06/26/breaking-news-non-lexical-lifetimes-arrives-for-everyone</id>
    <content type="html"><![CDATA[<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
<em>Update 1 July 2019</em>: fixed bugs in <a href="#Closure.fixes"><code>EscapingWriter</code></a> and
<a href="#Fixed.leaking.into.Drop"><code>as_reader</code></a> examples.
<br></br>
<em>Update 8 July 2019</em>: fixed a new bug in <a href="#Fixed.leaking.into.Drop"><code>as_reader</code></a> example.
</span></p>

<p>Hey there everyone!</p>

<p>It has been literally years since I last posted to this blog.
I have been doing a bunch of Rust compiler work.
One big feature has been deployed: Non-Lexical Lifetimes (hereafter denoted &ldquo;NLL&rdquo;).</p>

<p>The motivation for this blog post: The next version of Rust, 1.36, is
going to have NLL turned on for the 2015 edition. Going forward,
all editions of Rust will now use NLL.
That is a big change.
It is mostly a change that empowers developers;
but it also is a change that will cause some existing code to break.</p>

<p>This post is going to talk a little bit about what NLL is and why you
as a Rust developer should be excited about it as a feature
(because it enables programmers to express themselves more directly).</p>

<p>However, even though the main feature of NLL is to <em>increase</em>
the set of programs that Rust accepts,
the vast majority of this post will focus on cases where the
switch to NLL has caused the compiler to start
rejecting<label for='soundness-as-a-feature' class='margin-toggle'> &#8853;</label><input type='checkbox' id='soundness-as-a-feature' class='margin-toggle'/><span class='marginnote'>Rejecting unsound code is also a Rust feature that I value highly; but it often fails to excite developers, especially when it causes their legacy code to stop compiling. </span>
code that it used to accept erroneously.</p>

<!-- more -->


<hr />

<p>A note on quality of content (or lack thereof):
After I wrote this post, feedback on <a href="https://www.reddit.com/r/rust/comments/c6hs2t/breaking_news_nonlexical_lifetimes_arrives_for/">reddit</a> and
the <a href="https://users.rust-lang.org/t/blog-post-breaking-news-non-lexical-lifetimes-arrives-for-everyone/29714">users forum</a> pointed out bugs in some of the examples
 below.</p>

<p>The bugs themselves leaked through because of three mistakes
I made in my own development process for this post.</p>

<ol>
<li>Failure to write comparative tests for all of my proposed &ldquo;fixes&rdquo;,</li>
<li>Failure to think about exception safety when writing <code>unsafe</code> code, and</li>
<li>Worst of all: Waited too long to start writing (and then rushed to finish).</li>
</ol>


<p>I will note each significant update (in the margin at the start of the post) as I post them.</p>

<script>
// See https://github.com/imathis/octopress/issues/424
$(document).ready(function(){
    $('body').addClass('collapse-sidebar');
});
</script>


<a name="Table.of.Contents"></a>
<h2>Table of Contents</h2>

<ul>
<li><a href="#Background:.What.is.NLL">Background: What is NLL</a></li>
<li><a href="#How.was.NLL.implemented">How was NLL implemented</a></li>
<li><a href="#NLL.uses.a.new.MIR.borrow-checker">NLL uses a new MIR borrow-checker</a></li>
<li><a href="#NLL.resolves.soundness.bugs">NLL resolves soundess bugs</a></li>
<li><a href="#NLL.deployment.and.the.migration.mode">NLL deployment and the migration mode</a></li>
<li><a href="#But.what.about.the.2015.edition.">But what about the 2015 edition?</a></li>
<li><a href="#What.are.the.soundness.issues.fixed.by.NLL.">What are the soundness issues fixed by NLL?</a>

<ul>
<li><a href="#Closure.fixes">Closure fixes</a></li>
<li><a href="#Match.fixes">Match fixes</a></li>
<li><a href="#Corrections.to.the.model.of.control-flow">Corrections to the model of control-flow</a></li>
<li><a href="#Fixed.leaking.into.Drop">Fixed leaking into Drop</a></li>
<li><a href="#The..liveness.check.">The &ldquo;liveness check&rdquo;</a></li>
<li><a href="#Outlawed.partial.assignment.to.moved.values..for.now.">Outlawed partial assignment to moved values (for now)</a></li>
</ul>
</li>
<li><a href="#Conclusion..Related.Posts..and.Thanks">Conclusion, Related Posts, and Thanks</a></li>
</ul>


<a name="Background:.What.is.NLL"></a>
<h2>Background: What is NLL</h2>

<p>NLL is a change to Rust&rsquo;s static model of <em>lifetimes</em>. Lifetimes are
approximations of the dynamic extent of values in a program. In
earlier versions of Rust, lifetimes had a close correspondence with
lexical scope.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>                               <span class="c1">// SCOPE TREE</span>
</span><span class='line'>                                          <span class="c1">//</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">names</span> <span class="o">=</span>                       <span class="c1">// +- `names` scope start</span>
</span><span class='line'>        <span class="p">[</span><span class="s">&quot;abe&quot;</span><span class="p">,</span> <span class="s">&quot;beth&quot;</span><span class="p">,</span> <span class="s">&quot;cory&quot;</span><span class="p">,</span> <span class="s">&quot;diane&quot;</span><span class="p">];</span> <span class="c1">// |</span>
</span><span class='line'>                                          <span class="c1">// |</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">alias</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>            <span class="c1">// | +- `alias` scope start</span>
</span><span class='line'>                                          <span class="c1">// | |</span>
</span><span class='line'>    <span class="o">*</span><span class="n">alias</span> <span class="o">=</span> <span class="s">&quot;alex&quot;</span><span class="p">;</span> <span class="c1">// &lt;------------------------ write to `*alias`</span>
</span><span class='line'>                                          <span class="c1">// | |</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// &lt;--------------- read of `names[0]`</span>
</span><span class='line'>                                          <span class="c1">// | |</span>
</span><span class='line'>                                          <span class="c1">// | +- `alias` scope end</span>
</span><span class='line'>                                          <span class="c1">// +- `name` scope end</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The above code would be rejected under the old lexical model: the
mutable-borrow <code>&amp;mut names[0]</code> from line 6 would last until the end of
the scope of <code>alias</code>. Since <code>alias</code> is declared at the top-most block
that forms the body of <code>fn main</code>, its scope lasts until the end of
that body, and so when you would try to compile this code, you would get an error like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>error[E0502]: cannot borrow `names[..]` as immutable because it is also borrowed as mutable
</span><span class='line'>  --&gt; src/main.rs:10:20
</span><span class='line'>   |
</span><span class='line'>6  |     let alias = &amp;mut names[0];
</span><span class='line'>   |                      -------- mutable borrow occurs here
</span><span class='line'>...
</span><span class='line'>10 |     println!(&quot;{}&quot;, names[0]);
</span><span class='line'>   |                    ^^^^^^^^ immutable borrow occurs here
</span><span class='line'>...
</span><span class='line'>14 | }
</span><span class='line'>   | - mutable borrow ends here
</span></code></pre></td></tr></table></div></figure>


<p>But this compilation error does not correspond to an actual
unsoundness in the code: the read of <code>names[0]</code> always comes after the
last write through the aliasing reference. This error is an artifact
of the old model of lifetimes that was tightly wedded to lexical
scopes.</p>

<p>With NLL, the Rust compiler internally represents the fact that the
mutable-borrow <code>&amp;mut names[0]</code> does not need to last all the way to
the end of the lexical scope of <code>alias</code>; the mutable-borrow only needs
to last until the final access through <code>alias</code> on line 6. This shorter
mutable-borrow no longer overlaps with the read-access of <code>names[0]</code>
on line 10, and thus the program is accepted by the compiler with NLL enabled.</p>

<p>You can see this in action by trying out the program in the Rust
<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=caa469acdfb3c093a9659bb6b4685a09">playpen</a>; this link defaults to the 2018 edition of Rust,
which has had NLL enabled ever since its official <a href="https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html#non-lexical-lifetimes">release</a>.</p>

<p>You can read more about the motivation for NLL, with several other examples, on
<a href="https://rust-lang.github.io/rfcs/2094-nll.html">Rust RFC 2094: NLL</a>.</p>

<a name="How.was.NLL.implemented"></a>
<h2>How was NLL implemented</h2>

<p>In Rust, the &ldquo;borrow checker&rdquo; is a static analysis dedicated to enforcing rules like:
 &ldquo;you cannot write through a shared reference&rdquo;,
 &ldquo;you cannot write through an aliased mutable reference&rdquo;, or
 &ldquo;references never outlive their data&rdquo;.</p>

<p>One crucial part of NLL&rsquo;s implementation was the switch from the
legacy AST borrow-checker to a new MIR borrow-checker.</p>

<a name="Background:.What.is.MIR"></a>
<h3>Background: What is MIR</h3>

<p>The Rust compiler works by parsing a program into an Abstract Syntax Tree (AST).</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Before MIR, we tried to lessen these issues via two abstractions, called &ldquo;Category, Mutabilty, Type&rdquo; (CMT) and &ldquo;ExprUseVisitor&rdquo; (EUV). These hid away AST semantic details and reduced an analysis&rsquo;s concerns to a relatively small set of semantic effects.
Translating to MIR and analyzing that directly has been a superior approach, from a developer-efficiency point of view. MIR is used by more systems within the compiler; thus, MIR&rsquo;s encoding and processing are subject to more compiler developers' scrutiny. This tends to expose bugs more readily. Furthermore, since analyses are operating directly on MIR structures that have a concrete semantics, there is a lower barrier for entry for new compiler  developers seeking to help with MIR-based analyses. The CMT and EUV abstractions, in my opinion, were one reason that AST borrow-checker development was considered a black art.
</span>
AST-based analyses can suffer from three issues:</p>

<ol>
<li><p>First, individual nodes in the AST for a Rust program can have a relatively complicated meaning.
 Examples: <code>recv.invoke()</code> may move or borrow <code>recv</code>, based on the method&rsquo;s signature;
 also, a <code>match</code> expression may move or borrow its input based on the form of pattern on the
 match arm that is executed.</p></li>
<li><p>Second, there are many different varieties of AST nodes, and the
 quality of an analysis may depend on handling all of them. Some
 nodes may have similar semantics (e.g. <code>if</code> and <code>if let</code> can be
 desugared to <code>match</code>), but leveraging such similarity is not
 trivial.</p></li>
<li><p>Third, the tree-structure of the AST does not directly mirror the control-flow of the
 program it represents. Any static analysis interested in the control-flow of an
 AST must build a model of that control-flow; analyses using that modeled control-flow
 take the risk that the modeled control-flow
 <em>diverges</em> from the actual control-flow that is actually implemented by the low-level code generator.
 This was a significant source of subtle bugs in the AST borrow-checker.</p></li>
</ol>


<p>These factors make it difficult to implement and maintain compiler analyses that operate on the AST itself.
This in turn put limits on our ambition when designing such analyses.</p>

<p>Our solution to this suite of problems,
which plagued many aspects of the Rust compiler,
was the introduction of MIR.</p>

<p>MIR is the &ldquo;Middle Intermediate Representation&rdquo; of a Rust program.</p>

<p>After doing some initial AST-based static analyses,
the compiler translates from the AST representation into MIR.
After this translation, subsequent static analyses operate on the MIR.</p>

<p>The MIR is designed to be able to express the semantics of the Rust program
via a smaller-set of basic constructs,
while also encoding the information needed to do static analyses such as type-checking.</p>

<p>The MIR representation is a graph structure that directly corresponds to the program control-flow.
All control-flow, such as loops, breaks, or panics from function invocations, are explicitly encoded.
Complicated AST nodes like <code>match</code> are translated into compositions of simpler MIR nodes.</p>

<p>Since each MIR node is simple, and there is a smaller set of them to consider,
many MIR analyses are easier to implement and maintain than their analogous AST analyses,
addressing the first two issues above.</p>

<p>Since MIR directly encodes the program control-flow,
there is less risk of divergence between the control-flow model and the actual runtime behavior,
addressing the third issue above.</p>

<p>You can read more about the motivations for MIR, which go beyond those
listed here, on <a href="https://rust-lang.github.io/rfcs/1211-mir.html">Rust RFC 1211: MIR</a>.</p>

<a name="NLL.uses.a.new.MIR.borrow-checker"></a>
<h2>NLL uses a new MIR borrow-checker</h2>

<p>As noted above, NLL uses a new borrow-checker that processes MIR rather than the AST.</p>

<p>The main motivation for developing NLL was improving the expressiveness of Rust as a language:
we wanted to enable developers to write code that more directly corresponded to their intuition about
when references were valid and whether aliasing might occur.
(It doesn&rsquo;t hurt that the new code was also more concise.)</p>

<p>Fundamentally, NLL requires operating on a control-flow graph
(that&rsquo;s what puts the &ldquo;non-lexical&rdquo; in &ldquo;non-lexical lifetimes&rdquo;).</p>

<a name="NLL.resolves.soundness.bugs"></a>
<h2>NLL resolves soundness bugs</h2>

<p>As noted above, there were a host of bugs in the old AST borrow-checker.
Unsound code was sometimes accepted by the compiler
because the AST borrow-checker was not reasoning correctly about the program&rsquo;s semantics.</p>

<p>Fixing such bugs was <em>not</em> a primary motivation for implementing NLL.
The fact that such bugs would be fixed effectively &ldquo;for free&rdquo; as a side-effect of operating on MIR
was considered a welcome side-benefit.</p>

<p>There was a social effect on development though, and it is probably worth noting:
Since we, the Rust compiler developers, knew that
the MIR borrow-checker was going to be the <em>primary borrow-checker</em> in the (relatively near) future,
there was <em>signficantly less</em> motivation to fix bugs in the (soon-to-be legacy) AST borrow-checker.</p>

<p>There are currently 8 issues in the Rust bug database that have been tagged as
soundness bugs that are <a href="https://github.com/rust-lang/rust/issues?utf8=%E2%9C%93&amp;q=is%3Aissue++label%3ANLL-fixed-by-NLL+label%3A%22I-unsound+%F0%9F%92%A5%22+"><code>NLL-fixed-by-NLL</code></a>.
The response from the compiler developers for these bugs has usually been
one of either &ldquo;it is not feasible to fix this in the AST borrow-checker&rdquo;
or &ldquo;it is not <em>worthwhile</em> to invest time fixing this in the AST borrow-checker.&rdquo;</p>

<p>To be clear: I am in favor of such a response.
Which is unsurprising, since I have been one of the main voices behind such responses.</p>

<p>But it did mean that such code was allowed to persist in the wild.
Let us dive into that now.</p>

<a name="NLL.deployment.and.the.migration.mode"></a>
<h2>NLL deployment and the migration mode</h2>

<p>NLL was a big change to the compiler. We knew it might suffer from latent bugs:
it might unexpectedly regress compile-times, or
it might incorrectly accept unsound code, or
it might incorrectly reject valid code as unsound.</p>

<p>Furthermore, as discussed in the previous section,
we knew there were instances of previously-accepted code that would be <em>correctly</em> rejected by NLL
as unsound
(due to soundness fixes introduced with MIR borrow-check).</p>

<p>So we knew that NLL could have a negative impact on the developer experience,
but we did not know what the scope of such an impact might be.
To reduce the risk here, we limited the initial deployment of the NLL feature solely
to Rust code targeting the <a href="https://doc.rust-lang.org/stable/edition-guide/rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html">2018 edition of the language</a>.
Rust crates that did not opt into using the 2018 edition
would still be checked by the old AST borrow-check, warts and all.</p>

<p>Furthermore, since we did not want our end users to hit a road-block
where an attempt to migrate a pre-existing crate from the 2015 edition to the 2018 edition
was stymied by borrow-check errors that they had never seen before,
we included a further safeguard: the <em>NLL migration mode</em>.</p>

<p>The idea behind the NLL migration mode is simple.
First run the MIR borrow-checker on the input crate (buffering any
diagnostics it issues as it runs);
if the code is accepted by the MIR borrow-checker, then borrow-checking is done.
If the MIR borrow-checker rejects the input crate, <em>don&rsquo;t</em> reject it yet;
ask the AST borrow-checker whether it would also reject the crate.
If the AST borrow-checker would accept the crate, then this represents a case
where NLL is rejecting code that the AST borrow-checker would have accepted.
The compiler assumes any such case is an instance of a pre-existing bug in the AST borrow-checker;
it then emits the previously-buffered diagnostics, <em>downgrading</em> any emitted errors to future-compatibility warnings.</p>

<p>The heart of this is that the end user still gets feedback about problems in their code,
but they can keep using their crates for the short-term.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
One more slight UX downside:
an end-user has to wait until both the MIR borrow-checker <em>and</em> the AST borrow-checker run
before seeing diagnostic feedback about errors in a given piece of code.
</span>
The main downsides of the NLL migration-mode are</p>

<ul>
<li><p>Soundness bugs in end-user crates might go unaddressed</p></li>
<li><p>The Rust developers cannot remove the legacy AST borrow-checker
code base. (But we cannot remove it until all editions are using NLL anyway.)</p></li>
</ul>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
If you are using the Nightly compiler and want to try turning off migration mode yourself,
you can use <code>#![feature(nll)]</code> to do so.
</span>
In the long-term, we do intend to turn off the migration mode.
With migration mode off, any errors issued by NLL will cause the compiler to reject the input crate,
regardless of what the AST borrow-checker used to say about it.
(We have not yet established a time-line for when the migration mode will be turned off.)</p>

<a name="But.what.about.the.2015.edition."></a>
<h2>But what about the 2015 edition?</h2>

<p>Now that the 2018 edition has been out for about six months, we have
gained more confidence in the quality of the code underpinning NLL,
and we are taking the next step: turning on NLL for the 2015 edition.</p>

<p>As I said at the start of this post, the next Rust release, 1.36, is
going to have NLL turned on for all crates, regardless of edition.</p>

<p>As you might have guessed, we are only turning on the NLL migration mode.
If a crate has been unknowingly taking advantage of some soundness bug
in order to be accepted by the AST borrow-check, the initial impact of NLL
on that crate should be limited to future-compatibility warnings.</p>

<a name="What.are.the.soundness.issues.fixed.by.NLL."></a>
<h2>What are the soundness issues fixed by NLL?</h2>

<p>At this point, you may have questions:</p>

<ul>
<li>&ldquo;Is my crate going to be affected by this?&rdquo;,</li>
<li>&ldquo;What do these warnings from NLL look like?&rdquo;, or</li>
<li>&ldquo;What should I do to address these warnings when I see them?&rdquo;</li>
</ul>


<p>As I already mentioned, there are currently 8 issues tagged as
<a href="https://github.com/rust-lang/rust/issues?utf8=%E2%9C%93&amp;q=is%3Aissue++label%3ANLL-fixed-by-NLL+label%3A%22I-unsound+%F0%9F%92%A5%22+">soundness bugs fixed by NLL</a>.</p>

<p>What I want to do in the rest of this post is show concrete examples of
known crates that ran afoul of one of these soundness bugs. My hope in each case is to
show a reduced example of real code that breaks the rules set by the borrow-checker,
explain why breaking that rule is bad,
and then show how one might resolve the problem exposed by the compiler.</p>

<a name="Closure.fixes"></a>
<h3>Closure fixes</h3>

<p>NLL fixes the handling of closures in various ways.</p>

<p>Here is an example reduced from (an outdated version of) the <code>bart</code> crate
(<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=0cfa8715b2b266970154b1d228bcb4d4">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">std</span><span class="o">::</span><span class="n">fmt</span><span class="o">::</span><span class="p">{</span><span class="bp">self</span><span class="p">,</span> <span class="n">Write</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">EscapingWriter</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="k">mut</span> <span class="n">Write</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="n">Write</span> <span class="k">for</span> <span class="n">EscapingWriter</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">buf</span><span class="o">:</span> <span class="o">&amp;</span><span class="kt">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fmt</span><span class="o">::</span><span class="nb">Result</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Sneaky use of String::split, capturing the separator:</span>
</span><span class='line'>        <span class="kd">let</span> <span class="k">mut</span> <span class="n">separator</span> <span class="o">=</span> <span class="sc">&#39;_&#39;</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="n">part</span> <span class="k">in</span> <span class="n">buf</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="p">{</span> <span class="n">separator</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="n">x</span> <span class="o">==</span> <span class="sc">&#39;&quot;&#39;</span> <span class="p">})</span> <span class="p">{</span>
</span><span class='line'>            <span class="bp">self</span><span class="p">.</span><span class="n">inner</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="n">part</span><span class="p">)</span><span class="o">?</span><span class="p">;</span>
</span><span class='line'>            <span class="k">match</span> <span class="n">separator</span> <span class="p">{</span>
</span><span class='line'>                <span class="sc">&#39;&quot;&#39;</span> <span class="o">=&gt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">inner</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="s">&quot;&amp;quot;&quot;</span><span class="p">),</span>
</span><span class='line'>                <span class="n">_</span> <span class="o">=&gt;</span> <span class="nb">Ok</span><span class="p">(()),</span>
</span><span class='line'>            <span class="p">}</span><span class="o">?</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="nb">Ok</span><span class="p">(())</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which now yields this diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0503]: cannot use `separator` because it was mutably borrowed
</span><span class='line'>  --&gt; src/lib.rs:12:17
</span><span class='line'>   |
</span><span class='line'>9  |         for part in buf.split(|x| { separator = x; x == &#39;&quot;&#39; }) {
</span><span class='line'>   |                     ------------------------------------------
</span><span class='line'>   |                     |         |     |
</span><span class='line'>   |                     |         |     borrow occurs due to use of `separator` in closure
</span><span class='line'>   |                     |         borrow of `separator` occurs here
</span><span class='line'>   |                     borrow later used here
</span><span class='line'>...
</span><span class='line'>12 |                 &#39;&quot;&#39; =&gt; self.inner.write_str(&quot;&amp;quot;&quot;),
</span><span class='line'>   |                 ^^^ use of borrowed `separator`
</span><span class='line'>   |
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<p>As the code notes, this was a sneaky use of <code>String::split</code>.
Too sneaky, in fact.
The closure passed to <code>buf.split</code> captures separator by <code>&amp;mut</code>-reference;
it <em>has</em> to for this code to &ldquo;work&rdquo;, since
the whole idea is to sneak in the mutable reference as a side-channel
for transmitting information out of the invocation of the closure.</p>

<p>The problem is that the closure ends up being stored in the <code>Split</code> iterator returned by the <code>split</code> call;
this is represented by the statement that the borrow is used by the invocation itself,
<code>buf.split(...)</code> that is highlighted and labeled &ldquo;borrow later used here&rdquo;.
Since the <code>Split</code> iterator is what is providing the inputs to this <code>for</code>-loop,
the <code>&amp;mut</code>-borrow of <code>separator</code> has to live <em>across</em> the body of the <code>for</code>-loop.</p>

<p>The Rust memory model does not allow you to have a <code>&amp;mut</code>-borrow alive
across other accesses to its data, so this is rejected by the MIR borrow-checker.
The compiler issues an error, which is downgraded above to a warning by the migration mode (due to the old buggy AST borrow-checker accepting the code as written).</p>

<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>The fact that <code>separator</code> is a local bound outside of the loop is a wart:
In my opinion, this code really wants
bind the specific separator it found for <em>each</em> iteration of the loop.</p>

<p>In this specific case, it seems like the <code>str</code> API is a bit impoverished;
I see many variants of the <code>split</code> method,
but I see none that let you extract each of the delimiters that matched the given pattern while also extracting the portions of the string that did not match.</p>

<p>My answer, at least for now, is probably to rewrite the loop using <a href="https://doc.rust-lang.org/std/primitive.str.html#method.match_indices"><code>match_indices</code></a> (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=6806bb295e057b0b4f4c0be543735a19">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">std</span><span class="o">::</span><span class="n">fmt</span><span class="o">::</span><span class="p">{</span><span class="bp">self</span><span class="p">,</span> <span class="n">Write</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">EscapingWriter</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">inner</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="k">mut</span> <span class="n">Write</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="n">Write</span> <span class="k">for</span> <span class="n">EscapingWriter</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">,</span> <span class="n">buf</span><span class="o">:</span> <span class="o">&amp;</span><span class="kt">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fmt</span><span class="o">::</span><span class="nb">Result</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="k">mut</span> <span class="n">last_index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">delim</span><span class="p">)</span> <span class="k">in</span> <span class="n">buf</span><span class="p">.</span><span class="n">match_indices</span><span class="p">(</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">==</span> <span class="sc">&#39;\&quot;&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="bp">self</span><span class="p">.</span><span class="n">inner</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="n">last_index</span><span class="p">..</span><span class="n">index</span><span class="p">])</span><span class="o">?</span><span class="p">;</span>
</span><span class='line'>            <span class="k">match</span> <span class="n">delim</span> <span class="p">{</span>
</span><span class='line'>                <span class="s">&quot;</span><span class="se">\&quot;</span><span class="s">&quot;</span> <span class="o">=&gt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">inner</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="s">&quot;&amp;quot;&quot;</span><span class="p">),</span>
</span><span class='line'>                <span class="n">_</span> <span class="o">=&gt;</span> <span class="nb">Ok</span><span class="p">(()),</span>
</span><span class='line'>            <span class="p">}</span><span class="o">?</span><span class="p">;</span>
</span><span class='line'>            <span class="n">last_index</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="bp">self</span><span class="p">.</span><span class="n">inner</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="n">last_index</span><span class="p">..])</span><span class="o">?</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="nb">Ok</span><span class="p">(())</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
A previously posted version of this code was untested, and
it mishandled the delimiter and <code>index</code> state;
this brings to mind this variation of an old adage:
&ldquo;Beware of bugs in this code; I have only proved it sound, not tried it.&rdquo;
</span>
The <a href="https://doc.rust-lang.org/std/primitive.str.html#method.match_indices"><code>match_indices</code></a> method works by returning
both the matched delimiter and the index where that delimiter
<em>started</em> in the given string.
This version of the code is still saving state outside of the loop:
it remembers the index where the previous delimiter <em>ended</em> (<code>index + 1</code>,
since in this case we are only matching against delimiters of length 1),
and then after each iteration of the loop, we write the portion
of the input that followed that delimiter (<code>buf[last_index..index]</code>).</p>

<p>You can read about other fixes to the handling of closures at the following issues:</p>

<ul>
<li><a href="https://github.com/rust-lang/rust/issues/53432">#53432 &ldquo;Bug: nested closure outlives borrowed value.&rdquo;</a></li>
</ul>


<a name="Match.fixes"></a>
<h3>Match fixes</h3>

<p>Another area that got a lot of scrutiny with the switch to MIR
borrow-check was the handling of <code>match</code> expressions.</p>

<p>Consider the following code (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=fc1a4fbfd1ed9ad0282c292afe64d5ac">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">extern</span> <span class="n">crate</span> <span class="n">crossbeam</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="o">&amp;</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">one</span> <span class="o">=</span> <span class="o">&amp;</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">x</span> <span class="o">=</span> <span class="nb">Some</span><span class="p">(</span><span class="n">zero</span><span class="p">);</span>
</span><span class='line'>    <span class="n">crossbeam</span><span class="o">::</span><span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">s</span><span class="o">|</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="k">ref</span> <span class="k">mut</span> <span class="n">y</span><span class="p">)</span> <span class="o">=</span> <span class="n">x</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">s</span><span class="p">.</span><span class="nb">spawn</span><span class="p">(</span><span class="n">move</span> <span class="o">|</span><span class="n">_</span><span class="o">|</span> <span class="p">{</span> <span class="o">*</span><span class="n">y</span> <span class="o">=</span> <span class="n">one</span><span class="p">;</span> <span class="p">});</span>
</span><span class='line'>            <span class="c1">//                 ~~~~~~~~~</span>
</span><span class='line'>            <span class="c1">//                     |</span>
</span><span class='line'>            <span class="k">match</span> <span class="n">x</span> <span class="p">{</span> <span class="c1">// &lt;---- DATA RACE on discriminant of `x`!</span>
</span><span class='line'>                <span class="nb">Some</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;saw some&quot;</span><span class="p">),</span>
</span><span class='line'>                <span class="nb">None</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;saw none&quot;</span><span class="p">),</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}).</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which now yields this diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0503]: cannot use `x` because it was mutably borrowed
</span><span class='line'>  --&gt; src/main.rs:13:17
</span><span class='line'>   |
</span><span class='line'>7  |     crossbeam::scope(|s| {
</span><span class='line'>   |                       - has type `&amp;crossbeam::thread::Scope&lt;&#39;1&gt;`
</span><span class='line'>8  |         if let Some(ref mut y) = x {
</span><span class='line'>   |                     --------- borrow of `x.0` occurs here
</span><span class='line'>9  |             s.spawn(move |_| { *y = one; });
</span><span class='line'>   |             ------------------------------- argument requires that `x.0` is borrowed for `&#39;1`
</span><span class='line'>...
</span><span class='line'>13 |                 Some(_) =&gt; println!(&quot;saw some&quot;),
</span><span class='line'>   |                 ^^^^^^^ use of borrowed `x.0`
</span><span class='line'>   |
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<p>Your first reaction, upon reading that, might be &ldquo;there is no use of
<code>x.0</code> there. That match is only looking at the discriminant that
differentiates <code>Option::Some</code> from <code>Option::None</code>, not the data held
in the <code>Some</code>.&rdquo;</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The initial version of the MIR borrow-checker actually made the same erroneous assumption here.
But the soundness checks performed by MIRI exposed the flaw in reasoning here; see <a href="https://github.com/rust-lang/rust/issues/56797">issue #56797</a>.
</span>
And indeed, the AST borrow-checker assumes that the discriminant for
an enum value is always stored at a memory location that is disjoint from the
fields of that enum variant.</p>

<p>But this assumption is not generally true; Rust is free to make use of
data fields to hold an enum discriminant. (The simplest example of
this: a <code>&amp;T</code> is always a non-null pointer value, and therefore we can
represent an <code>Option&lt;&amp;T&gt;::None</code> as null!)</p>

<p>This means that an access to the discriminant of an enum
<em>might</em><label for='freedom of discrimination' class='margin-toggle'> &#8853;</label><input type='checkbox' id='freedom of discrimination' class='margin-toggle'/><span class='marginnote'>I say &ldquo;might&rdquo; here because we want to maximize the freedom for future versions of the compiler in how it chooses to represent enum discriminants. </span>
access memory stored in the fields of the enum&rsquo;s variants.</p>

<p>In this case, the highlighted <code>Some(_)</code> labeled &ldquo;use of borrowed <code>x.0</code>&rdquo; is the
point where the discriminant (and thus the memory at the location of that field)
might be read. But that would be a data-race with the mutable borrow of
<code>x.0</code> that was stored in <code>y</code> and passed off to another thread.
The compiler issues an error (which is downgraded above to a warning by the migration mode).</p>

<p>In practice, what you&rsquo;re likely to see is a similar error on this variant of the above code (<a href="">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">extern</span> <span class="n">crate</span> <span class="n">crossbeam</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="o">&amp;</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">one</span> <span class="o">=</span> <span class="o">&amp;</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">x</span> <span class="o">=</span> <span class="nb">Some</span><span class="p">(</span><span class="n">zero</span><span class="p">);</span>
</span><span class='line'>    <span class="n">crossbeam</span><span class="o">::</span><span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">_</span><span class="o">|</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="k">ref</span> <span class="k">mut</span> <span class="n">y</span><span class="p">)</span> <span class="o">=</span> <span class="n">x</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">match</span> <span class="n">x</span> <span class="p">{</span>
</span><span class='line'>                <span class="nb">Some</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;saw some&quot;</span><span class="p">),</span>
</span><span class='line'>                <span class="nb">None</span> <span class="o">=&gt;</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;saw none&quot;</span><span class="p">),</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="o">*</span><span class="n">y</span> <span class="o">=</span> <span class="n">one</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}).</span><span class="n">unwrap</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which now yields this diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0503]: cannot use `x` because it was mutably borrowed
</span><span class='line'>  --&gt; src/main.rs:10:17
</span><span class='line'>   |
</span><span class='line'>8  |         if let Some(ref mut y) = x {
</span><span class='line'>   |                     --------- borrow of `x.0` occurs here
</span><span class='line'>9  |             match x {
</span><span class='line'>10 |                 Some(_) =&gt; println!(&quot;saw some&quot;),
</span><span class='line'>   |                 ^^^^^^^ use of borrowed `x.0`
</span><span class='line'>...
</span><span class='line'>13 |             *y = one;
</span><span class='line'>   |             -------- borrow later used here
</span><span class='line'>   |
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<p>This does not represent a data-race, but it does represent a violation
of the Rust memory model that is designed to prevent data races like
the one above.</p>

<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>One option is to change the code to avoid inspecting the discriminant a second time.
Another option is to reorganize the code so that the
final write to <code>*y</code> is guaranteed to precede the second match of <code>x</code>.</p>

<a name="Fixes.to.match.guards"></a>
<h4>Fixes to match guards</h4>

<p>Another instance of a problem with <code>match</code> that has been resolved by NLL is the handling of <em>match guards</em>.</p>

<p>Consider this code, reduced from the <a href="https://github.com/andreastt/htmlgrep">htmlgrep crate</a> (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=4246e291c64c2b3550a7f633bdbe85ca">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">Matches</span><span class="p">;</span>
</span><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">Options</span> <span class="p">{</span> <span class="n">separator</span><span class="o">:</span> <span class="n">char</span><span class="p">,</span> <span class="n">max</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">usize</span><span class="o">&gt;</span><span class="p">,</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span> <span class="n">Matches</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">count</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">usize</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">print_count</span><span class="p">(</span><span class="n">matches</span><span class="o">:</span> <span class="n">Matches</span><span class="p">,</span> <span class="n">opts</span><span class="o">:</span> <span class="n">Options</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">match</span> <span class="n">opts</span><span class="p">.</span><span class="n">max</span> <span class="p">{</span>
</span><span class='line'>        <span class="nb">Some</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">if</span> <span class="n">matches</span><span class="p">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">n</span> <span class="o">=&gt;</span> <span class="nb">print</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}{}&quot;</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">opts</span><span class="p">.</span><span class="n">separator</span><span class="p">),</span>
</span><span class='line'>        <span class="nb">Some</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">|</span> <span class="nb">None</span> <span class="o">=&gt;</span> <span class="nb">print</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}{}&quot;</span><span class="p">,</span> <span class="n">matches</span><span class="p">.</span><span class="n">count</span><span class="p">(),</span> <span class="n">opts</span><span class="p">.</span><span class="n">separator</span><span class="p">),</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The above code is accepted by AST borrow-check, but it has a huge mistake:
the <code>count</code> method takes <code>Matches</code> by value,
which means evaluating the first guard consumes it.
This code should <em>not</em> be allowed to invoke <code>matches.count()</code>
on the second match arm.</p>

<p>With NLL, we now see the following diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0382]: use of moved value: `matches`
</span><span class='line'>  --&gt; src/lib.rs:11:36
</span><span class='line'>   |
</span><span class='line'>8  | fn print_count(matches: Matches, opts: Options) {
</span><span class='line'>   |                ------- move occurs because `matches` has type `Matches`, which does not implement the `Copy` trait
</span><span class='line'>9  |     match opts.max {
</span><span class='line'>10 |         Some(n) if matches.count() &gt; n =&gt; print!(&quot;{}{}&quot;, n, opts.separator),
</span><span class='line'>   |                    ------- value moved here
</span><span class='line'>11 |         Some(_) | None =&gt; print!(&quot;{}{}&quot;, matches.count(), opts.separator),
</span><span class='line'>   |                                          ^^^^^^^ value used here after move
</span><span class='line'>   |
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>In this case, the code is just wrong. Either the <code>count</code> method should
be taking <code>&amp;self</code> rather tnan <code>self</code>, or it should calcuate
<code>matches.count()</code> once and save its value in a local variable before
entering the <code>match</code>.</p>

<hr />

<p>For further discussion of various bugs in borrow-checking <code>match</code> that are
resolved by NLL, see the following issues on the Rust repository:</p>

<ul>
<li><a href="https://github.com/rust-lang/rust/issues/27282">#27282 &ldquo;Can mutate in match-arm using a closure&rdquo;</a></li>
<li><a href="https://github.com/rust-lang/rust/issues/45045">#45045 &ldquo;binding-less matches on borrowed data are incorrectly allowed&rdquo;</a></li>
<li><a href="https://github.com/rust-lang/rust/issues/56797">#56797 &ldquo;Matching on an enum should read the entire enum&rdquo;</a></li>
</ul>


<a name="Corrections.to.the.model.of.control-flow"></a>
<h3>Corrections to the model of control-flow</h3>

<p>As mentioned above, one of the problems with AST borrow-check
is that it used an internal model of control-flow that could diverge from
the actual control-flow of the generated program.</p>

<!-- An easy example of this can be seen in this code from reduced from the [fractions_and_matrices][] crate on github.
[fractions_and_matrices]: https://github.com/AuroransSolis/fractions_and_matrices
git@github.com:AuroransSolis/fractions_and_matrices.git
-->


<p>An easy example of this can be seen in this code from the <a href="https://github.com/floriama/agents/">floriama/agents</a> crate on github
(<a href="https://github.com/floriama/agents/blob/4cbecde2dbb408266b94c1ac73aa7c2d405936f3/src/network.rs#L215">line permalink</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="bp">self</span><span class="p">.</span><span class="n">graph</span><span class="p">.</span><span class="n">node_payload_mut</span><span class="p">(</span><span class="n">i_idx</span><span class="p">).</span><span class="n">physics</span><span class="p">.</span><span class="n">pos</span> <span class="o">+=</span>
</span><span class='line'>    <span class="bp">self</span><span class="p">.</span><span class="n">graph</span><span class="p">.</span><span class="n">node_payload</span><span class="p">(</span><span class="n">i_idx</span><span class="p">).</span><span class="n">physics</span><span class="p">.</span><span class="n">vel</span><span class="p">.</span><span class="n">scale</span><span class="p">(</span><span class="n">dt</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>This used to be accepted, because the AST borrow-check used a
control-flow model that said <code>LHS += RHS</code> is evaluated like so:</p>

<ol>
<li>evaluate the right-hand side (RHS), putting its value into a temporary local.</li>
<li>evaluate the left-hand side (LHS),</li>
<li>call the <code>add_assign</code> method on the evaluated LHS, passing it the RHS.</li>
</ol>


<p>But that does not agree with the actual semantics of Rust.
Rust actually evaluates the LHS <em>before</em> the RHS and then performs the
<code>add_assign</code> invocation.</p>

<p>So you can probably now see the problem with the code above: the AST
borrow-check allows the immutable borrow for the evaluation of the RHS.
Such an immutable borrow does not need to outlive that evaluation.
Thus, if the RHS were evaluated first, then the immutable borrow
would not overlap the <code>&amp;mut</code>-borrow required for the evaluation of LHS.
But the LHS <em>is</em> evaluated first, and its <code>&amp;mut</code>-borrow does need to last
up through and including the invocation of <code>add_assign</code>.</p>

<p>Thus, the line of code above now issues the following diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0502]: cannot borrow `self.graph` as immutable because it is also borrowed as mutable
</span><span class='line'>   --&gt; src/network.rs:216:17
</span><span class='line'>    |
</span><span class='line'>215 |               self.graph.node_payload_mut(i_idx).physics.pos +=
</span><span class='line'>    |               ----------
</span><span class='line'>    |               |
</span><span class='line'>    |  _____________mutable borrow occurs here
</span><span class='line'>    | |
</span><span class='line'>216 | |                 self.graph.node_payload(i_idx).physics.vel.scale(dt);
</span><span class='line'>    | |_________________^^^^^^^^^^_________________________________________- mutable borrow later used here
</span><span class='line'>    |                   |
</span><span class='line'>    |                   immutable borrow occurs here
</span><span class='line'>    |
</span><span class='line'>    = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>    = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>




<!--
Even the simpler expression `LHS = RHS` has the same issue here:
the AST borrow-check models this as evaluating RHS before LHS,
but its actual behavior is that the LHS is evaluated first.

https://crater-reports.s3.amazonaws.com/pr-60914/try%23f45cc3094ee337acd688771b9234318046b0572d/gh/ethowitz.life/log.txt
-->


<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>In this case, the common fix is to do the evaluation of the RHS before the LHS, like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kd">let</span> <span class="n">rhs</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">graph</span><span class="p">.</span><span class="n">node_payload</span><span class="p">(</span><span class="n">i_idx</span><span class="p">).</span><span class="n">physics</span><span class="p">.</span><span class="n">vel</span><span class="p">.</span><span class="n">scale</span><span class="p">(</span><span class="n">dt</span><span class="p">);</span>
</span><span class='line'><span class="bp">self</span><span class="p">.</span><span class="n">graph</span><span class="p">.</span><span class="n">node_payload_mut</span><span class="p">(</span><span class="n">i_idx</span><span class="p">).</span><span class="n">physics</span><span class="p">.</span><span class="n">pos</span> <span class="o">+=</span> <span class="n">rhs</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This text is a bit blasé about the effort associated with transforming
<code>LHS += RHS</code> into <code>let rhs = RHS; LHS += rhs</code>
In fact, there were bugs we fixed in NLL that would have required a similar pattern
to be deployed widely across many code bases; namely, cases where one did <code>foo.mutate(&amp;*foo.field)</code>
would have been forced to be rewritten as <code>{ let rhs = &amp;*foo.field; foo.mutate(rhs) }</code>
We did realize that for NLL to be adopted in practice, we needed to continue accepting such code.
This is what motivated the introduction of two-phase borrows aka <a href="https://rust-lang.github.io/rfcs/2025-nested-method-calls.html">RFC 2025: &ldquo;nested method calls&rdquo;</a>.
</span>
Of course, you should verify that such a reordering is actually valid in each such case;
The fact that this code rewrite is not semantics-preserving in general is why we did not
just have the compiler do it for you behind the scenes.</p>

<hr />

<p>For further discussion of these issues with modeling control-flow, see</p>

<ul>
<li><p><a href="https://github.com/rust-lang/rust/issues/27868">#27868 &ldquo;Inconsistent evaluation order for assignment operations&rdquo;</a></p></li>
<li><p><a href="https://github.com/rust-lang/rust/issues/38899">#38899 &ldquo;borrowed referent of a <code>&amp;T</code> sometimes incorrectly allowed&rdquo;</a></p></li>
</ul>


<a name="Fixed.leaking.into.Drop"></a>
<h3>Fixed leaking into Drop</h3>

<p>Our next example is reduced from code found in the <a href="https://github.com/estebank/galvanize/blob/a9624a317d8664dced737b203d2712f4127eb90e/src/writer.rs#L121">galvanize</a> crate on github :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="nb">Reader</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">file</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="k">mut</span> <span class="n">F</span> <span class="p">}</span>
</span><span class='line'><span class="k">struct</span> <span class="nb">Writer</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;</span> <span class="p">{</span> <span class="n">file</span><span class="o">:</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="k">mut</span> <span class="n">F</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;</span> <span class="nb">Writer</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">as_reader</span><span class="p">(</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Reader</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kd">let</span> <span class="n">s</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">;</span>
</span><span class='line'>            <span class="n">s</span><span class="p">.</span><span class="n">finalize</span><span class="p">();</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nb">Reader</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">file</span><span class="p">)</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That looks pretty innocent, right?</p>

<p>Well, lets see what NLL has to say about it (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a0143f0e7bbf1bf0bfeb3eac4c6c8801">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0713]: borrow may still be in use when destructor runs
</span><span class='line'>  --&gt; src/lib.rs:12:21
</span><span class='line'>   |
</span><span class='line'>6  | impl&lt;&#39;a, F&gt; Writer&lt;&#39;a, F&gt; {
</span><span class='line'>   |      -- lifetime `&#39;a` defined here
</span><span class='line'>...
</span><span class='line'>12 |         Reader::new(self.file)
</span><span class='line'>   |         ------------^^^^^^^^^- returning this value requires that `*self.file` is borrowed for `&#39;a`
</span><span class='line'>13 |     }
</span><span class='line'>   |     - here, drop of `self` needs exclusive access to `*self.file`, because the type `Writer&lt;&#39;_, F&gt;` implements the `Drop` trait
</span><span class='line'>   |
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<p>Oh, yeah, I forgot to mention: there&rsquo;s an <code>impl Drop</code> on <code>Writer</code>, and that changes everything.</p>

<p>As the diagnostic explains, the destructor for <code>Writer</code> has exclusive access to its fields while it runs,
including the <code>&amp;mut</code> borrow in <code>self.file</code>.</p>

<p>Therefore we cannot just hand off <code>self.file</code> to the new <code>Reader</code> while also allowing the destructor to run;
that would violate Rust&rsquo;s aliasing rules for <code>&amp;mut</code>.</p>

<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>One approach is wrap an <code>Option</code> around the <code>&amp;mut F</code> reference in <code>Writer</code>, and swap in <code>None</code> in the <code>as_reader</code> method.
This is sort of a drag though, since it means all the other <code>Writer</code> methods end up checking for <code>None</code>, just because of this usage here.</p>

<p>You might have noticed that <code>as_reader</code> is already doing the same work that <code>drop</code> does (namely, call <code>finalize</code> on the writer).
So it would be nice if we could move the file out of <code>self</code> and then <code>mem::forget(self)</code> to prevent its destructor from running.
Unfortunately, that does not work: <code>mem::forget</code> still wants a fully-formed value for its input.</p>

<p>The previous idea <em>does</em> yield the basis for a valid second approach, though (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=8c49528676a43eff7a2dda5db0306f35">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">as_reader</span><span class="p">(</span><span class="k">mut</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Reader</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="p">,</span> <span class="n">F</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">s</span> <span class="o">=</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="bp">self</span><span class="p">;</span>
</span><span class='line'>        <span class="n">s</span><span class="p">.</span><span class="n">finalize</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">file</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">F</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ptr_f</span><span class="o">:</span> <span class="o">*</span><span class="kr">const</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">F</span> <span class="o">=</span> <span class="o">&amp;</span><span class="bp">self</span><span class="p">.</span><span class="n">file</span><span class="p">;</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">file</span><span class="o">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">F</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">ptr</span><span class="o">::</span><span class="n">read</span><span class="p">(</span><span class="n">ptr_f</span><span class="p">);</span>
</span><span class='line'>        <span class="n">std</span><span class="o">::</span><span class="n">mem</span><span class="o">::</span><span class="n">forget</span><span class="p">(</span><span class="bp">self</span><span class="p">);</span>
</span><span class='line'>        <span class="n">file</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="nb">Reader</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
An earlier version of this post wrapped the <code>&amp;mut F</code> in a <code>ManuallyDrop</code> in the definition of <code>struct Writer</code>, and called (the currently unstable) <a href="https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.take"><code>take</code></a> method to extract a copy of the reference. But this is not really an intended use of <code>ManuallyDrop</code>. After all, <code>&amp;mut F</code> has no destructor <em>itself</em>, so it was (at best) an awkward way to express the intent: store a local copy of the <code>self.file</code> reference before forgetting <code>self</code>. That intent is more clearly expressed via <code>ptr::read</code>.
</span>
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Another version called <code>ptr::read</code> after the <code>mem::forget</code>, but this is undefined behavior because <code>mem::forget(x)</code> <a href="https://doc.rust-lang.org/std/mem/fn.forget.html">might invalidate</a> pointers into the memory for <code>x</code>. The fix: call <code>ptr::read</code> before <code>mem::forget</code>.
</span>
This new version uses <a href="https://doc.rust-lang.org/std/ptr/fn.read.html"><code>ptr::read</code></a> to extract the file before forgetting <code>self</code>.
(This does require using <code>unsafe</code>, though.)</p>

<hr />

<p>For further discussion of how destructors interact with the
borrow-checking, see the following issues on the Rust repository:</p>

<ul>
<li><a href="https://github.com/rust-lang/rust/issues/31567">#31567 &ldquo;<code>Drop</code> and leaking <code>&amp;mut</code> references&rdquo;</a></li>
</ul>


<!--
### Corrections to handling of unions

 * [\#45157 "Borrow checker unsoundness with unions"][issue #45157]

### Corrections to handling of const-promoted expressions

 * [\#46557 "Compiler accepts return mut ref to local var on no longer valid stackframe"][issue #46557]

 * [\#49955 "Garbage value when accessing a reference into a field/element of a const value."][issue #49955]
-->




<!--
### Corrections to region-checking
Here is an example reduced from (an outdated version of) the `compare-version` crate.
--Nope, not sure this is something to advertise; see https://github.com/rust-lang/rust/issues/62185
-->


<a name="The..liveness.check."></a>
<h3>The &ldquo;liveness check&rdquo;</h3>

<p>The liveness check enforces the rule: &ldquo;any region which appears at the point P
must contain the point P.&rdquo;</p>

<p>The AST borrow-check did not actually enforce this
rule in all cases.</p>

<p>Here is an example reduced from an outdated version of the <code>enumflags2</code> crate (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=522815bfdc2bbaba98b6ab6673b93937">play</a>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">trait</span> <span class="n">RawBitFlags</span><span class="o">:</span> <span class="n">Copy</span> <span class="o">+</span> <span class="nb">Clone</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">Type</span><span class="p">;</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">flag_list</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="p">[</span><span class="n">Self</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="k">struct</span> <span class="n">BitFlags</span><span class="o">&lt;</span><span class="n">T</span><span class="o">:</span> <span class="n">RawBitFlags</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">val</span><span class="o">:</span> <span class="n">T</span><span class="o">::</span><span class="n">Type</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">:</span> <span class="n">RawBitFlags</span><span class="o">&gt;</span> <span class="n">BitFlags</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">iter</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="k">impl</span> <span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span> <span class="o">=</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">T</span><span class="o">::</span><span class="n">flag_list</span><span class="p">().</span><span class="n">iter</span><span class="p">().</span><span class="n">cloned</span><span class="p">()</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>which now yields this diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>warning[E0310]: the parameter type `T` may not live long enough
</span><span class='line'>  --&gt; src/lib.rs:13:22
</span><span class='line'>   |
</span><span class='line'>13 |     fn iter(self) -&gt; impl Iterator&lt;Item = T&gt; {
</span><span class='line'>   |                      ^^^^^^^^^^^^^^^^^^^^^^^
</span><span class='line'>   |
</span><span class='line'>   = help: consider adding an explicit lifetime bound `T: &#39;static`...
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span><span class='line'>
</span><span class='line'>warning[E0310]: the parameter type `T` may not live long enough
</span><span class='line'>  --&gt; src/lib.rs:14:9
</span><span class='line'>   |
</span><span class='line'>14 |         T::flag_list().iter().cloned()
</span><span class='line'>   |         ^^^^^^^^^^^^^^
</span><span class='line'>   |
</span><span class='line'>   = help: consider adding an explicit lifetime bound `T: &#39;static`...
</span><span class='line'>   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
</span><span class='line'>   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
</span></code></pre></td></tr></table></div></figure>


<p>Here, we see that the compiler is newly detecting a case that it had
previously missed, where the existential type returned by <code>iter</code> holds
instances of the type <code>T</code>.
The compiler wants the code to state up front that these values will
not carry any non-static references, because of the liveness rule:
since we do not have any constraint on where in this control-flow
this iterator will be used, any regions in its type must contain all
points in the control-flow.</p>

<p>This liveness rule was a change that Niko had spent some time
considering adding to the AST borrow-check as well, as documented in
<a href="https://github.com/rust-lang/rust/pull/55988">PR 55988: introduce &ldquo;type must be valid for&rdquo; into lexical region solver</a>.
In the end, he found a narrower fix that addressed the most serious cases,
and we ended up falling back on our default plan of letting the remaining bugs in this area
just get fixed with the migration to NLL.</p>

<hr />

<p>You can see further discussion of this on:</p>

<ul>
<li><a href="https://github.com/rust-lang/rust/issues/55756">#55756: Lifetimes bug on beta 1.31: the associated type may not live long enough</a></li>
</ul>


<a name="Outlawed.partial.assignment.to.moved.values..for.now."></a>
<h3>Outlawed partial assignment to moved values (for now)</h3>

<p>One last thing to mention that is <em>not</em> a soundness fix, but does break some AST borrow-check code in the wild.
The NLL system finally fixed a bug that was uncovered over four years ago.</p>

<p>Here&rsquo;s one of the instances I found of this bug, from the <code>epub</code> crate:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="p">...</span>
</span><span class='line'><span class="kd">let</span> <span class="n">arnode</span> <span class="o">=</span> <span class="n">Rc</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">RefCell</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">node</span><span class="p">));</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">current</span> <span class="o">=</span> <span class="n">parents</span><span class="p">.</span><span class="n">last</span><span class="p">();</span>
</span><span class='line'>    <span class="k">if</span> <span class="kd">let</span> <span class="nb">Some</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="o">=</span> <span class="n">current</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">c</span><span class="p">.</span><span class="n">borrow_mut</span><span class="p">().</span><span class="n">childs</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">arnode</span><span class="p">.</span><span class="n">clone</span><span class="p">());</span>
</span><span class='line'>        <span class="n">node</span><span class="p">.</span><span class="n">parent</span> <span class="o">=</span> <span class="nb">Some</span><span class="p">(</span><span class="n">Rc</span><span class="o">::</span><span class="n">downgrade</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>This now yields the following diagnostic:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="n">warning</span><span class="p">[</span><span class="n">E0382</span><span class="p">]</span><span class="o">:</span> <span class="n">assign</span> <span class="n">to</span> <span class="n">part</span> <span class="n">of</span> <span class="n">moved</span> <span class="n">value</span><span class="o">:</span> <span class="err">`</span><span class="n">node</span><span class="err">`</span>
</span><span class='line'>  <span class="o">--&gt;</span> <span class="n">src</span><span class="o">/</span><span class="n">xmlutils</span><span class="p">.</span><span class="n">rs</span><span class="o">:</span><span class="mi">68</span><span class="o">:</span><span class="mi">29</span>
</span><span class='line'>   <span class="o">|</span>
</span><span class='line'><span class="mi">53</span> <span class="o">|</span>                     <span class="kd">let</span> <span class="k">mut</span> <span class="n">node</span> <span class="o">=</span> <span class="n">XMLNode</span> <span class="p">{</span>
</span><span class='line'>   <span class="o">|</span>                         <span class="o">--------</span> <span class="n">move</span> <span class="n">occurs</span> <span class="n">because</span> <span class="err">`</span><span class="n">node</span><span class="err">`</span> <span class="n">has</span> <span class="k">type</span> <span class="err">`</span><span class="n">xmlutils</span><span class="o">::</span><span class="n">XMLNode</span><span class="err">`</span><span class="p">,</span> <span class="n">which</span> <span class="n">does</span> <span class="n">not</span> <span class="n">implement</span> <span class="n">the</span> <span class="err">`</span><span class="n">Copy</span><span class="err">`</span> <span class="k">trait</span>
</span><span class='line'><span class="p">...</span>
</span><span class='line'><span class="mi">62</span> <span class="o">|</span>                     <span class="kd">let</span> <span class="n">arnode</span> <span class="o">=</span> <span class="n">Rc</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">RefCell</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">node</span><span class="p">));</span>
</span><span class='line'>   <span class="o">|</span>                                                       <span class="o">----</span> <span class="n">value</span> <span class="n">moved</span> <span class="n">here</span>
</span><span class='line'><span class="p">...</span>
</span><span class='line'><span class="mi">68</span> <span class="o">|</span>                             <span class="n">node</span><span class="p">.</span><span class="n">parent</span> <span class="o">=</span> <span class="nb">Some</span><span class="p">(</span><span class="n">Rc</span><span class="o">::</span><span class="n">downgrade</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">));</span>
</span><span class='line'>   <span class="o">|</span>                             <span class="o">^^^^^^^^^^^</span> <span class="n">value</span> <span class="n">partially</span> <span class="n">assigned</span> <span class="n">here</span> <span class="n">after</span> <span class="n">move</span>
</span><span class='line'>   <span class="o">|</span>
</span><span class='line'>   <span class="o">=</span> <span class="n">warning</span><span class="o">:</span> <span class="n">this</span> <span class="n">error</span> <span class="n">has</span> <span class="n">been</span> <span class="n">downgraded</span> <span class="n">to</span> <span class="n">a</span> <span class="n">warning</span> <span class="k">for</span> <span class="n">backwards</span> <span class="n">compatibility</span> <span class="n">with</span> <span class="n">previous</span> <span class="n">releases</span>
</span><span class='line'>   <span class="o">=</span> <span class="n">warning</span><span class="o">:</span> <span class="n">this</span> <span class="n">represents</span> <span class="n">potential</span> <span class="n">undefined</span> <span class="n">behavior</span> <span class="k">in</span> <span class="n">your</span> <span class="n">code</span> <span class="n">and</span> <span class="n">this</span> <span class="n">warning</span> <span class="n">will</span> <span class="n">become</span> <span class="n">a</span> <span class="n">hard</span> <span class="n">error</span> <span class="k">in</span> <span class="n">the</span> <span class="n">future</span>
</span></code></pre></td></tr></table></div></figure>


<p>I freely admit that this <em>does not</em> represent undefined behavior of any
sort. The language design team&rsquo;s decision to outlaw this code was not based
on catching soundness errors; the motivation was for overall <a href="https://github.com/rust-lang/rust/issues/21232#issuecomment-427152371">consistency in the language</a>.</p>

<p>However, I do suspect that this often will catch a bug in the code when it arises. (For example, in this case: did the author actually intend to mutate the field on <code>arparent</code> intead?)</p>

<p>(The basic problem is that if you initialize a field of an
uninitialized struct, you currently cannot read from that field. So
doing such an initialization serves almost no purpose.)</p>

<a name="How.can.you.fix.this."></a>
<h4>How can you fix this?</h4>

<p>Your main options here are one of the following:</p>

<ol>
<li>stop writing to the fields in question, or</li>
<li>re-initialize the struct value before doing a write, or</li>
<li>restructure the code so that you use locals instead of a single struct.</li>
</ol>


<hr />

<p>For much further discussion of how we ended up outlawing this coding
construct, and some hypothetical plans for treating it more
respectfully in the future, see:</p>

<ul>
<li><p><a href="https://github.com/rust-lang/rust/issues/21232">#21232: borrow-checker allows partial reinit of struct that has been moved away, but no use of it.</a></p></li>
<li><p><a href="https://github.com/rust-lang/rust/issues/54986">#54986: NLL: Reject partial init of uninitialized record (struct or tuple)</a></p></li>
<li><p><a href="https://github.com/rust-lang/rust/issues/54987">#54987: Goal: Accept partial initialization + use of records created via such</a></p></li>
<li><p><a href="https://github.com/rust-lang/rust/issues/60450">#60450: assign to part of possibly uninitialized variable is flagged as UB (but only in 2018 edition)</a></p></li>
</ul>


<a name="Conclusion..Related.Posts..and.Thanks"></a>
<h2>Conclusion, Related Posts, and Thanks</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I might update this post in the future if I encounter other
significant regressions that are calling out to be documented in this
manner. But for now I am hoping that this list will suffice to entertain you all.
</span>
That&rsquo;s all of the AST borrow-check regressions that I had the stomach to try to categorize
in this post.</p>

<p>If you are interested in learning more about the technology underpinning NLL,
and the process we used to develop it over the course of <a href="https://github.com/rust-lang/rust/issues/6393">six years</a>, I highly
recommend Niko&rsquo;s <a href="http://smallcultfollowing.com/babysteps/categories/#NLL">series</a> of posts on the subject.</p>

<p>And, as you might be able to tell, there is still more work to be done!
For example, the original plans for NLL included a goal known in the NLL RFC as
<a href="https://rust-lang.github.io/rfcs/2094-nll.html#problem-case-3-conditional-control-flow-across-functions">Problem Case #3</a>. We ended up scaling back our ambitions
in order to ensure that we could deploy a viable product with the 2018 edition;
but that just means there is opportunity to add support for this case, and many
more, in future versions of the Rust compiler.</p>

<p>Having said that, doing the exercise of writing this post has made me appreciate
what a long journey we have had with getting NLL out the door. There have been
so many subtle problems to resolve, and so many great volunteers who stepped
up to the plate to assist us.
I want to give shout-outs specifically to the members, both new and old, of the NLL working group (aka WG-NLL):
qmx, davidtwco, lqd, matthewjasper, spastorino, and blitzerr.
We <em>literally</em> could not have done this without your help.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GC and Rust Part 2: The Roots of the Problem]]></title>
    <link href="http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/"/>
    <updated>2016-01-01T00:00:00-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem</id>
    <content type="html"><![CDATA[<p>This is the second in a series of posts will discuss why garbage
collection is hard, especially for Rust, and brainstorm about
solutions to the problems we face.</p>

<p>The <a href="http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/">previous post</a> wrote down some criteria for integration.
Now I want to delve into why satisfying those criteria is hard,
at least in Rust as it stands today.</p>

<!-- more -->




<script>
// See https://github.com/imathis/octopress/issues/424
$(document).ready(function(){
    $('body').addClass('collapse-sidebar');
});
</script>


<p>(The body of this post makes heavy use of client-side rendering,
because of author idiosyncrasies.  You may need to wait a moment while
the supporting Javascript loads.)</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/js_to_dot.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/gc_rendering.js" charset="utf-8"></script>


<a name="Simplifying.Assumptions"></a>
<h2>Simplifying Assumptions</h2>

<p>Let us make some assumptions, so that we can focus on why
this problem is still hard even <em>after</em> being somewhat simplified.</p>

<p>As previously discussed in <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/#how-gc-works">the proloque</a>, one can think of the
main program and the GC as <em>coroutines</em>. We will continue with that
mind set.</p>

<p>Let us assume (for now) that the main program will not be running
concurrently with the GC;<label for='no-concurrent-mutation' class='margin-toggle sidenote-number'></label><input type='checkbox' id='no-concurrent-mutation' class='margin-toggle'/><span class='sidenote'>This is certainly a significant assumption; in practice, to enforce this we would probably need to employ some sort of rendezvous protocol with gc-safepoints on every thread that might hold roots for a given GC Heap. (Of course, one might also satisfy this by directly adopting the coroutine model and also disallowing sharing of references into any one GC heap across multiple threads.) </span> or more specifically, the main program
thread(s) will not read or write any GC roots nor GC Heap-allocated
objects concurrently with the GC thread.</p>

<p>In addition, let us assume that in the context of the GC coroutine, no
mutator roots are live values in CPU registers;<label for='no-register-roots' class='margin-toggle sidenote-number'></label><input type='checkbox' id='no-register-roots' class='margin-toggle'/><span class='sidenote'>This assumption is mostly a convenience for the text below, so that instead of saying &ldquo;in live callee-save registers or on the stack&rdquo;, I can just say &ldquo;on the stack.&rdquo; Also, in practice, I do not know if many GCs actually handle this in a more &ldquo;clever&rdquo; fashion than just forcing such values to live on the stack during a root scan (though certainly <em>some</em> do support roots in registers). </span>
 in other words, all mutator register values that the GC might care about
will have been saved somewhere in a mutator stack frame
(and will be reloaded from those saved stack slots
before subsequent use by the mutator).</p>

<p>Again, these assumptions are <em>not</em> meant to be interpreted as specific
requirements of Rust&rsquo;s final solution for GC; instead, they describe a
simplified version of &ldquo;the GC integration problem&rdquo; that
I claim is <em>still</em> hard to solve for Rust in general.</p>

<p>Throughout most of this post, I will be discussing various data
structures to support GC activity. When providing concrete examples of
the runtime state, the goal will usually be to represent something analogous
to the following
fragment of an object graph (or some small variant thereof).</p>

<p id="running_example_graph"></p>




<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var o = object_record("O: StructZ", "<f0> field z (root)");
o.id = "O";
var x = object_record("X1", "...");
var y = object_record("Y", "...");
var x2 = object_record("X2", "...");
x.style = "rounded";
y.style = "rounded";
x2.style = "rounded";

var local_x = { id: "local_x", label: "local x: Gc&lt;X&gt; (root)", shape: "record" };
var local_y = object_record("StructY", "<f0> field y (root)");
var local_o = { id: "local_o", label: "local o = Box(O)", shape: "record" };

stack[1] = local_x;
stack[2] = local_y;
stack[3] = local_o;
local_x.ref = edge_from_to_ports(":e", ":id:nw", x);
local_y.ref = edge_from_to_ports(":f0", ":id", y);
local_o.box = edge_to_port(":id", o);

o.f0 = edge_from_to_ports(":f0", ":id:w", x);
rust_heap[0] = o;

gc_heap[2] = x;
gc_heap[3] = y;
gc_heap[4] = x2;

var objects = [stack, gc_heap, rust_heap];

stack.rank = "same";

post_objects("running_example_graph", objects, { rankdir:"LR", nodesep:0.2, no_dims: true, with_code: false });
</script>


<p>Instances of structured data are
shown with a label<label for='labels-for-presentation' class='margin-toggle sidenote-number'></label><input type='checkbox' id='labels-for-presentation' class='margin-toggle'/><span class='sidenote'>These labels are often a presentation artifact: they do not necessarily denote a header word in the memory itself. </span>
(<code>StructY</code>, <code>O: StructZ</code>, <code>X</code>, <code>Y</code>) that identifies the data and usually includes its type.</p>

<p>Often I will omit the type of a local variable or member (such as with
<code>o</code>, <code>y</code>, and <code>z</code> above). If I want to specify the type, I will do so via
type-ascription
syntax (e.g. <code>x: Gc&lt;X&gt;</code> above), and if I want to specify the particular
value given to a variable, I will use assignment syntax (e.g. <code>o = Box(O)</code> above).
(Note that the assigned value should always be redundant, since there
should also be an arrow linking to the assigned value in these diagrams.)</p>

<p>Values of type <code>Gc&lt;T&gt;</code> hold references to objects allocated on the GC Heap.
Every object on the GC Heap will have a label that is derived from the
type <code>T</code> and, if necessary, a numeric suffix to disambiguate between
multiple instances of <code>T</code> on the GC Heap.</p>

<p>I have denoted the <em>contents</em> of the objects on the GC Heap by
ellipses, because I am focusing in this post
solely on problems related to finding the roots;
the contents of the objects referenced by the roots, and the remaining
transitively reachable objects beyond them, are not important to us today.</p>

<p>Objects allocated on the Rust Heap will tend to be boxes owned by
values of type <code>Box&lt;T&gt;</code>; they will have an identifying label and the
type of the contents (e.g. <code>O: StructZ</code> above).</p>

<p>I will tend to present examples of structured data with trivial
structs that have one field; e.g. <code>StructY</code> has a single field <code>y</code>,
and likewise <code>StructZ</code> has just the field <code>z</code>. (Of course in real
programs there will be structs and arrays with multiple members, but single field
structs simplifies the diagrams here.)</p>

<a name="Rust.complicates.Root.Identification"></a>
<h2>Rust complicates Root Identification</h2>

<p>At some point, probably in response to a memory allocation request,
the GC is going to initiate a collection.</p>

<p>That requires traversing the root set of the main program, since those
roots will be the kernel that the GC uses to identify the reachable
objects.</p>

<p>What are the options for traversing the root-set?</p>

<a name="Do.we.need.to.solve.this.problem."></a>
<h3>Do we need to solve this problem?</h3>

<p>One approach is to &ldquo;define away the problem&rdquo;; one version of this I
<a href="#Interoperation.with.a..black.box..GC">previously described</a> is to
hide the root-set itself inside the black-box abstraction
that we are interoperating with, and expose only handles that
point to the roots.</p>

<p id="target_anchor_black_box_gc_1" class="fullwidth"></p>


<p>The key principle in this picture is that the GC is meant to be
completely isolated from the state of the main program; when it does a
collection, the GC just starts from the root-set hidden within the
<code>handles</code> in the GC-heap. It does not inspect any state in the boxes
labelled &ldquo;Stack&rdquo; nor &ldquo;Rust Heap.&rdquo;</p>

<p>But a big problem with this, that I failed to stress in my earlier
post, is that you now need to <em>manage</em> the hidden-root set stored in
the <code>handles</code> array.</p>

<p>In particular, in the above picture, every entry in <code>handles</code> maps to
exactly one <code>Handle</code> value on the &ldquo;Stack&rdquo; or &ldquo;Rust Heap.&rdquo; This leads
to some troubling questions.</p>

<ul>
<li><p>What happens when you clone the box referenced by the local variable <code>o</code>: does that need to create a new entry in the hidden <code>handles</code> array?</p></li>
<li><p>How about if you instead dropped <code>o</code> &ndash; does that clear the <code>handles</code> entry at index 2?</p>

<ul>
<li><p>If not, when/how will the root set be updated appropriately?</p></li>
<li><p>If so, are previously cleared entries reused? If so, how do you determine whether an entry is available for reuse &ndash; do you keep a mark-bit on each handle?</p></li>
</ul>
</li>
<li><p>This handle array maintenance sounds expensive, maybe
we should instead periodically scan the stack to look for pointers to handles &hellip;</p></li>
</ul>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Just to be clear: the joke here is that we are basically
suggesting layering our own semi-automated memory management system
on top of a third-party automated memory management system. We should be striving to
<em>reduce</em> our problems to smaller subproblems, not <em>reproducing</em> them.
</span>
&hellip; maybe we should rethink our overall approach here.</p>

<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };
var handles = object_record("handles", "<h2> Y | <h1> X | <h3> X");

var c = object_record("C", "<f0> Gc(X) | <f1> Box(O)");
c.style = "rounded";
var o = object_record("O: StructZ", "<f0> field z = Handle(2)");
o.id = "O";
var x = object_record("X", "...");
var y = object_record("Y", "...");
x.style = "rounded";
y.style = "rounded";
var local_x = { id: "local_x", label: "local x = Handle(1)", shape: "record" };
var local_y = { id: "local_y", label: "StructY | <f0> field y = Handle(0)", shape: "record" };
var local_o = { id: "local_o", label: "local o = Box(O)", shape: "record" };

o.f0 = edge_from_to_ports(":f0", ":h3", handles);

c.f0 = edge_from_to_ports(":f0", ":id", x);
c.f1 = edge_from_to_ports(":f1", ":id", o);

stack[1] = local_x;
stack[2] = local_y;
stack[3] = local_o;

rust_heap[0] = o;
gc_heap[0] = handles;
handles.x1 = edge_from_to_ports(":h1", ":id", x);
handles.y2 = edge_from_to_ports(":h2", ":id", y);
handles.x3 = edge_from_to_ports(":h3", ":id:sw", x);
local_x.handle = edge_to_port(":h1", handles);
local_y.handle = edge_from_to_ports(":f0", ":h2", handles);
local_o.box = edge_to_port(":id", o);
gc_heap[2] = x;
gc_heap[3] = y;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_black_box_gc_1", objects, { rankdir:"LR", nodesep:0.2, no_dims: true });
</script>


<a name="Scanning.the.Mutator.State"></a>
<h3>Scanning the Mutator State</h3>

<p>So let&rsquo;s assume we are <em>not</em> dealing with a complete black box;
instead, the main program (aka &ldquo;the mutator&rdquo;) and the GC are going
to collaborate in some more fundamental way.</p>

<p>In other words, let&rsquo;s assume that roots are allowed to leak outside of
the GC Heap and into the mutator; no more black-box.</p>

<p>Once we have roots floating around under the control of the mutator,
we need to talk about identifying those roots by inspecting/querying the mutator
state.</p>

<p>Some relevant issues to consider on this topic:</p>

<ul>
<li><p>Are all roots <em>precisely</em> identified as roots?</p></li>
<li><p>Where can the roots reside in the mutator? (Frames on the stack? Boxes on the Rust Heap?)</p></li>
<li><p>How is the GC informed about the location of the roots in the mutator?</p></li>
<li><p>How does the mutator itself access the roots?</p></li>
<li><p>What information might the mutator maintain on the behalf of the GC?</p></li>
<li><p>Might a given root&rsquo;s value (i.e. the address of the referenced
object on the GC Heap) be changed by the GC during the collection
(in other words, does the GC rule out <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/#pinning-support">pinning</a>)?</p></li>
</ul>


<p>Let&rsquo;s explore some of the problems associated with these
questions, especially how it relates to Rust.</p>

<a name="Are.roots.precisely.identified."></a>
<h2>Are roots precisely identified?</h2>

<p>The roots are somewhere in mutator-managed memory.
The GC will need to know the values held in those roots,
and possibly will need to update those values if the referenced
objects are moved in memory.</p>

<p>There are two basic options for root scanning: conservative or precise.</p>

<p>A <em>conservative</em> scan is needed when some of the values
might hold an actual root, but might also hold a false-positive.</p>

<p>This arises when, for example, there is not enough type information
available<label for='avail-types' class='margin-toggle sidenote-number'></label><input type='checkbox' id='avail-types' class='margin-toggle'/><span class='sidenote'>&ldquo;Not available&rdquo; can mean that that the information is absent; but it can also mean that it is <em>untrusted</em>. I discuss this further below. </span>
to know that a scanned word is meant to be interpreted by the mutator as an object
reference.</p>

<p>If there are any conservatively-scanned roots, the GC needs to
validate their values (e.g. by checking if it lies within one of the
ranges of addresses used for the objects allocated on the GC Heap),
and trace any object potentially referenced by such values.</p>

<p>An earlier discussion on &ldquo;<a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/#pinning-support">pinning</a>&rdquo; established that any object
referenced by a conservatively scanned root
cannot be moved by the GC.
Therefore, integrating with a GC that does not support object pinning
(such as a fully-copying collector)
will require we scan the roots precisely, not conservatively.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
One problem with ensuring that a word on the stack is precisely identified
is that it requires close cooperation with the compiler backend.
E.g. if the backend (LLVM in the case of <code>rustc</code>) is permitted to reuse a stack
slot for two values of different types (and disjoint extents) then
we need to take care that the GC knows whether the current value in that slot
is or is not a GC reference.
(LLVM is a very expressive backend, so it provides mechanisms to account for this scenario, but it is not automatic.)
</span>
A given word in memory can be <em>precisely</em> scanned
if we ensure that the root&rsquo;s location in memory is
unambiguously interpreted by the mutator as an object reference.
I will say that such a root can be
&ldquo;unambiguously classified&rdquo; only if such assurance is established.</p>

<p>Often the ability to classify a root unambiguously is derived from
static types, runtime type information, and global system invariants.</p>

<p>Where the roots might reside influences the design space for
unambiguous classification quite a bit.
For example, if all roots are members of heap-allocated objects, then
the allocator might embed a type-tag in the header of such an object,
or segregate objects into disjoint regions of memory based on that
type.</p>

<p>Therefore, we will explore the question of where roots reside next.</p>

<a name="Where.are.the.roots."></a>
<h2>Where are the roots?</h2>

<p>There are two components to the question &ldquo;where are the roots?&rdquo;:</p>

<ul>
<li><p>Where can roots <em>possibly</em> reside?</p></li>
<li><p>Where do the roots <em>actually</em> reside?</p></li>
</ul>


<p>The first bullet is a question about the system as a whole; it is a
question that we must answer as designers.</p>

<p>The second bullet is about encoding how the GC will look up the memory
addresses of the roots (potentially with the mutator&rsquo;s help) every
time it wants to initiate a root scan.</p>

<p>The two parts interact with each other, so we will address them both
somewhat simultaneously.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
This list is leaving out some other options,
such as <em>completely unconstrained</em>, where roots might live in memory
unknown to the both the GC and Rust runtime (I do not see a way this first option could work without
requiring programmers to instrument foreign code with calls to root registration
and deregistration functions),
or keeping the roots solely on a <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.5570">shadow stack</a>
with structure isomorphic to the actual stack, but not vulnerable
to disruption due to compiler code transformations (I am omitting
this second option since it is known to carry a significant performance penalty).
</span></p>

<p>Consider these options for locations where roots can reside:</p>

<ol>
<li><p><em>Constrained To Boxed Values</em>:
 Solely found embedded in boxed values on the Rust Heap.</p></li>
<li><p><em>Constrained To Stack</em>:
 Stored solely on the program stack, and</p></li>
<li><p><em>Rust-Managed But Otherwise Unconstrained</em>:
 Stored either on the stack or embedded in boxed values on Rust Heap.</p></li>
</ol>


<a name="Roots.Constrained.To.Boxed.Values..Option.1."></a>
<h3>Roots Constrained To Boxed Values (Option 1)</h3>

<p>If roots are <em>solely</em> stored in members of boxed values, then we might
store runtime-type metadata in an allocator-injected header.</p>

<p>This option is seductive: Adding a header via the runtime system&rsquo;s
<code>#[allocator]</code> crate could sidestep a significant amount of compiler
integration (maybe even all of it).</p>

<p>There are some interesting ideas to explore from that starting point,
such as collecting all such boxed values together in a linked list
whose head is known to the GC (and thus the answer to &ldquo;how does the
GC scan the roots?&rdquo; is just &ldquo;it walks the list&rdquo;<label for='list-maintenance' class='margin-toggle sidenote-number'></label><input type='checkbox' id='list-maintenance' class='margin-toggle'/><span class='sidenote'>Do not be fooled; it would not be that easy. In particular, properly maintaining such a list could complicate the interface between the mutator and the values holding the roots. </span>).</p>

<p>However,
constraining roots to solely live in members of boxed
values may not be feasible in Rust as it stands today.
For example, one is always free to move the instance of <code>T</code> out of a
<code>Box&lt;T&gt;</code>, deallocating the backing storage but moving the <code>T</code> into
another location, such as a stack-allocated local variable.</p>

<p>Let&rsquo;s look at the remaining two
approaches.</p>

<a name="Roots.Constrained.To.Stack..Option.2."></a>
<h3>Roots Constrained To Stack (Option 2)</h3>

<p>If roots can be stored directly on the stack (i.e. options 2 or 3 above),
then when the GC initiates a root scan, it will need to find those
roots.</p>

<p>This search of the stack can be guided by
&ldquo;stack maps&rdquo;:<label for='stack maps' class='margin-toggle sidenote-number'></label><input type='checkbox' id='stack maps' class='margin-toggle'/><span class='sidenote'>For details, see <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.56.1641">Compiler Support for Garbage Collection in a Statically Typed Language</a>, Diwan Moss and Hudson (1992). </span>
compiler-generated metadata providing a mapping from a
code address<label for='code-address' class='margin-toggle sidenote-number'></label><input type='checkbox' id='code-address' class='margin-toggle'/><span class='sidenote'>This mapping need not have an entry for <em>every</em> address from the program instruction stream; we can make do with just the addresses of <em>call-sites</em> into runtime routines that could cause a GC. </span>
to the set of stack slots<label for='stack-map-slot' class='margin-toggle sidenote-number'></label><input type='checkbox' id='stack-map-slot' class='margin-toggle'/><span class='sidenote'>More specifically, the offset in a stack frame of a slot, and any relevant type information needed by the GC the compiler opted to include. </span>
that hold values of interest.</p>

<p>However, restricting the roots to live solely on the stack may be
problematic for much the same reason that plagues the earlier idea of
restricting roots to boxed values: in Rust today, one is always free
to move instances of <code>T</code> from a stack-local slot into a member of a
boxed value.</p>

<p>In some circumstances, we might be able to counteract these
&ldquo;freedom of movement&rdquo; issues in a backwards-compatible manner with a compiler
plugin (lint) that analyzes the source and trys to flag any code might move a root
into an illegal location. (<a href="https://servo.org/">Servo</a> already uses <a href="https://blog.mozilla.org/research/2014/08/26/javascript-servos-only-garbage-collector/#custom-static-analysis">a lint like this</a>
for its integration with the Spidermonkey GC.)</p>

<p>Or, if we are willing to extend the language itself,
we might add marker trait <code>Immobile</code> that indicates
that values of such type <em>cannot</em> be
moved.<label for='hunh-moved' class='margin-toggle sidenote-number'></label><input type='checkbox' id='hunh-moved' class='margin-toggle'/><span class='sidenote'>Proper integration of <code>trait Immobile</code> would probably require a way type for type parameters to opt-out of the capability to be moved, e.g. via a <code>T: ?Moved</code> anti-bound, analogous to the <code>?Sized</code> anti-bound.<br></br>Yes, I just made up the term &ldquo;anti-bound.&rdquo; </span></p>

<p>But either of those options are just ways of enforcing a restriction,
and it will outlaw certain kinds of program composition.<label for='vec-composition' class='margin-toggle sidenote-number'></label><input type='checkbox' id='vec-composition' class='margin-toggle'/><span class='sidenote'>An easy example of this: If you want to be able to put a root as part of the element type in a <code>Vec&lt;T&gt;</code>, then that <code>T</code> has to be able to be moved (since expanding the capacity of a vec will require moving its contents from one backing buffer to another). </span></p>

<p>In practice, we simply may be better off lifting such restrictions
entirely. So, let us now consider our remaining option:
allowing roots to be embedded in values on the stack or boxed on the Rust Heap.</p>

<a name="Roots.are.Rust-Managed..But.Otherwise.Unconstrained..Option.3."></a>
<h2>Roots are Rust-Managed, But Otherwise Unconstrained (Option 3)</h2>

<p>Now we come to what is probably the most realistic option for Rust/GC integration:
allowing roots to reside anywhere that the Rust compiler or runtime knows about.</p>

<p>Arguably, I might well have <em>started</em> this discussion with this
approach, since it is by definition the most general of the three, and
thus if we <em>do</em> have a solution for it, then why not jump to it?</p>

<p>The reason I left it for last is that I suspect any design we adopt
for GC integration in Rust 1.x is going to require a hybrid of the
approaches described in the prior two sections (allocator-injected
metadata <em>and</em> stack maps), and therefore I wanted to outline them in
isolation, before I started mixing them together.</p>

<a name="GC:..Where.are.the.roots....Mutator:......"></a>
<h2>GC: &ldquo;Where are the roots?&rdquo;, Mutator: &ldquo;&hellip;&rdquo;</h2>

<p>If we assume that roots can be embedded in values either on the stack
or in boxes on the Rust Heap, then how will the GC find the roots when
it needs to scan them?</p>

<p>The support for the GC&rsquo;s root scanning capability can be seen as having three parts:</p>

<ol>
<li><p>What work does the GC itself do, on the fly, to determine the roots
when it needs them,</p></li>
<li><p>What work does the mutator do (if any) as it executes the
program<label for='mutator-work' class='margin-toggle sidenote-number'></label><input type='checkbox' id='mutator-work' class='margin-toggle'/><span class='sidenote'>&ldquo;Mutator work&rdquo; here includes code hidden in library functions the mutator calls, such as <code>#[allocator]</code> subroutines, or code automatically injected by the compiler, such read- or write-barriers. </span>
to support a potential root scan by the GC in a future, and,</p></li>
<li><p>What meta-data must be gathered and emitted by the compiler
to support root-scanning?</p></li>
</ol>


<p>One idea for enabling easy GC root traversal was mentioned earlier:
why not collect the roots together in a linked list structure?
Towards this goal, we might
consider maintaining an intrusive
 links forming a list of all roots.</p>

<p id="intrusive_list_of_roots"></p>




<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var o = object_record("O: StructZ", "<f0> field z (root) | <next> next_root = null");
o.id = "O";
var x = object_record("X", "...");
var y = object_record("Y", "...");
x.style = "rounded";
y.style = "rounded";

var local_x = object_record("local_x", "<f0> (root) | <next> next_root");
var local_y = object_record("StructY", "<f0> field y (root) | <next> next_root");
var local_o = { id: "local_o", label: "local o = Box(O)", shape: "record" };

stack[1] = local_x;
stack[2] = local_y;
stack[3] = local_o;

local_x.ref = edge_from_to_ports(":f0", ":id", x);
local_y.ref = edge_from_to_ports(":f0", ":id", y);
local_o.box = edge_to_port(":id", o);

o.f0 = edge_from_to_ports(":f0", ":id:sw", x);
rust_heap[0] = o;

gc_heap[2] = x;
gc_heap[3] = y;

root_head = object_record("roots", "<next> next_root");
var anonymous_xy = {id: "anonymous_xy", style:"invis", shape: "point"};

// gc_heap[0] = root_head;

root_head.next = edge_from_to_ports(":next", ":f0", local_x);
local_x.next = edge_from_to_ports(":next", ":f0", anonymous_xy);
local_x.next.arrowhead = "none";

anonymous_xy.ref = edge_to_port(":f0:w", local_y);
local_y.next = edge_from_to_ports(":next", ":f0", o);

// anonymous_yx.ref.constraint = "false";
// anonymous_yx.ref.arrowhead = "none";

stack.rank = "same";

// root_head.presentation = invisible_edge(anonymous_yx);
// local_y.presentation = invisible_edge(local_x);
// local_x.presentation = invisible_edge(anonymous_xy);
// stack[4] = anonymous_yx;

var objects = [stack, gc_heap, rust_heap, root_head];
post_objects("intrusive_list_of_roots", objects, { rankdir:"LR", nodesep:0.2, no_dims: true, with_code: false });
</script>


<p>This is an <em>intrusive</em> list because the pointers in the list are
pointing into the interiors of objects. This allows traversing the
list to be completely uniform (from the viewpoint of the GC,
it looks like nothing more than a linked list of pairs).
In this scenario, the GC does essentially <em>zero</em> work on-the-fly
to find the locations of the roots;
maintaining the list would become the reponsibility of the mutator as
it creates and moves values with embedded roots.</p>

<p>However, Rust today does not have good support for intrusive data structures (<a href="https://github.com/rust-lang/rfcs/issues/417">RFC Issue 417</a>).
The already-mentioned capability to move values freely, as well as the
capability to swap a pre-existing <code>T</code> with the value held beind a
<code>&amp;mut T</code> reference, are among the reasons that intrusive structures
are difficult today, since it changes the addresses associated
with objects, and thus requires updating of the interior links.</p>

<p>So, what other options do we have?</p>

<p>Having the GC traverse the memory of the call-stack, even with the assistance of a stack map
to provide precise type information, will not give us the locations of all the roots,
since some are located on the Rust Heap. A stack map cannot hold the addresses of the blocks
of memory dynamically allocated for a box on the heap.</p>

<p>However, the stack map <em>can</em> hold the type information for the local
variables, and that sounds promising: If we record that a local
variable <code>o</code> has type <code>Box&lt;Struct&gt;</code>, then treat the contents of the
box on the heap as owned by the stack, so that when we encounter <code>o</code>
during the stack scan, we can recursively scan the memory of the box,
using the type <code>Struct</code> to inform the scan about how to treat each of
the embedded members.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I have slightly modified the running example to show two instances
of the local <code>x</code> on the call-stack in separate frames, each corresponding
to a distinct (recursive) invocation of the function <code>fn f</code>.
<br></br>
This is just to bring home the point that the stack map info encodes
static information about the frame for a function (at a particular call-site),
and thus recursive invocations of the same function can potentially
reuse the same entry in the stack map.
</span></p>

<p id="stack_map_boxes"></p>




<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var frame0 = { id: "cluster_frame0", label: "frame0: fn f()", is_subgraph: true };
var frame1 = { id: "cluster_frame1", label: "frame1: fn g()", is_subgraph: true };
var frame2 = { id: "cluster_frame2", label: "frame2: fn h()", is_subgraph: true };
var frame3 = { id: "cluster_frame3", label: "frame3: fn f()", is_subgraph: true };

var o = object_record("O: StructZ", "<f0> field z (root) = Gc(X1)");
o.id = "O";
var x  = object_record("X1", "...");
var x2 = object_record("X2", "...");
var y = object_record("Y", "...");
x.style = "rounded";
x2.style = "rounded";
y.style = "rounded";

var local_x = { id: "local_x1", label: "local x (root) = Gc(X1)", shape: "record" };
var local_x2 = { id: "local_x2", label: "local x (root) = Gc(X2)", shape: "record" };

var local_y = object_record("StructY", "<f0> field y (root) = Gc(Y)");
var local_o = { id: "local_o", label: "local o = Box(O)", shape: "record" };

frame0[0] = local_x;
frame1[0] = local_y;
frame2[0] = local_o;
frame3[0] = local_x2;

// frame3[0].ref = { is_edge: true, target: frame2[0], ltail: frame3.id, lhead: frame2.id, constraint: false };
// frame2[0].ref = { is_edge: true, target: frame1[0], ltail: frame2.id, lhead: frame1.id, constraint: false };
// frame1[0].ref = { is_edge: true, target: frame0[0], ltail: frame1.id, lhead: frame0.id, constraint: false };

stack[0] = frame0;
stack[1] = frame1;
stack[2] = frame2;
stack[3] = frame3;

local_x.ref = edge_to_port(":id:nw", x);
local_x2.ref = edge_to_port(":id:sw", x2);
local_y.ref = edge_from_to_ports(":f0", ":id", y);
local_o.box = edge_to_port(":id", o);

o.f0 = edge_from_to_ports(":f0", ":id:w", x);
rust_heap[0] = o;

gc_heap[2] = x;
gc_heap[3] = y;
gc_heap[4] = x2;

var objects = [stack, gc_heap, rust_heap];

stack.rank = "same";

post_objects("stack_map_boxes", objects, { rankdir:"LR", nodesep:0.2, compound: true, no_dims: true, with_code: false });
</script>


<p>The principle is that when control shifts to the GC coroutine,
it walks through the stack backtrace, consulting the stack
map for each callsite.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>stack_map_info for callsite 0x0010_ABBA in fn f:
</span><span class='line'>  local x:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: Gc&lt;X&gt;
</span><span class='line'>
</span><span class='line'>stack_map_info for callsite 0x0020_BACA in fn g:
</span><span class='line'>  local _:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: StructY
</span><span class='line'>
</span><span class='line'>stack_map_info for callsite 0x0030_C0C0 in fn h:
</span><span class='line'>  local o:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: Box&lt;StructZ&gt;</span></code></pre></td></tr></table></div></figure>


<p>From the stack map, it finds the offsets of relevant local variables
within that stack frame, and the type information for those locals, so
that it knows when it needs to dereference an pointer to inspect a
block on the Rust Heap (such as the <code>Box(O)</code> in our running example).</p>

<p>The GC will need separate meta-data describing the layout of each
type, with the offset and type of each field of interest:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>type_map_info for type StructY:
</span><span class='line'>  field y:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: Gc&lt;Y&gt;
</span><span class='line'>
</span><span class='line'>type_map_info for type Box&lt;StructZ&gt;:
</span><span class='line'>  field 0:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: StructZ
</span><span class='line'>
</span><span class='line'>type_map_info for type StructZ:
</span><span class='line'>  field z:
</span><span class='line'>    offset: [...]
</span><span class='line'>    type: Gc&lt;X&gt;</span></code></pre></td></tr></table></div></figure>


<p>The boxed objects may themselves own other root-holding objects on the Rust Heap,
like so:</p>

<p id="nested_stack_map_boxes" class="fullwidth"></p>




<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var frame0 = { id: "cluster_frame0", label: "frame0: fn f()", is_subgraph: true };
var frame1 = { id: "cluster_frame1", label: "frame1: fn g()", is_subgraph: true };
var frame2 = { id: "cluster_frame2", label: "frame2: fn h()", is_subgraph: true };
var frame3 = { id: "cluster_frame3", label: "frame3: fn f()", is_subgraph: true };

var o = object_record("O: StructB", "<f0> field b (root) = Box(Z)");
o.id = "O";
var b = object_record("Z: StructZ", "<f0> field z (root) = Gc(X1)");
b.id = "B";
var x  = object_record("X1", "...");
var x2 = object_record("X2", "...");
var y = object_record("Y", "...");
x.style = "rounded";
x2.style = "rounded";
y.style = "rounded";

var local_x = { id: "local_x1", label: "local x (root) = Gc(X1)", shape: "record" };
var local_x2 = { id: "local_x2", label: "local x (root) = Gc(X2)", shape: "record" };

var local_y = object_record("StructY", "<f0> field y (root) = Gc(Y)");
var local_o = { id: "local_o", label: "local o = Box(O)", shape: "record" };

frame0[0] = local_x;
frame1[0] = local_y;
frame2[0] = local_o;
frame3[0] = local_x2;

// frame3[0].ref = { is_edge: true, target: frame2[0], ltail: frame3.id, lhead: frame2.id, constraint: false };
// frame2[0].ref = { is_edge: true, target: frame1[0], ltail: frame2.id, lhead: frame1.id, constraint: false };
// frame1[0].ref = { is_edge: true, target: frame0[0], ltail: frame1.id, lhead: frame0.id, constraint: false };

stack[0] = frame0;
stack[1] = frame1;
stack[2] = frame2;
stack[3] = frame3;

local_x.ref = edge_to_port(":id:w", x);
local_x2.ref = edge_to_port(":id:sw", x2);
local_y.ref = edge_from_to_ports(":f0", ":id", y);
local_o.box = edge_to_port(":id", o);

o.f0 = edge_from_to_ports(":f0", ":id:w", b);
b.f0 = edge_from_to_ports(":f0", ":id:nw", x);
rust_heap[0] = o;
rust_heap[1] = b;

gc_heap[2] = x;
gc_heap[3] = y;
gc_heap[4] = x2;

var objects = [stack, gc_heap, rust_heap];

stack.rank = "same";

post_objects("nested_stack_map_boxes", objects, { rankdir:"LR", nodesep:0.2, compound: true, no_dims: true, with_code: false });
</script>


<p>To find all the roots starting from the stack
in the presence of such ownership chains
(which may go through other types like <code>Vec</code>),
the GC will need to recursively traverse the boxes,
or otherwise enqueue them onto a worklist structure.
In principle, if we can prove that certain types never
transitively own roots, then the GC should be able to skip traversing
boxed data for such types.</p>

<p>Using the stack map and type map data to find all roots transitively
owned by the stack is a promising approach. What is the catch, if any?</p>

<a name="Unsafe.Pointers"></a>
<h2>Unsafe Pointers</h2>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The <code>from_raw</code> method that converts a <code>*mut T</code> to <code>Box&lt;T&gt;</code>
is unsafe, but <code>into_raw</code> is a safe method. Safe code
can always convert a <code>Box&lt;T&gt;</code> to a <code>*mut T</code>, and clients
expect it to also be reasonable to round-trip via <code>from_raw</code>.
</span>
What should we do about unsafe pointers <code>*mut T</code> and <code>*const T</code>.
For example, it is not uncommon for library code to convert
boxed data <code>Box&lt;T&gt;</code> to a <code>*mut T</code> or vice versa;
that is an ownership transfer.</p>

<p>I used <code>local o = Box(O)</code> above (where <code>o: Box&lt;StructB&gt;</code>),
but it is entirely possible that <code>o</code> has type <code>*mut StructB</code>.</p>

<p>Here are some options for how to handle unsafe pointers:</p>

<ul>
<li><p>Skip unsafe pointers during root scanning.</p>

<p>This seems almost certain to cause unsound behavior; as noted above,
transmuting <code>Box&lt;T&gt;</code> to <code>*mut T</code> is an ownership transfer, and if
<code>T</code> holds a root, then later code might access it. This means that
the roots owned by <code>T</code> need to be scanned, to keep their associated
objects on the GC Heap alive.</p></li>
<li><p>Punt the question: if a program uses GC, any use of unsafe pointers
(as local variables or as members of structures) needs some sort of
attribute or annotation that tells the GC how to interpret the value
held in the unsafe pointer.</p>

<p>This would be quite difficult to put into practice. <a href="http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/">Part 1</a>
included a <a href="http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/#modularity">&ldquo;Modularity&rdquo; goal</a>:</p>

<blockquote><p>A Rust program that uses GC should be able to link to a crate
whose source code was authored without knowledge of GC.</p></blockquote>

<p>Requiring annotations on
every use of unsafe pointers means sacrificing this goal.</p></li>
<li><p>Treat unsafe pointers as potential root owners: Traverse them
and use their type as the basis for the scan.</p>

<p>This seems like the most reasonable option. But, can the types
of unsafe pointers be trusted?</p></li>
</ul>


<a name="Is.the.meta-data.trustworthy."></a>
<h2>Is the meta-data trustworthy?</h2>

<p>We assumed the existence of stack and type maps.
But where do they come from?</p>

<p>These maps need to be generated by the <code>rustc</code> compiler; after all,
they rely on low-level details of the generated code, such as the
offsets of fields within types, the offsets of local variables in a
stack frame, or the addresses of function call-sites.</p>

<p>The <code>rustc</code> compiler, in turn, is going to generate the information
based on the source code text. So far, so good.</p>

<p>Here&rsquo;s the rub: we assumed that the stack map will tell us the types
we need for all local variables of interest for all frames on the call
stack.</p>

<p>But in practice, a value can be <em>cast</em> to a different type.</p>

<p>In particular, in today&rsquo;s Rust 1.x, it is considered <em>safe</em> to cast
between <code>*mut T</code> and <code>*mut U</code> for any <code>T</code> and <code>U</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">b</span> <span class="o">=</span> <span class="n">Box</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="s">&quot;peanut butter&quot;</span><span class="p">);</span> <span class="c1">// (imagine if this held rooted data)</span>
</span><span class='line'>    <span class="kd">let</span> <span class="k">mut</span> <span class="n">p</span> <span class="o">=</span> <span class="n">Box</span><span class="o">::</span><span class="n">into_raw</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">pb</span> <span class="o">=</span> <span class="n">p</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="n">String</span><span class="p">;</span> <span class="c1">// bogus type, but safe</span>
</span><span class='line'>    <span class="n">p</span> <span class="o">=</span> <span class="n">Box</span><span class="o">::</span><span class="n">into_raw</span><span class="p">(</span><span class="n">Box</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="s">&quot;jelly&quot;</span><span class="p">));</span>
</span><span class='line'>    <span class="c1">// this is where a potential GC would be worrisome</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;p: {:?} p2: {:?}&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">pb</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// (just demonstrating recovery of original value via unsafe code)</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">pb</span> <span class="o">=</span> <span class="n">pb</span> <span class="k">as</span> <span class="o">*</span><span class="k">mut</span> <span class="o">&amp;</span><span class="n">&#39;static</span> <span class="kt">str</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">recover</span> <span class="o">=</span> <span class="k">unsafe</span> <span class="p">{</span> <span class="n">Box</span><span class="o">::</span><span class="n">from_raw</span><span class="p">(</span><span class="n">pb</span><span class="p">)</span> <span class="p">};</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;recovered: {:?}&quot;</span><span class="p">,</span> <span class="n">recover</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a real problem, in terms of the goals we have set up for ourselves.
100% modular GC requires that we be able to link with code that does things
like the above with the owners of its roots, and that includes when the roots
are indirectly held in boxes on the Rust Heap.</p>

<p>We may be able to add constraints on the <code>Gc&lt;T&gt;</code> type to prevent such things
from occurring when the types are apparent (e.g. when one is working with a
local variable of type <code>Gc&lt;T&gt;</code>). But in general, the types will
not be apparent to the code performing the cast; in particular,
we would still need to address type-parametric code that performs
such casts of unsafe pointers.</p>

<a name="Solutions"></a>
<h2>Solutions</h2>

<p>What can we do about these problems?</p>

<p>One obvious response to the untrustworthy meta-data problem would be to change the language and make casts from <code>*T</code> to <code>*U</code>
<em>unsafe</em>.<label for='unsafe-casts' class='margin-toggle sidenote-number'></label><input type='checkbox' id='unsafe-casts' class='margin-toggle'/><span class='sidenote'>Indeed, we may make such casts unsafe anyway; nmatsakis has said during informal conversation that he is not sure why we classified such casts as safe in the first place. </span>
 This would deal with the problem at a surface level, in the sense that
we would be able to at least allow a program using GC to link to a
GC-oblivious crate if the latter crate did not use any <code>unsafe</code>
blocks.
But it would not be terribly satisfactory; we want Rust&rsquo;s
solution for GC to be able to link to as many crates as possible, and
ruling out all code that does any cast of an unsafe pointer seems quite limiting.</p>

<p>We could also revise the set of goals, e.g. scale back our ambitions
with respect to compositionality, and return to ideas like having the
roots constrained to stack, as <a href="#Roots.Constrained.To.Stack..Option.2.">discussed above</a>.</p>

<p>An alternative solution I have been considering is to try to adopt a
hybrid approach for root scanning: use stack maps for the local
variables, but also have the allocator inject tracing meta-data onto
the objects allocated on the Rust Heap, and do a kind of conservative
scanning, but <em>solely</em> for finding roots embeded in objects on the
Rust Heap. This way, unsafe casts might become irrelevant: when
encountering <em>any</em> native pointer (e.g. <code>*mut u8</code>), we would ignore
the referenced type and instead look up whether it is an object on the
Rust Heap, and if so, extract the allocator-injected tracing
information.</p>

<p>I plan to dive more deeply into discussing solutions in a follow-up post.
This post is already quite long, but more importantly, I want to get some
concrete data first on the overheads imposed by the metadata injected during
allocation in state of the art conservative GC&rsquo;s like <a href="http://www.hboehm.info/gc/">BDW</a>.</p>

<hr />

<p>Oh, and finally (but completely unrelated): Happy 2016 to all the hackers out there!
Hope that you copied over all your live objects from 2015!</p>

<script>
// ## References
//
// * [On LLVM’s GC Infrastructure][on-llvms-gc]
//
// * [Compiler Support for Garbage Collection in a Statically Typed Language][diwan-moss-hudson]
</script>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Surfaces and Signatures: Component Privacy versus Dependence]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/12/19/signatures-and-surfaces-thoughts-on-privacy-versus-dependency/"/>
    <updated>2015-12-19T22:30:00+01:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/12/19/signatures-and-surfaces-thoughts-on-privacy-versus-dependency</id>
    <content type="html"><![CDATA[<p>I have had some thoughts on what <em>privacy</em> is used for in programming
languages, and how it differs from the notion of <em>dependence</em> between
modules (or at least compilation units) in a language like Rust.
And I thought I should share.</p>

<!-- more -->


<p>I have been working on an
RFC<label for='arr-eff-what' class='margin-toggle sidenote-number'></label><input type='checkbox' id='arr-eff-what' class='margin-toggle'/><span class='sidenote'><a href="https://github.com/rust-lang/rfcs/">Request For Comment</a>: A document used to propose significant changes to the Rust language or standard library. </span>
meant to increase the expressiveness of Rust&rsquo;s privacy construct
(the <code>pub</code> modifier), and in the process hopefully simplify the mental
model for what privacy means there.</p>

<p>However, I kept finding myself diving into regressions in my draft RFC
document: idealized hypothetical semantics for privacy, and
discussions of what motivates different aspects of that semantics.</p>

<p>Eventually I realized that such text was going to really bog down the
RFC itself (which is meant to describe a relatively simple language
change);
so I decided it was time for a blog
post<label for='gc-posts' class='margin-toggle sidenote-number'></label><input type='checkbox' id='gc-posts' class='margin-toggle'/><span class='sidenote'>Yes, I know that I also am overdue for the next chapter in my <a href="http://blog.pnkfx.org/blog/categories/gc/">GC blog post series</a>; it is coming. </span>,
if for no other reason than to provide a place for me to cut-and-paste
all those digressions.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Bugs including:
&ldquo;Trait re-exports fail due to privacy of containing module&rdquo; (<a href="https://github.com/rust-lang/rust/issues/18241">#18241</a>),
&ldquo;Rules governing references to private types in public APIs not enforced in impls&rdquo; (<a href="https://github.com/rust-lang/rust/issues/28325">#28325</a>)
&ldquo;Type alias can be used to bypass privacy check&rdquo; (<a href="https://github.com/rust-lang/rust/issues/28450">#28450</a>),
&ldquo;Private trait&rsquo;s methods reachable through a public supertrait&rdquo; (<a href="https://github.com/rust-lang/rust/issues/28514">#28514</a>),
&ldquo;Non-exported type in exported type signature does not error&rdquo; (<a href="https://github.com/rust-lang/rust/issues/29668">#29668</a>),
</span>
There are a number of bugs that have been filed against the privacy
checking in Rust; some are simply implementation issues, but the
comment threads in the issues make it clear that in some cases,
different people have very different mental models about how privacy
interacts with aliases (e.g. <code>type</code> declarations) and re-exports.</p>

<p>The existing privacy rules in Rust try to enforce two things:</p>

<ol>
<li><p>When an item references a path, all of the names on that path need to
be visible (in terms of privacy) in the referencing context, and,</p></li>
<li><p>Private items should not be exposed in the surface of public API&rsquo;s.</p></li>
</ol>


<p>One might reasonably ask: What do I mean by &ldquo;visible&rdquo;, or &ldquo;surface&rdquo;?</p>

<p>For Rust today, &ldquo;visible&rdquo; means &ldquo;either (1.) public, via <code>pub</code>, (2.)
defined in the current module, or (3.) defined in a parent of the
current module.&rdquo;</p>

<p>But &ldquo;surface&rdquo; is a bit more subtle, and before we discuss it, I want
to talk a bit about the purpose of &ldquo;visibility&rdquo; in the first place.</p>

<a name="Digression:.a.dependence.need.not.be.visible"></a>
<h2>Digression: a dependence need not be visible</h2>

<p>In a hypothetical idealized programming language (<em>not</em> Rust), and
under a particularly extreme reading of the term &ldquo;private&rdquo;, changes to
definitions that are private to one module would have no effect on the
validity of pre-existing uses from other modules. Another way of
looking at this: changes to private definitions in one compilation
unit would not require other compilation units to be recompiled, and
will not cause programs that previously type-checked to stop
type-checking.</p>

<p>One form of this ideal is the following:</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<div id="extreme_private_calls"></div>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent"; node [shape="rect"]; subgraph cluster_1 { fn_a [label="pub fn a()"]; label="unit1"; } subgraph cluster_2 { fn_b [label="pub fn b()"]; fn_c [label="fn c()"]; fn_b -> fn_c [label="calls"]; label="unit2"; } fn_a -> fn_b [label="calls"]; }';
    var elem = document.getElementById("extreme_private_calls");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>In this picture, one can see that the <code>fn c()</code> is a private component
of &ldquo;unit2&rdquo;: it may just be an implementation detail of the body of
<code>pub fn b()</code>, that the author of &ldquo;unit2&rdquo; can revise at will or
eliminate entirely, without requiring any changes to &ldquo;unit1&rdquo;
downstream.</p>

<p>A problem arises when one sees other kinds of composition, at least in
language like Rust, where values are directly embedded into their
containers.  For example, instead of function calls, imagine type
definitions:</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<div id="extreme_private_types"></div>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent"; node [shape="rect"]; subgraph cluster_1 { struct_a [label="pub struct A { \\l    b: unit2::B \\l}\\l"]; label="unit1"; } subgraph cluster_2 { struct_b [label="pub struct B { \\l    c: C \\l}\\l"]; struct_c [label="struct C {\\l    x: i32,\\l    y: i32\\l}\\l"]; label="unit2"; } struct_a -> struct_b [label="uses"]; struct_b -> struct_c[label="uses", constraint=false] }';
    var elem = document.getElementById("extreme_private_types");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In many other languages (e.g. Java, ML, Scheme), such
changes do not require recompiling the downstream crate, because
the members of structural types are just <em>references</em> to other heap-allocated
values, rather than being directly embedded in the allocated structure.
</span>
In this situation, even though the <code>struct C</code> is not publicly
accessible outside of &ldquo;unit2&rdquo;, changes to <code>struct C</code> will still
require the downstream &ldquo;unit1&rdquo; to be recompiled (because the contents
of <code>struct A</code>, and thus its size in bytes, may have changed along with
<code>struct C</code>).</p>

<p>So, what does it <em>mean</em> that <code>C</code> is &ldquo;private&rdquo;, if there is still a
dependence from the contents of &ldquo;unit1&rdquo; on the supposedly private
definition of <code>struct C</code>?</p>

<p>My answer to this is to distinguish between <em>visibility</em> versus <em>dependency</em>.</p>

<p>In the above picture, <code>struct A</code> in &ldquo;unit1&rdquo; has a dependence on the
definition of <code>struct C</code> in &ldquo;unit2&rdquo;. But <code>struct C</code> remains
<em>invisible</em> to <code>struct A</code>, in the sense that one cannot actually write
a direct reference to that type in the context of &ldquo;unit1.&rdquo;</p>

<a name="What.is.visibility.for."></a>
<h2>What is visibility for?</h2>

<p>Some basic definitions: An item is just as it is declared in the Rust
<a href="https://doc.rust-lang.org/reference.html#items">reference manual</a>: a component of a crate, located at a fixed path
(potentially at the &ldquo;outermost&rdquo; anonymous module) within the module
tree of the crate.</p>

<p>Every item can be thought of as having some hidden implementation
component(s) along with an exposed surface API.</p>

<p>So, for example, in:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">pub</span> <span class="k">fn</span> <span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="o">:</span> <span class="n">Input</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Output</span> <span class="p">{</span> <span class="n">Body</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>the surface of <code>fn foo</code> includes <code>Input</code> and <code>Output</code>, while the <code>Body</code> is
hidden.</p>

<p>What I would like is to establish the following
invariant<label for='inv' class='margin-toggle'> &#8853;</label><input type='checkbox' id='inv' class='margin-toggle'/><span class='marginnote'>Yes, this is basically a rephrasing of the second of the previously-stated pair of goals of the existing privacy rules. </span>
for the language: if an item <code>I</code> is accessible in context <code>C</code>, then the
surface for <code>I</code> does not expose anything that is inaccessible to <code>C</code>.</p>

<a name="Intuition.behind.what..surface..means"></a>
<h2>Intuition behind what &ldquo;surface&rdquo; means</h2>

<p>I am taking care to distinguish between the phrase &ldquo;exposed surface
API&rdquo; (more simply put, &ldquo;surface API&rdquo; or just &ldquo;surface&rdquo;), versus the
more common unqualified phrase &ldquo;API&rdquo;, because some items have
components that I argue are part of the item&rsquo;s programming interface,
but are not part of the publicly exposed surface of the item (further
discussed in a <a href="#Why.is.a..surface..not.the.same.as.a.signature.">later section</a>).</p>

<p>The inutition behind the term &ldquo;surface&rdquo; is this:
The exposed surface of an item is all of the
components<label for='surface-components' class='margin-toggle'> &#8853;</label><input type='checkbox' id='surface-components' class='margin-toggle'/><span class='marginnote'>&ldquo;components&rdquo; means: types, methods, paths &hellip; perhaps its easiest to just say &ldquo;names.&rdquo; </span>
 that the client operation&rsquo;s context must be able to reference to in order to use this
item legally.</p>

<p>There are two halves to this, that are roughly analogous to the output
and input types of a function: ensuring that local reasoning holds,
and ensuring an interface is actually usable.</p>

<a name="Restricting.output.surface.enables.local.reasoning"></a>
<h3>Restricting output surface enables local reasoning</h3>

<p>A function&rsquo;s return type is part of its exposed surface, because if
a module has decided that a type <code>T</code> should be inaccessible in some
outer context <code>C</code>, then we do not want a value of that type to flow
into <code>C</code> while still having the type
<code>T</code>.<label for='boxes' class='margin-toggle'> &#8853;</label><input type='checkbox' id='boxes' class='margin-toggle'/><span class='marginnote'>Of course if the type of the value is hidden, e.g. a <code>Box&lt;PrivateType&gt;</code> behind a <code>Box&lt;PublicTrait&gt;</code>, then that is fine as always. </span></p>

<p>In other words, we wish to reject such code in order to enable
module authors to employ <em>local reasoning</em> about all possible
locations in the source code that the operations on instances of
<code>T</code> could be invoked.</p>

<p>This <em>is</em> a soundness criteria: People need to be able to employ
this kind of reasoning.</p>

<a name="Restricting.input.surface.catches.API.mistakes"></a>
<h3>Restricting input surface catches API mistakes</h3>

<p>A function&rsquo;s input types are part of its exposed surface, because
without access to such types, the function is not callable.</p>

<p>In other words, we wish to reject such code in order to catch bugs
where a crate is <em>accidentally providing</em> a function without realizing
that it cannot actually be used in the contexts that the author wants
it available in.</p>

<p>This is not a soundness criteria; it is just a language usability one.<label for='prioritizing-halves' class='margin-toggle'> &#8853;</label><input type='checkbox' id='prioritizing-halves' class='margin-toggle'/><span class='marginnote'>In the long run, I suspect that the local reasoning enabled by restricting the output surface is going to be more important than the benefits of restricting the input surface. I am not aware of any case where we actually need to <emph>choose</emph> between the two; I am more speaking of where we should direct our attention. </span></p>

<a name="Why.is.a..surface..not.the.same.as.a.signature."></a>
<h2>Why is a &ldquo;surface&rdquo; not the same as a signature?</h2>

<p>Intuitively, one might ask: &ldquo;well, this is easy: the <em>signature</em> of
<code>fn foo</code> is <code>fn (Input) -&gt; Output</code>; does that not suffice as the
description of the <em>surface</em> of <code>fn foo</code>?&rdquo;</p>

<p>I am distinguishing the above notion of &ldquo;surface&rdquo; from the idea of a
&ldquo;signature&rdquo;, for the following reason: To my mind, the signature
(e.g. of a type or a function) contains all of the meta-data needed to
check (in the current crate or in other crates) whether a item is
being used properly. Such a signature may include references to names
that are not actually accessible in the current context. Compare this
to the <em>surface</em>, which is the subset of the names of the signature
that <em>must</em> be accessible in any context where the item is itself
accessible.</p>

<p>One example of where this kind of thinking can be applied is
<code>where</code> clauses. A where-clause can reference things that are not
accessible outside of the module of the function.  I would consider
such a <code>where</code> clause to still be part of the function&rsquo;s signature
(e.g., I would expect the compiler to reject my attempt to call the
function if I violate the encoded constraint), but I do not
necessarily consider the types or traits within that where clause part
of the surface API, since there are hidden parts to the constraint
that I do not have access to in my calling module.</p>

<p>Here is a concrete example that runs in Rust 1.5:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">S</span><span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;static</span> <span class="kt">str</span><span class="p">);</span>                 <span class="c1">// private struct type S</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">trait</span> <span class="n">Trait</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">compute</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">i32</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">impl</span> <span class="n">Trait</span> <span class="k">for</span> <span class="p">(</span><span class="kt">i32</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">fn</span> <span class="n">compute</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">i32</span> <span class="p">{</span> <span class="bp">self</span><span class="p">.</span><span class="mi">0</span> <span class="o">+</span> <span class="p">((</span><span class="bp">self</span><span class="p">.</span><span class="mi">1</span><span class="p">).</span><span class="mf">0.</span><span class="n">len</span><span class="p">()</span> <span class="k">as</span> <span class="kt">i32</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span><span class="o">:</span> <span class="n">X</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">i32</span>
</span><span class='line'>        <span class="n">where</span> <span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span><span class="o">:</span> <span class="n">Trait</span> <span class="c1">// where clause refers to private type S</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">S</span><span class="p">(</span><span class="s">&quot;hi&quot;</span><span class="p">)).</span><span class="n">compute</span><span class="p">()</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">a</span><span class="o">::</span><span class="n">foo</span><span class="p">(</span><span class="mi">3</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>There are other examples that we may want to support in the future.
For example, Rust (version 1.5) considers bounding a type parameter
directly via a private trait to be illegal, but we might reasonably
revise the rules to say that while such a bound is part of the
signature, it need not be part of the <em>surface</em>.</p>

<p>(A very similar construction is allowed in Rust 1.5: A <code>pub</code> trait
can have a private <em>parent</em> trait, which allows us to encode the
latter construction anyway: the surface area of a function does not
include the parent traits of bounds on its type parameters.)</p>

<p>That&rsquo;s a lot of text to read. Here is the kind of code I am talking
about:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">S</span><span class="p">(</span><span class="n">String</span><span class="p">);</span>                      <span class="c1">// private type</span>
</span><span class='line'>    <span class="k">trait</span> <span class="n">Trait</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">make_s</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">S</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// private trait</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">trait</span> <span class="n">SubT</span><span class="o">:</span> <span class="n">Trait</span> <span class="p">{</span> <span class="p">}</span>              <span class="c1">// public trait to placate rustc</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">X</span><span class="o">:</span><span class="n">SubT</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span><span class="o">:</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// public fn that external code *can* use.</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">s</span><span class="o">:</span> <span class="n">S</span> <span class="o">=</span> <span class="n">x</span><span class="p">.</span><span class="n">make_s</span><span class="p">();</span>
</span><span class='line'>        <span class="n">s</span><span class="p">.</span><span class="n">do_stuff</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Impl trait for both () and i32, so clients can call `foo` on () or i32.</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">Trait</span> <span class="k">for</span> <span class="p">()</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">make_s</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">S</span> <span class="p">{</span> <span class="n">S</span><span class="p">(</span><span class="n">format</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;():()&quot;</span><span class="p">))</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">Trait</span> <span class="k">for</span> <span class="kt">i32</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">make_s</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">S</span> <span class="p">{</span> <span class="n">S</span><span class="p">(</span><span class="n">format</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}:i32&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">SubT</span> <span class="k">for</span> <span class="p">()</span> <span class="p">{}</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">SubT</span> <span class="k">for</span> <span class="kt">i32</span> <span class="p">{}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">impl</span> <span class="n">S</span> <span class="p">{</span> <span class="k">fn</span> <span class="n">do_stuff</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="p">{</span> <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;stuff with {}&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">a</span><span class="o">::</span><span class="n">foo</span><span class="p">(());</span>
</span><span class='line'>    <span class="n">a</span><span class="o">::</span><span class="n">foo</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In short: the term &ldquo;surface API&rdquo; here is <em>not</em> synonymous with the
term &ldquo;signature&rdquo;.</p>

<p>Assuming that you believe me that this new term, &ldquo;surface API&rdquo;, is
actually warranted, you might now ask: &ldquo;How does one determine the
surface API of an item?&rdquo; That is one of those questions that may sound
trivial at first, but it is actually a bit subtle.</p>

<p>Let us explore.</p>

<a name="Some.items.can.change.their.surface.based.on.context"></a>
<h3>Some items can change their surface based on context</h3>

<p>For some items, such as <code>fn</code> definitions, the surface API is the same
regardless of the context of where the item is used; for example, if a
function is visible to you, then its surface API is simply its
argument and return types, regardless of from where the function is
referenced.</p>

<p>However, the previous rule does not generally hold for most items; in
general, the exposed surface of a given item is dependent on the
context where that item is referenced.</p>

<p>The main examples of this are:</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
All of these bullets are phrased as &ldquo;can be hidden&rdquo;, i.e.,
the visibility may be restricted. However, in Rust today,
one can write: <code>mod a{struct X{pub y: i32}}</code>
I may want to generalize the statements here. (Then again, I
am not clear whether there is any way to actually <em>use</em> the
<code>y</code> field that has been exposed in this way.)
</span></p>

<ul>
<li><p><code>struct</code> fields can be hidden in a <code>struct</code>,</p></li>
<li><p>inherent methods can be hidden relative to the type they are attached to, and</p></li>
<li><p>items can be hidden in a <code>mod</code>.</p></li>
</ul>


<p>In all cases where a surface component can be hidden in this
context-dependent fashion, there is an associated <code>pub</code>-modifier
present on the definition of that component.</p>

<p>As an example of how the surface of a <code>struct</code> is context dependent,
the following is legal:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="cp">#[derive(Default)]</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">Priv</span><span class="p">(</span><span class="kt">i32</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">pub</span> <span class="kn">mod</span> <span class="n">b</span> <span class="p">{</span>
</span><span class='line'>        <span class="cp">#[derive(Default)]</span>
</span><span class='line'>        <span class="k">pub</span> <span class="k">struct</span> <span class="n">F</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">pub</span>    <span class="n">x</span><span class="o">:</span> <span class="kt">i32</span><span class="p">,</span>
</span><span class='line'>                   <span class="n">y</span><span class="o">:</span> <span class="o">::</span><span class="n">a</span><span class="o">::</span><span class="n">Priv</span><span class="p">,</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// ... accesses to F.{x,y} ...</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="c1">// ... accesses to F.x ...</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kn">mod</span> <span class="n">k</span> <span class="p">{</span>
</span><span class='line'>  <span class="kn">use</span> <span class="n">a</span><span class="o">::</span><span class="n">b</span><span class="o">::</span><span class="n">F</span><span class="p">;</span>
</span><span class='line'>  <span class="c1">// ... accesses to F and F.x ...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Within <code>mod b</code>, the surface API of <code>F</code> includes both the fields <code>x</code>
and <code>y</code>, which means that the use of the type <code>Priv</code> is okay, since
that is accessible from the context of <code>mod b</code>.</p>

<p>Elsewhere, such as within <code>mod k</code>, the surface API of <code>F</code> is just the
field <code>x</code>. But this is again okay, because the type of <code>x: i32</code> is
visible everywhere.</p>

<a name="Aliases.and.translucency"></a>
<h3>Aliases and translucency</h3>

<p>Some items, such as <code>type</code> aliases, <code>const</code> definitions, or rebinding
imports a la <code>use &lt;path&gt; as &lt;ident&gt;</code>, can act to introduce named aliases
to an item.</p>

<p>In such cases, the alias itself has its own associated visibility:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">struct</span> <span class="n">S</span><span class="p">(</span><span class="n">String</span><span class="p">);</span> <span class="c1">// public type</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">Alias1</span> <span class="o">=</span> <span class="n">S</span><span class="p">;</span>      <span class="c1">// private alias to the type</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="kn">use</span> <span class="n">a</span><span class="o">::</span><span class="n">S</span> <span class="k">as</span> <span class="n">Alias2</span><span class="p">;</span>   <span class="c1">// public alias to the type</span>
</span></code></pre></td></tr></table></div></figure>


<p>The surface of simple aliases is also simple: the surface of an
alias
is just the paths referenced on its right-hand side.</p>

<p>As a small additional wrinkle, type aliases can be type-parametric. In
general, the exposed surface of a type alias are the bounds on its
type parameters, plus the paths referenced on its left-hand side.</p>

<p>So, for example, according to the rules today:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">bad_aliases</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">Private1</span><span class="p">(</span><span class="n">String</span><span class="p">);</span> <span class="c1">// private type</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">type</span> <span class="n">PubAlias1</span> <span class="o">=</span> <span class="n">Private1</span><span class="p">;</span> <span class="c1">// ERROR: private type exposed in pub surface</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">trait</span> <span class="n">PrivateTrait</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">type</span> <span class="n">PubAlias2</span><span class="o">&lt;</span><span class="n">X</span><span class="o">:</span><span class="n">PrivateTrait</span><span class="o">&gt;</span> <span class="o">=</span> <span class="kt">i32</span><span class="p">;</span> <span class="c1">// ERROR: private trait exposed in pub surface</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The more interesting issue is how <em>other</em> surface APIs are influenced
when they reference an alias.</p>

<p>For example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">struct</span> <span class="n">S</span><span class="p">(</span><span class="n">String</span><span class="p">);</span> <span class="c1">// public type</span>
</span><span class='line'>    <span class="k">type</span> <span class="n">Alias1</span> <span class="o">=</span> <span class="n">S</span><span class="p">;</span>      <span class="c1">// private alias to the type</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">twice</span><span class="p">(</span><span class="n">s</span><span class="o">:</span> <span class="n">Alias1</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">String</span> <span class="p">{</span> <span class="n">s</span><span class="p">.</span><span class="mi">0</span> <span class="p">}</span>
</span><span class='line'>    <span class="c1">//              ~~~~~~</span>
</span><span class='line'>    <span class="c1">//                 |</span>
</span><span class='line'>    <span class="c1">// Should a `pub fn` be able to reference a private alias,</span>
</span><span class='line'>    <span class="c1">// if it points to a suitably public type (like `S` here)?</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">pub</span> <span class="kn">use</span> <span class="n">a</span><span class="o">::</span><span class="n">S</span> <span class="k">as</span> <span class="n">Alias2</span><span class="p">;</span>   <span class="c1">// public alias to the type</span>
</span></code></pre></td></tr></table></div></figure>


<p>Should it be legal for us to publicly export <code>fn twice</code> from <code>mod a</code>,
even though it&rsquo;s signature references a private type alias?</p>

<p>The language team recently <a href="https://github.com/rust-lang/rust/pull/29973#issuecomment-165723770">debated</a> this topic, because
it was suggested that allowing this would <a href="https://github.com/rust-lang/rust/pull/29973#issuecomment-158686899">reduce breakage</a>
from a pull request.</p>

<p>The conclusion for now was to continue to disallow the reference to
the private alias in the signature of a public function.</p>

<p>However, there are similar cases that <em>are</em> allowed today (also
discussed on that same PR), mainly involving references to <code>const</code> paths
from types in such signatures.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span>
</span><span class='line'>    <span class="kr">const</span> <span class="n">LEN</span><span class="o">:</span> <span class="n">usize</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">max</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="p">[</span><span class="kt">i32</span><span class="p">;</span> <span class="n">LEN</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="kt">i32</span> <span class="p">{</span> <span class="n">a</span><span class="p">.</span><span class="n">iter</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">i</span><span class="o">|*</span><span class="n">i</span><span class="p">).</span><span class="n">max</span><span class="p">().</span><span class="n">unwrap</span><span class="p">()</span> <span class="p">}</span>
</span><span class='line'>    <span class="c1">//                  ~~~</span>
</span><span class='line'>    <span class="c1">//                   |</span>
</span><span class='line'>    <span class="c1">// A reference to a private const in a public signature</span>
</span><span class='line'>    <span class="c1">// is legal in Rust today.</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span> <span class="n">a</span><span class="o">::</span><span class="n">max</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]));</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I have not made up my mind as to which option would be better here.
We may decide to leave things as they are, or loosen the rules for
type aliases (so that they act more like <code>const</code> in the latter code),
or we may tighten the rules for references to <code>const</code> (so that one
would have to make <code>LEN</code> in the above code <code>pub</code>).</p>

<p>Regardless of what path we take, I think it makes sense today for the
language specification to at least identify a high-level abstraction
here, rather than dealing with each alias-creating form like <code>type</code> or
<code>const</code> or <code>use</code> individually in an ad-hoc manner.</p>

<p>Namely, I want to pin down the idea of a <em>translucent name</em>. Such a
name is not part of the API surface where it occurs; instead, an
occurrence adds the surface of the alias statement itself to the API
surface.</p>

<p>So, as another artifical example, if we were to change the language so
that <code>type</code> aliases were <em>translucent</em> when determining the exposed
surface of an API, then we might have the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">mod</span> <span class="n">a</span> <span class="p">{</span> <span class="c1">// (not legal Rust today)</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">struct</span> <span class="n">S</span><span class="p">(</span><span class="n">String</span><span class="p">);</span> <span class="c1">// public type</span>
</span><span class='line'>    <span class="k">pub</span> <span class="k">trait</span> <span class="n">Bound</span> <span class="p">{</span> <span class="k">type</span> <span class="n">X</span><span class="p">;</span> <span class="k">fn</span> <span class="n">trait_method</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Self</span><span class="o">::</span><span class="n">X</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">Bound</span> <span class="k">for</span> <span class="n">String</span> <span class="p">{</span> <span class="k">type</span> <span class="n">X</span> <span class="o">=</span> <span class="n">String</span><span class="p">;</span> <span class="k">fn</span> <span class="n">trait_method</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">String</span> <span class="p">{</span> <span class="bp">self</span><span class="p">.</span><span class="n">clone</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">impl</span> <span class="n">Bound</span> <span class="k">for</span> <span class="n">S</span> <span class="p">{</span> <span class="k">type</span> <span class="n">X</span> <span class="o">=</span> <span class="n">String</span><span class="p">;</span> <span class="k">fn</span> <span class="n">trait_method</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">String</span> <span class="p">{</span> <span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">clone</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">type</span> <span class="n">Alias</span><span class="o">&lt;</span><span class="n">T</span><span class="o">:</span> <span class="n">Bound</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">T</span><span class="o">::</span><span class="n">X</span><span class="p">,</span> <span class="n">S</span><span class="p">);</span> <span class="c1">// private Alias, with surface = {Bound, S}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">pub</span> <span class="k">fn</span> <span class="n">free_fun</span><span class="o">&lt;</span><span class="n">T</span><span class="o">:</span> <span class="n">Bound</span><span class="o">&lt;</span><span class="n">X</span><span class="o">=</span><span class="n">String</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="n">Alias</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">String</span>
</span><span class='line'>    <span class="c1">//                 ~~~~~   ~~~~~~      ~~~~~        ~~~~~~</span>
</span><span class='line'>    <span class="c1">//  free_fun has     |       |           |            |</span>
</span><span class='line'>    <span class="c1">//     surface = { Bound, String, surface(Alias), String }</span>
</span><span class='line'>    <span class="c1">//             = { Bound, String,    Bound, S   , String }</span>
</span><span class='line'>    <span class="c1">//             = { Bound, S, String }</span>
</span><span class='line'>    <span class="c1">//</span>
</span><span class='line'>    <span class="c1">// which is compatible with `free_fn` being `pub`, because</span>
</span><span class='line'>    <span class="c1">// `Bound`, `S`, and `String` are all `pub`.</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">format</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}{}&quot;</span><span class="p">,</span> <span class="n">a</span><span class="p">.</span><span class="mf">0.</span><span class="n">trait_method</span><span class="p">(),</span> <span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="mi">1</span><span class="p">).</span><span class="mi">0</span><span class="p">)</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note 1: Even though <code>Alias</code> is type-parameteric over <code>T</code>, that
parameter would not be considered part of its surface. Anyone using
the alias would have to have access to whatever type they plugged in
there, of course.</p>

<p>Note 2: Type parameter bounds not enforced on type aliases in Rust yet.</p>

<p>This computation and questions here would become a little more
interesting if we had restricted visibility access modifiers on
associated items in traits. However, we do not have to consider it:
All associated items are implicitly <code>pub</code>, and so we do not need to
worry about whether the <code>X</code> in a projection like <code>T::X</code> is visible.
All that matters is whether the trait <code>Bound</code> itself is visible (which
is already reflected in the surfaces where <code>Bound</code> is used).</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>Okay, that was of a bit of a meandering tour through some
of the issues I have been thinking about.</p>

<p>The big ideas I want to stress are these:</p>

<ul>
<li><p>The &ldquo;surface&rdquo; of an item can be different from the &ldquo;signature&rdquo; of
that item.</p></li>
<li><p>Restricting the components in a surface of an item according to the
visibility of that item (1.) enables local reasoning and (2.)
catches API mistakes.</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fixing Octopress Table Rendering]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/12/18/fixing-octopress-table-rendering/"/>
    <updated>2015-12-18T22:00:00-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/12/18/fixing-octopress-table-rendering</id>
    <content type="html"><![CDATA[<p>Learn how I hacked the SCSS for my blog to get tables to look right,
without breaking everything else (I hope).</p>

<!-- more -->


<p>Here is a sample table.</p>

<table>
<thead>
<tr>
<th>key </th>
<th> value1 </th>
<th> value2</th>
</tr>
</thead>
<tbody>
<tr>
<td>a   </td>
<td> apple  </td>
<td> aardvark</td>
</tr>
<tr>
<td>b   </td>
<td> banana </td>
<td> bonobo</td>
</tr>
<tr>
<td>c   </td>
<td> clementine </td>
<td> cat</td>
</tr>
</tbody>
</table>


<p>It is written in my blog source via this source text:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>key | value1 | value2
</span><span class='line'>----|--------|----------
</span><span class='line'>a   | apple  | aardvark
</span><span class='line'>b   | banana | bonobo
</span><span class='line'>c   | clementine | cat</span></code></pre></td></tr></table></div></figure>


<p>The default octopress presentation of such a table just smushes the
text into a grid, but does not render the division of the header,
rows, columns, nor cells in any way (no borders, no colors, et
cetera).</p>

<p>After hearing a colleague complain about how bad that default
presentation looked compared to what Github does with such tables, I
decided to try to figure out how to fix it.</p>

<p>First, I opened up gist.github.com and put my table into a gist there
(with a <code>.md</code>) extension, so I could see what github does to render
such tables.</p>

<p>By hitting &ldquo;Inpsect Element&rdquo; and looking at the
cascading style sheet (CSS) settings for the <code>table</code>, <code>tr</code>, <code>th</code>, and
<code>td</code> elements,<label for='settings' class='margin-toggle'> &#8853;</label><input type='checkbox' id='settings' class='margin-toggle'/><span class='marginnote'>Namely, the <code>border</code>, <code>padding</code>, <code>font-weight</code>, <code>background-color</code>, and <code>margin-bottom</code> settings. </span>
I identified the things that needed to change.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
The one trick I <em>will</em> note, since its a pretty cute hack on the
part of CSS, is the way it uses the <code>:nth-child</code> selector to
differentiate the even rows from the odd rows when deciding on the
background color.
</span>
You can see the specific changes, with comments, in the <code>.scss</code>
file transcribed below; I will not describe the effect of each one
here.</p>

<p>My usual tactic when doing this sort of interactive exploration of CSS
is to toggle each such setting on and off in the reference document
(the rendered gist, in this case), to see the effect of the setting on
the overall document, and then manually enter the setting into a
similarly inspected element in the target document where I am trying
to recreate the effect.</p>

<p>To limit the effect of the styling to just the tables that appear in a
blog post, I made sure that each CSS customization was prefixed by
<code>.entry-content</code>; I had determined via inspection that each block
entry is surrounded by a <code>&lt;div class="entry-content"&gt;</code>.</p>

<p>So, I added the customizations to my <code>sass/custom/_styles.scss</code>,
regenerated my site, and looked at the result. It was quite promising,
except for one big problem: I had changed the formatting for <em>all</em>
tables, including the ones that are used to render code snippets!</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
I will admit that I do not actually know the semantics of an
&ldquo;inherit&rdquo; setting. I assume it means something like &ldquo;inherit the
value from your parent element, based on the context of where you
appear in the document.&rdquo;
</span>
So I further revised the CSS so that, when you are in the context of a
<code>class="code"</code> underneath a <code>class="entry-content"</code>, <em>then</em> you should
just inherit the setting, rather than using the values specified here.</p>

<p>Anyway, <em>that</em> seemed to work great!</p>

<p>So here&rsquo;s my customized <code>_better_tables.scss</code> file (which is
imported into the aformentioned <code>_styles.scss</code> file via
<code>@import "better_tables";</code>)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='scss'><span class='line'><span class="c1">// make the text for the header row bold and centered.</span>
</span><span class='line'><span class="c1">// (I have not been able to figure out where jekyll/octopress are overriding</span>
</span><span class='line'><span class="c1">//  the text-align and setting it to `left`)</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nt">th</span> <span class="p">{</span> <span class="na">font-weight</span><span class="o">:</span> <span class="no">bold</span><span class="p">;</span> <span class="na">text-align</span><span class="o">:</span> <span class="no">center</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// typography for p/blockquote/ul/ol puts a 1.5em margin below those elements,</span>
</span><span class='line'><span class="c1">// so do the same for our tables ...</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nt">table</span> <span class="p">{</span> <span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.5</span><span class="kt">em</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// ... but undo that for tables for pygments-generated code</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nc">.code</span> <span class="nt">table</span> <span class="p">{</span> <span class="na">margin-bottom</span><span class="o">:</span> <span class="no">inherit</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1">// add a border around each cell and padding around its content ...</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nt">th</span><span class="o">,</span> <span class="nc">.entry-content</span> <span class="nt">td</span> <span class="p">{</span>
</span><span class='line'>  <span class="na">border</span><span class="o">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="no">solid</span> <span class="mh">#ddd</span><span class="p">;</span>
</span><span class='line'>  <span class="na">padding</span><span class="o">:</span> <span class="mi">6</span><span class="kt">px</span> <span class="mi">13</span><span class="kt">px</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// ... but undo that for tables for pygments-generated code</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nc">.code</span> <span class="nt">th</span><span class="o">,</span> <span class="nc">.entry-content</span> <span class="nc">.code</span> <span class="nt">td</span> <span class="p">{</span>
</span><span class='line'>  <span class="na">border</span><span class="o">:</span> <span class="no">inherit</span><span class="p">;</span> <span class="na">padding</span><span class="o">:</span> <span class="no">inherit</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1">// zebra-stripe the rows (N.B. `nth-child(2n)` works too) ...</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nt">tr</span>                 <span class="p">{</span> <span class="na">background-color</span><span class="o">:</span> <span class="mh">#FFFFFF</span> <span class="p">}</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nt">tr</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">even</span><span class="o">)</span> <span class="p">{</span> <span class="na">background-color</span><span class="o">:</span> <span class="mh">#F8F8F8</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// ... but undo that for tables for pygments-generated code</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nc">.code</span> <span class="nt">tr</span>                 <span class="p">{</span> <span class="na">background-color</span><span class="o">:</span> <span class="no">inherit</span> <span class="p">}</span>
</span><span class='line'><span class="nc">.entry-content</span> <span class="nc">.code</span> <span class="nt">tr</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">even</span><span class="o">)</span> <span class="p">{</span> <span class="na">background-color</span><span class="o">:</span> <span class="no">inherit</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cherry-picking from the shoulders of giants]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/11/27/cherrypicking-tuftes-of-hair/"/>
    <updated>2015-11-27T14:00:00-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/11/27/cherrypicking-tuftes-of-hair</id>
    <content type="html"><![CDATA[<p>This post: I describe some changes to my blog&rsquo;s presentation
format, and how I hacked them in by cherry-picking from the shoulders
of giants.</p>

<!-- more -->


<p>I&rsquo;m a big fan of Edward Tufte&rsquo;s work on presentation of
information. He mostly focuses on graphical presentations, especially
of statistical data. But really one can learn much from his overall
presentation style, e.g. from how he formats his text.</p>

<p>Of course I am not the first person to recognize this. :)</p>

<p>Lots of people have been adapting Tufte&rsquo;s style to formats compatible
with standard electronic authoring environments.</p>

<ul>
<li><p><a href="https://tufte-latex.github.io/tufte-latex/">tufte-latex</a> is pretty cool, if you&rsquo;re working in the realm of
LaTeX. (For example, <a href="http://www.mpi-sws.org/~turon/turon-thesis.pdf">aturon&rsquo;s thesis</a>
uses this style.)</p></li>
<li><p><a href="https://edwardtufte.github.io/tufte-css/">tufte-css</a> is pretty cool, if you&rsquo;re working in the realm of
writing HTML and want to just plug in a style sheet and go.</p></li>
</ul>


<p>(I&rsquo;m sure the hardcore Tufte fans in the audience are now saying &ldquo;How
can you claim to want to emulate Tufte&rsquo;s work in a post that uses a
bulleted list!?!&rdquo; I think there remains a time and place for a
bulleted list; this digression continues <a href="#on-bulleted-lists">below</a>.)</p>

<ul>
<li><p>What if you&rsquo;re trying to work with a blog system like
Octopress?</p>

<p>Well, you&rsquo;re actually in luck; other people have already done the
work of adapting the style rules in <a href="https://edwardtufte.github.io/tufte-css/">tufte-css</a> to Jekyll (the
infrastructure that Octopress is built upon), yielding
<a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a>.</p></li>
</ul>


<p>After skimming over the presentation over at <a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a> and
suffering with recurrent Octopress issues, I briefly considered
<span style="white-space: nowrap"><code>rm -rf</code>&lsquo;ing</span> Octopress from my blog system and adopting Jekyll directly.
(Which isn&rsquo;t as big a deal as it sounds, since Octopress is built on
top of Jekyll and so in principle I would get to reuse much of my
previous customizations.)</p>

<p>But the reality is that I do not really want to spend that much time on this;
having a presentation that matches every aspect of <a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a> is not
currently that important to me. (At least, not yet.)</p>

<p>What I really wanted was to cherry-pick certain aspects that I find
important.</p>

<p>In particular, I <em>really</em> want sidenotes (and margin notes/figures),
and an option for full width figures. I&rsquo;ll discuss each in turn.</p>

<p>Luckily for me, the presentation of <a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a> is itself
somewhat dedicated to spelling out how each feature was added.  In
other words, it seems <em>perfect</em> to use as the basis for such
cherry-picking.</p>

<p>Pretty much all of the things I wanted were implemented in
<a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a> via Jekyll Plugins. Let&rsquo;s go through them one by one,
largely just to prove to myself that it is all working as I expect,</p>

<p>(In actual practice, what this actually meant is that iteratively
fixed my CSS and/or made my own variants of the plugins until this
text rendered as a postable demonstration).</p>

<p>(The presentation below makes claims about how each construct is
written in the source markdown; however, each case is assuming that
one has installed the appropriate Jekyll plugins and SCSS support
files)</p>

<a name="Side.Notes"></a>
<h2>Side Notes</h2>

<p>My previous blog posts<label for='previous-blog-posts' class='margin-toggle sidenote-number'></label><input type='checkbox' id='previous-blog-posts' class='margin-toggle'/><span class='sidenote'>Hey, a sidenote! One post that can/will benefit from these is my earlier <a href="blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/">GC and Rust Part 0</a>. </span>
sometimes hacked in ad-hoc footnotes. But footnotes on the web are
super awkward because I am never quite sure how far down into the post
to collect the footnotes together.  Furthermore, I dislike how my
ad-hoc footnotes would disrupt the flow of the text if they were not
placed at the bottom of the (potentially very long) post; but if they
were all collected at the bottom, then navigating the page becomes
unwieldy at best.</p>

<p>Side notes do not suffer from either of these problems.</p>

<p>Side note support (and margin content in general) <em>does</em> come at the
cost of potentially introducing a large unused space on the right-hand
side of the presentation.</p>

<p>But the CSS magic here is smart enough to only try to grab the space
if it can afford to do so; if you are viewing this on a narrow
device,<label for='thin-browser' class='margin-toggle sidenote-number'></label><input type='checkbox' id='thin-browser' class='margin-toggle'/><span class='sidenote'>Or make your browser window sufficiently thin relative to its font size. </span>
the superscript indicating the presence of an associated side note
turns into a toggle switch for the associated content (now presented <em>inline</em>
with the text when toggled on).</p>

<p>One writes a sidenote with the following liquid tag syntax:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>main content{% sidenote 'unique-id' 'side content' %}</span></code></pre></td></tr></table></div></figure>


<p>which renders as:
main content<label for='unique-id' class='margin-toggle sidenote-number'></label><input type='checkbox' id='unique-id' class='margin-toggle'/><span class='sidenote'>side content </span></p>

<a name="Margin.Notes"></a>
<h2>Margin Notes</h2>

<p>Sometimes even the superscripted number that a sidenote carries is
disruptive, and unnecessary if:</p>

<ol>
<li><p>the content is lined up nicely, and</p></li>
<li><p>the presentation width for the main column is sufficiently wide.</p></li>
</ol>


<p>In other words: Why not drop the superscript?
<label for='inherited-from-foonotes' class='margin-toggle'> &#8853;</label><input type='checkbox' id='inherited-from-foonotes' class='margin-toggle'/><span class='marginnote'>This is a margin note <em>without</em> a superscript. The superscripts on sidenotes are a holdover from the world of footnotes. </span></p>

<p>That&rsquo;s what marginnotes are for.</p>

<p>But again, one wants to handle the case where the rendering area is
too narrow to set aside a margin. If your make the window narrow, you
will see that a margin note is replaced with an
inline symbol<label for='checkplus' class='margin-toggle sidenote-number'></label><input type='checkbox' id='checkplus' class='margin-toggle'/><span class='sidenote'>Since there is no number associated with a margin note, the symbol is a plus sign with a circle around it; I think it is this: &ldquo;&#x2295;&rdquo; U+2295 (aka &ldquo;CIRCLED PLUS&rdquo;) </span>
that will provide the reader with a way to toggle the presentation
of the elided content on and off, the same way that the superscript
acted as a toggle for a sidenote above.</p>

<p>Anyway, the code for <code>marginnote</code> is entirely analogous to that for <code>sidenote</code>.
One writes a margin note with the following liquid tag syntax:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>main content{% marginnote 'uniq-id' 'margin content' %}</span></code></pre></td></tr></table></div></figure>


<p>which renders as:
main content<label for='uniq-id' class='margin-toggle'> &#8853;</label><input type='checkbox' id='uniq-id' class='margin-toggle'/><span class='marginnote'>margin content </span></p>

<a name="Margin.Figures"></a>
<h2>Margin Figures</h2>

<p>Another topic I have touched on (and plan to do more with soon) is
drawing diagrams of graph structures. This usually involves SVG in
some manner.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     id="demo_svg_defs" height="0" viewBox="0 0 32 32">
<defs>
<pattern id="grid_cell" width=10 height=10 patternUnits="userSpaceOnUse">
<path d="M 0,0 v10 h10" fill="none" stroke="#aaa" stroke-width=1/>
</pattern>
<pattern id="grid" width=100 height=100 patternUnits="userSpaceOnUse">
<path d="M 0,0 v100 h100 v-100 z" stroke="#555" stroke-width=1 fill="url(#grid_cell)"/>
</pattern>
<g id="the_pic">
<rect x=0 y=0 width="100%" height="100%" fill="url(#grid)"/>
<circle cx=20 cy=20 r=10 stroke="green" fill="none"/>
<path d="M 80,30 C 90,20 30,20 10,40" stroke="blue" fill="none"/>
</g>
</defs>
</svg></p>

<p>Here is a relatively simple bit of SVG:</p>

<p><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     id="demo_svg_main" height="50" width="100%">
<use xlink:href="#the_pic"/>
</svg></p>

<!-- If you're looking at this source code, then you can see that the
     actual content definitions are above, in the SVG group (`g`)
     element identified by `the_pic` -->


<p>I want to be able to present such diagrams in the same manner that
<code>tufte-css</code> and <code>tufte-jekyll</code> presents margin figures, full-width
figures, and column width figures.</p>

<p>However, <code>tufte-jekyll</code> assumes in its plugin for these features that
whatever figure you want to present is held in a separate file.</p>

<p><label for='svg-margin-figure' class='margin-toggle'>&#8853;</label><input type='checkbox' id='svg-margin-figure' class='margin-toggle'/><span class='marginnote'>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     id="demo_svg_margin" height="50" width="100%">
<use xlink:href="#the_pic"/>
</svg>
Here is a margin figure; it shows a circle and a cubic bezier curve
(along with helpful grid lines, which I need to figure out how to
adjust the coordinates in the source SVG).
</span></p>

<p>I resolved this by hacking the <code>margin_figure.rb</code> plugin so that it
extends from <code>Liquid::Block</code> instead of <code>Liquid::Tag</code>, and then
hacking the implementation of the plugin until it started producing
the output I expect. By the time I finished, I had something
with a totally different feature-set and interface; so I renamed
this version of the plugin to <code>marginblock</code>.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Actually, I think all of the side- and margin-content extensions
discussed here have the same limitation that they only work with
inline elements.
</span></p>

<p>Important Caveat: this hacked <code>marginblock</code> plugin can only handle
inline elements.</p>

<p><label for='demo-code-in-margin' class='margin-toggle'>&#8853;</label><input type='checkbox' id='demo-code-in-margin' class='margin-toggle'/><span class='marginnote'>
<code>&lt;code&gt;styling&lt;/code&gt;</code> does work (via HTML or Markdown backticks), but
fenced code blocks do not, because they generate <code>figure</code> and <code>table</code>
elements.
</span></p>

<ol>
<li><p>HTML code for certain elements (like
 <nobr><code>figure</code>,</nobr> <nobr><code>p</code>,</nobr> <nobr><code>pre</code>,</nobr> or
 <code>table</code> elements) will fragment the content, with some initial
 portion in the margin, and the remainder injected into the main
 text.</p></li>
<li><p>Markdown syntax that generates block-level elements has the
 same problem as HTML block-level elements.</p>

<p> For example, content after an empty line will be converted into
 a <code>p</code> element (and those will end up injected back into the main
 text).</p></li>
</ol>


<p>In other words: any markdown syntax inside a <code>marginblock</code>, including just an empty line
separating two blocks of text, will just confuse things.</p>

<p>So, don&rsquo;t do that.</p>

<p>To write a margin block, use the following syntax:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{% marginblock %}
</span><span class='line'>Margin block content, with no line breaks (see caveat above).
</span><span class='line'>{% endmarginblock %}</span></code></pre></td></tr></table></div></figure>


<a name="Full.Width.Figures"></a>
<h2>Full Width Figures</h2>

<p>You might have noticed that in the SVG diagram <a
href="#demo_svg_main">above</a>, the diagram only spans the width of
the &ldquo;main text&rdquo;, while the code block spans the full extent of the
page, flowing into the margin area.</p>

<p>I have hacked the CSS so that all of the figures for code are given
the full width of the page (otherwise, they always overflowed the
available space, yielding unfortunate scroll bars).</p>

<p>Still, it might well be that some SVG diagrams will likewise need the
full width of the page.
<code>tufte-jekyll</code> provides a plugin for this (called <code>fullwidth</code>), but
much like with its <code>marginfigure</code> plugin,
the <code>fullwidth</code> plugin assumes that
the content to be rendered lives in a separate file. Analogously to
how I dealt with that by making my own version of plugin,
<code>margin_block</code>, I have here made my own <code>fullwidth_figure</code> plugin.</p>

<p>Here is that circle and bezier curve again, this time spanning
the full width of the page:</p>

<p><figure class='fullwidth'>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     id="demo_svg_main" height="50" width="100%">
<use xlink:href="#the_pic"/>
</svg>
</figure></p>

<p>So, all you need to do is write:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{% fullwidthfigure %}
</span><span class='line'>The lines of fullwidth figure content will extend across the full
</span><span class='line'>width of the page before line wrapping. (Some block elements will end
</span><span class='line'>up being mishandled, so don't use elements like `p` or `ul`, et
</span><span class='line'>cetera, or Markdown that generates them.)
</span><span class='line'>As the name implies, this is nested within a `figure` element;
</span><span class='line'>that means, for example, you can use `figcaption` to add a caption:
</span><span class='line'>&lt;figcaption&gt;Caption for `fullwidthfigure` demo&lt;/figcaption&gt;
</span><span class='line'>{% endfullwidthfigure %}</span></code></pre></td></tr></table></div></figure>


<p>which renders as:
<figure class='fullwidth'>
The lines of fullwidth figure content will extend across the full
width of the page before line wrapping. (Some block elements will end
up being mishandled, so don&rsquo;t use elements like <code>p</code> or <code>ul</code>, et
cetera, or Markdown that generates them.)
As the name implies, this is nested within a <code>figure</code> element;
that means, for example, you can use <code>figcaption</code> to add a caption:
<figcaption>Caption for <code>fullwidthfigure</code> demo</figcaption>
</figure></p>

<a name="Drawbacks..Rendering.Bugs.and.or.Gotcha.s"></a>
<h2>Drawbacks, Rendering Bugs and/or Gotcha&rsquo;s</h2>

<p>Originally I had a whole section here decrying the fact that I could
not put <em>any</em> line breaks into the source for a <code>sidenote</code> or
<code>marginnote</code>, since the Liquid tag parser requires the entirety of a
tag be contained on one line.</p>

<p>But then I hacked up <code>marginblock</code> (described above), and my problem
just goes away
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Well, it goes away for superscript-free margin notes, at least.
If I ever feel the need to write a long side note, then I guess
I&rsquo;ll make a <code>sideblock</code> plugin at that time.
</span></p>

<p>Besides, maybe discouraging me from writing
long side notes<label for='dfw' class='margin-toggle sidenote-number'></label><input type='checkbox' id='dfw' class='margin-toggle'/><span class='sidenote'>I am pretty sure <a href="https://en.wikipedia.org/wiki/Infinite_Jest">Infinite Jest</a> would not work so well as a blog post. </span>
is not such a bad thing.</p>

<ul>
<li><p>Oh, by the way, it looks like you cannot throw side notes just
<em>anywhere</em><label for='bullet-test' class='margin-toggle sidenote-number'></label><input type='checkbox' id='bullet-test' class='margin-toggle'/><span class='sidenote'>Like, say, a bulleted list; further discussion in the <a href="#on-bulleted-lists">On Bulleted Lists</a> section. </span>
and expect them to play nice with the other marked up text.</p>

<p>For example, it may appear at a inconsistently inset margin&hellip; or worse&hellip;</p></li>
<li><p>Markup in a surrounding context is handled <em>somewhat<label for='emph-test' class='margin-toggle sidenote-number'></label><input type='checkbox' id='emph-test' class='margin-toggle'/><span class='sidenote'>This is relatively fine, even though it was not written with emphasis. </span> poorly</em>,
in that it may inherit the style of the surrounding markup it was embedded within</p></li>
<li><p>And some contexts, like code markup,<label for='code-test' class='margin-toggle'> &#8853;</label><input type='checkbox' id='code-test' class='margin-toggle'/><span class='marginnote'>Yeah, that raw HTML you see there is due to some bad interaction between the Jekyll sidenote plugin code and the markdown pre-processor. </span>
are handled <em>especially poorly</em>.
<code>
As in `not&lt;label for='code-test' class='margin-toggle sidenote-number'&gt;&lt;/label&gt;&lt;input type='checkbox' id='code-test' class='margin-toggle'/&gt;&lt;span class='sidenote'&gt;This is not fine &lt;/span&gt; good.
</code></p></li>
</ul>


<a name="L.a.id..on-bulleted-lists....a.On.Bulleted.Lists"></a>
<h2><a id="on-bulleted-lists"></a>On Bulleted Lists</h2>

<p>Speaking of bulleted lists: I implied up above that Tufte has a
problem with the use of bulleted lists, and that this is why the
standard <a href="https://edwardtufte.github.io/tufte-css/">tufte-css</a> does away with
them.<label for='is-ul-really-gone' class='margin-toggle sidenote-number'></label><input type='checkbox' id='is-ul-really-gone' class='margin-toggle'/><span class='sidenote'>Or rather, it does away with the bullet sigils, not unordered lists themselves. </span></p>

<p>If you are curious about Tufte&rsquo;s argument against the use of bulleted
lists, I highly recommend you pick up his essay
<a href="http://www.edwardtufte.com/tufte/books_pp">&ldquo;The Cognitive Style of PowerPoint&rdquo;</a>,<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Your local library is more likely to carry &ldquo;Beautiful Evidence&rdquo;
than the PowerPoint essay on its own (which one might deem a pamphlet).
Alternatively, you can also
<a href="http://www.edwardtufte.com/tufte/ebooks">purchase</a>
the Powerpoint essay as a PDF-format e-book on Tufte&rsquo;s website.
</span>
(which you can acquire on its own, or can be found as a chapter of his book
<a href="http://www.edwardtufte.com/tufte/books_be">&ldquo;Beautiful Evidence&rdquo;</a>).</p>

<p>For me, when writing markdown, the visible bullets serve a purpose.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
According to some conventions, my argument here is a strawman,
because I have already failed by putting more than six words on a
single bullet (&ldquo;any more words per bullet, and you don&rsquo;t have a
bullet.&rdquo;). I do not really have an argument against that,
(except that Tufte himself seems to lambast such rules of thumb).
</span></p>

<ul>
<li><p>In particular, I sometimes attach more than one paragraph of text
to an item in an unordered list.</p></li>
<li><p>But if I associate more than one paragraph of text with an item on
such a list, then without the visible bullet, one cannot readily
tell whether the new paragraph has started a new item, &hellip;</p>

<p>&hellip; or if it is a continuation of the previous item.</p></li>
<li><p>Then again, since the standard Octopress format does not indent
unordered lists, the same problem arises unless one
customizes<label for='scss-indented-list' class='margin-toggle sidenote-number'></label><input type='checkbox' id='scss-indented-list' class='margin-toggle'/><span class='sidenote'>See the <code>$indented-lists</code> variable in <code>_layout.scss</code> </span>
its SCSS to turn it on. (I tried this, but it ends up being more
trouble than its worth in terms of it breaking other things in the
CSS implementing this main-and-margin presentation.)</p></li>
<li><p>Have you noticed that the indentation of the margin notes
that are attached to list-elements are a little screwy?</p>

<ul>
<li><p>This is because of how the CSS is implemented; the main content elements
(like <code>p</code>, <code>ul</code>, et cetera) are all assigned <code>width: 60%</code>,
so that the remaining 40% is available for the margin content,
which is then assigned <code>margin-right: -40%</code> in the CSS.</p></li>
<li><p>The problem, as far as I can tell, is that the <code>-40%</code> is computed
relative to the width of the parent element.<label for='relative-margins-and-list-indents' class='margin-toggle sidenote-number'></label><input type='checkbox' id='relative-margins-and-list-indents' class='margin-toggle'/><span class='sidenote'>When list content gets indented, the width of a list element is less than that of paragraphs in the main text, and so its computed <code>margin-right: -40%</code> is a bit smaller than that for other margin content, causing a slight (but annoyingly noticeable) difference. </span></p></li>
<li><p>(Update: For that matter, the <em>width</em> of the text in nested list elements,
 like this one, does not play well with the margin content; the text
 of the list element in the main column is creeping into the margin.)</p></li>
<li><p>I have spent some time trying to puzzle this out, but at this point
I am willing to just say &ldquo;avoid attaching margin content to list
elements.&rdquo;</p></li>
</ul>
</li>
</ul>


<p>I <em>am</em> trying to learn how to make my blog posts more stream of thought
(for quick generation and publication), rather than carefully crafted
pieces of art. The bulleted list approach certainly provides a
quick-and-dirty way to do that.<label for='long-text' class='margin-toggle sidenote-number'></label><input type='checkbox' id='long-text' class='margin-toggle'/><span class='sidenote'>Speaking of quick-and-dirty, here is some really long text because I want to see what happens to the horizontal rule that divides the two parts of the main text below. At first different browsers handled the rendering in different ways; but now I have customized my SCSS so that <code>hr</code> has the same <code>width</code> constraint as a <code>p</code> element. </span></p>

<p>Update: a draft verison of this blog post had an <code>hr</code>-element between the
previous paragraph and this point in the text. Then shortly before publication,
I changed the <code>hr</code>-element to a new section heading, and didn&rsquo;t notice that
the fix I had put into the CSS to make the span of <code>hr</code>-element shorter
did not apply to the dotted line being rendered above the section header.</p>

<hr />

<p>So, now (post publication) I have put back in an <code>hr</code>-element at roughly the point
I expect it in the text.</p>

<a name="How.d.He.Do.Dat."></a>
<h2>How&rsquo;d He Do Dat?</h2>

<p>So how did I do all this?</p>

<p>I started by copying the <a href="http://clayh53.github.io/tufte-jekyll/articles/15/tufte-style-jekyll-blog">tufte-jekyll</a> plugins and SCSS support
files into my blog source tree. Since I use Octopress, I had to move
things around a bit:</p>

<ol>
<li><p>The <code>tufte.scss</code> that you find in tufte-jekyll&rsquo;s <code>css/</code>
needs to go somewhere; I put a copy of it into <code>sass/custom</code>.</p>

<p>Then I made a copy of the copy and named it <code>_fsk_tufte.scss</code><label for='on-renaming' class='margin-toggle'> &#8853;</label><input type='checkbox' id='on-renaming' class='margin-toggle'/><span class='marginnote'>In truth, the renamed copy came later, but it is good practice and simplifies the current discussion to assume I did it at the outset. </span></p></li>
<li><p>After putting the <code>.scss</code> files into place, I had to actually load the
main one into the Jekyll&rsquo;s page generation system. That is accomplished
via an <code>@import</code> in <code>sass/custom/_styles.scss</code>:</p>

<pre><code>@import "fsk_tufte";
</code></pre></li>
<li><p>Running the <code>rake generate</code> task to generate the CSS and the pages showed that
there were references to undefined variables like <code>$constrast-color</code>.
I skimmed through <code>fsk_tufte.scss</code> and either removed such references
or figured out where those variables were defined in the original
tufte-jekyll source repository, and ported them over accordingly.
For example, <code>$contrast-color</code> was defined in <code>_sass/_settings.scss</code>;
I cut-and-pasted it into <code>sass/custom/_color.scss</code>.</p></li>
<li><p>I initially copied all of the plugins from tufte-jekyll&rsquo;s
<code>_plugins/</code> into my <code>plugins/</code>.</p></li>
<li><p>Even after doing this, a lot of things were broken. I spent a <em>long</em>
time with a web browser&rsquo;s &ldquo;Inspect Element&rdquo; tool, comparing how
the tufte-jekyll post was being rendered to how my own draft blog
post was rendered.</p>

<p>Over the course of doing this, I found it necessary to revise my
<code>_fsk_tufte.scss</code> in myriad ways.</p></li>
</ol>


<a name="Revisions.to._fsk_tufte.scss"></a>
<h3>Revisions to _fsk_tufte.scss</h3>

<ol>
<li><p>I removed any content that I hypothesized was not related to my
margin-rendering related goals. For example, <code>tufte.scss</code>
automatically increases the font size as the browser window
width increases. I find this distracting as a programmer (and
annoying as a reader), so I removed it.</p></li>
<li><p>I changed the footnote font-size selection strategy.</p>

<ul>
<li><p>Tufte-jekyll&rsquo;s strategy is to use <code>1.0rem</code><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
&ldquo;rem&rdquo; stands for &ldquo;root em&rdquo; which in turn means &ldquo;unit equal to the
height of a capital M in the root (i.e. <code>html</code>) element of the document&rdquo;
</span>
as the <code>font-size</code> for the margin text and then scaling up the font-size
for the main content to be <code>1.4rem</code> (so that the main text ends up 1.4x
the size of the margin text).</p></li>
<li><p>I instead used <code>font-size: 0.8rem;</code> for margin text, and leave the
font-size for the main text unchanged (so that in principle it will
remain at <code>1rem</code>).</p></li>
<li><p>My reasoning here is that the majority of the text should be
occurring in the main content area, and we should be respecting
the font settings chosen by the user in their browser for such
text. If the user has selected a font size of 14, then that is
what we should use for the main text; we should not be using 14
for the margin notes and scale the main text up to 1.4*14 (=
19.6).</p></li>
</ul>
</li>
<li><p>After I noticed that my main-and-margin presentation style was
begin applied even to things like the <em>sidebar</em> of the blog,
I added guards to all of the relevant parts of <code>_fsk_tufte.scss</code>
so that the main-and-margin styling <em>only</em> applies to elements
that occur within an <code>article</code> element (since the main content
blocks always fall under an article).</p>

<p>Those were rules like this:</p>

<pre><code>// If a `ul`/`ol` occurs *immediately* (&gt;) under an `article`
article &gt; ul, article &gt; ol {
    width: 60%
}
</code></pre>

<p>I also added customization to try to avoid double-applications of
the percentage-based width restrictions; for example, I added
a rule like:</p>

<pre><code>p, ul, ol { p, ul, ol: width: 100 }
</code></pre>

<p>Update: Then I discovered that:</p>

<ol>
<li><p>this rule was not necessary for the cases where I had originally needed it,</p></li>
<li><p>it is not actually being applied since it is overridden by other rules
 (presumably due to some resolution logic for CSS that I have not digested),
 and,</p></li>
<li><p>if you get it to apply, it has a negative overall effect on
 e.g. nested lists: it causes them to be assigned a width corresponding
 to main <em>plus</em> margin. (Clearly my mental model of what how these percentages
 relate to the parent element is flawed in various ways.)</p></li>
</ol>


<p>So I have since removed that last rule.</p></li>
</ol>


<p>Anyway, those are the main customizations of the SCSS that I can think
of off-hand. You can of course just go peek at <a href="https://github.com/pnkfelix/pnkfx-blog/">its source code</a>
if you want to see what it currently looks like (and perhaps offer
tips on how I might revise it).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GC and Rust Part 1: Specifying the Problem]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/"/>
    <updated>2015-11-10T17:45:00-05:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem</id>
    <content type="html"><![CDATA[<p>This is the first in a series of posts will discuss why garbage
collection is hard, especially for Rust, and brainstorm about
solutions to the problems we face.</p>

<p>The relationship between garbage collection (GC) and the Rust
programming language has been an interesting one.</p>

<p>GC was originally deeply integrated into the language, complete with
dedicated syntax (good old <code>@T</code> &hellip;). Over time the team found ways to
lessen the dependency on GC, and then finally remove it from the
language entirely.</p>

<p>However, we still want to provide support for garbage collection.</p>

<p>To explain why, I need to define the actual problems we seek to solve.
So let us explore the problem space.</p>

<!-- more -->


<a name="L.....now.you.have..nyh..two.problems"></a>
<h1>&hellip; <a href="http://regex.info/blog/2006-09-15/247">now you have</a> two problems</h1>

<p>(The body of this post makes heavy use of client-side rendering,
because of author idiosyncrasies.  You may need to wait a moment while
the supporting Javascript loads.)</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/js_to_dot.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/gc_rendering.js" charset="utf-8"></script>


<a name="The.Problem.Space"></a>
<h2>The Problem Space</h2>

<p>Now that we have <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/">reviewed</a> what GC is and how it works, let us
discuss what GC could mean to Rust.</p>

<p>I have identified two distinct kinds of support that we could provide:
&ldquo;GC&rdquo; could describe a feature for pure Rust programs, or &ldquo;GC&rdquo; could mean a
3rd-party runtime interoperation feature. Let us discuss each in turn.</p>

<a name="One.GC.shared.by.every.crate"></a>
<h3>One GC shared by every crate</h3>

<p>We could add a smart-pointer to <code>libstd</code>, e.g. a <code>Gc&lt;T&gt;</code> type, that
arbitrary library crates could use as they create or receive instances
of <code>T</code>. The intention here would be similar to how <code>Rc&lt;T&gt;</code> is used:
One does not want to track ownership precisely, but rather treat
ownership as shared amongst all users of a value, and let the runtime
system handle reclaiming the value.</p>

<p>So for example, we might want to write code that looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kn">use</span> <span class="n">std</span><span class="o">::</span><span class="n">gc</span><span class="o">::</span><span class="n">Gc</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">Cons</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">head</span><span class="o">:</span> <span class="n">T</span><span class="p">,</span>
</span><span class='line'>    <span class="n">tail</span><span class="o">:</span> <span class="n">Cell</span><span class="o">&lt;</span><span class="nb">Option</span><span class="o">&lt;</span><span class="n">Gc</span><span class="o">&lt;</span><span class="n">Self</span><span class="o">&gt;&gt;&gt;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">Cons</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">new</span><span class="p">(</span><span class="n">head</span><span class="o">:</span> <span class="n">T</span><span class="p">,</span> <span class="n">tail</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">Gc</span><span class="o">&lt;</span><span class="n">Self</span><span class="o">&gt;&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Self</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">Cons</span> <span class="p">{</span> <span class="n">head</span><span class="o">:</span> <span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="o">:</span> <span class="n">Cell</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">head</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">T</span> <span class="p">{</span> <span class="o">&amp;</span><span class="bp">self</span><span class="p">.</span><span class="n">head</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">tail</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">Gc</span><span class="o">&lt;</span><span class="n">Self</span><span class="o">&gt;&gt;</span> <span class="p">{</span> <span class="bp">self</span><span class="p">.</span><span class="n">tail</span><span class="p">.</span><span class="n">get</span><span class="p">()</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#[test]</span>
</span><span class='line'><span class="k">fn</span> <span class="n">demo</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">f</span><span class="o">:</span> <span class="n">Gc</span><span class="o">&lt;</span><span class="n">_</span><span class="o">&gt;</span><span class="p">;</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>            <span class="n">a</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">None</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">b</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">a</span><span class="p">));</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">c</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">a</span><span class="p">));</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">d</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">b</span><span class="p">));</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">e</span><span class="o">:</span> <span class="n">Gc</span><span class="o">&lt;</span><span class="n">_</span><span class="o">&gt;</span><span class="p">;</span>
</span><span class='line'>            <span class="n">e</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">b</span><span class="p">));</span>
</span><span class='line'>            <span class="n">f</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">d</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>        <span class="kd">let</span> <span class="k">mut</span> <span class="n">g</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="nb">None</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">let</span>     <span class="n">h</span> <span class="o">=</span> <span class="k">box</span> <span class="n">Cons</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="nb">Some</span><span class="p">(</span><span class="n">g</span><span class="p">));</span>
</span><span class='line'>        <span class="n">g</span><span class="p">.</span><span class="n">tail</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">h</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="c1">// here, locals `a` and `f` are the roots</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(The above snippet assumes we have extended <code>box EXPR</code> to an
overloaded operator in the manner similar to that described in
<a href="https://github.com/rust-lang/rfcs/blob/master/text/0809-box-and-in-for-stdlib.md">RFC 809</a>, so that <code>let g: Gc&lt;_&gt; = box EXPR;</code> works, and that
the type inference figures out that all the locals need to be
in <code>Gc&lt;_&gt;</code>.)</p>

<p>This results in a stack and heap modelled by this picture.</p>

<p id="target_anchor_gc_demo_1" class="fullwidth"></p>


<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };
var a = object_record("A", "<head> head: 1 | <tail> tail: None");
var b = object_record("B", "<head> head: 2 | <tail> tail: Some(A)");
var c = object_record("C", "<head> head: 3 | <tail> tail: Some(A)");
var d = object_record("D", "<head> head: 4 | <tail> tail: Some(B)");
var e = object_record("E", "<head> head: A | <tail> tail: Some(B)");
var f = object_record("F", "<head> head: C | <tail> tail: Some(D)");
var g = object_record("G", "<head> head: 10 | <tail> tail: Some(H)");
var h = object_record("H", "<head> head: 20 | <tail> tail: Some(G)");

var local_a = { id: "local_a", label: "a", shape: "record" };
var local_f = { id: "local_f", label: "f", shape: "record" };

stack[1] = local_a;
stack[2] = local_f;

b.tail = edge_from_port(":tail", a);
c.tail = edge_from_port(":tail", a);
d.tail = edge_from_to_ports(":tail", ":id", b);
e.head = edge_from_port(":head", a);
e.tail = edge_from_to_ports(":tail", ":id", b);
f.head = edge_from_to_ports(":head", ":id", c);
f.tail = edge_from_to_ports(":tail", ":id", d);
g.tail = edge_from_to_ports(":tail", ":id", h);
h.tail = edge_from_to_ports(":tail", ":id", g);

local_a.ref = a;
local_f.ref = edge_to_port(":id", f);

gc_heap[0] = a;
gc_heap[1] = b;
gc_heap[2] = c;
gc_heap[3] = d;
gc_heap[4] = e;
gc_heap[5] = f;
gc_heap[6] = g;
gc_heap[7] = h;

var objects = [stack, gc_heap];
post_objects("target_anchor_gc_demo_1", objects, { rankdir:"LR", nodesep:0.2, no_dims:true });
</script>


<p>The GC would be allowed to collect the objects labelled &ldquo;E&rdquo;, &ldquo;G&rdquo;, and
&ldquo;H&rdquo; in the picture, since they are not reachable from the roots.
(However, the GC is not obligated to reclaim them at any particular
time. Usually GC&rsquo;s provide little guarantees about how soon objects
will be reclaimed.)</p>

<p>This kind of feature could be useful in any Rust library.</p>

<a name="Advantages.of.Gc.T..over.Rc.T."></a>
<h4>Advantages of Gc<T> over Rc<T></h4>

<p>The main hypothesized advantages over <code>Gc&lt;T&gt;</code> over <code>Rc&lt;T&gt;</code> are:</p>

<ul>
<li><p><code>Gc&lt;T&gt;</code> is <code>Copy</code>, which makes it possible to construct types like
<code>Cell&lt;Gc&lt;T&gt;&gt;</code>.</p>

<p>(It also has nicer programmer ergonomics in some cases; e.g. some
programmers dislike having to write <code>x.clone()</code> every time they
want to make a copy of ref-counted <code>x</code>.)</p></li>
<li><p><code>Gc&lt;T&gt;</code> allows cyclic structure to be reclaimed (e.g. the objects
 &ldquo;G&rdquo; and &ldquo;H&rdquo; in the picture above.</p></li>
<li><p>Using <code>Gc&lt;T&gt;</code> <em>might</em> have less overhead than <code>Rc&lt;T&gt;</code>: every time
you clone an <code>Rc&lt;T&gt;</code> it incurs reference-count overhead, while
<code>Gc&lt;T&gt;</code> just copies the reference.</p>

<p>(However, this stated advantage must be tempered by the
realization that GC incurs its own separate overheads, as
discussed in the <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/">background post</a>.</p></li>
</ul>


<a name="Drawbacks.of.one.GC.for.everyone"></a>
<h4>Drawbacks of one GC for everyone</h4>

<p>There are two immediate drawbacks with this kind of collector
support.</p>

<p>First, adding it would require that the standard library either
provide a garbage collector (that all clients of <code>Gc&lt;T&gt;</code> would have to
link in), or at least standardize a fixed API that third-party
collector implementations would have to satisfy to support <code>Gc&lt;T&gt;</code>.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In particular, smart-pointers in Rust
require at <em>least</em> support for the <a href="https://doc.rust-lang.org/std/ops/trait.Deref.html"><code>Deref</code> trait</a>, so
that dereferencing expressions like <code>gc_ref.field</code> and
<code>gc_ref.method()</code> are compiled into code that resolves the <code>gc_ref</code> to
a<code>&amp;T</code> reference (and then the subsequent field or method lookup is
performed with respect to that <code>&amp;T</code> reference).
<br></br>
As a reminder, the signature of the <code>deref</code> method, before lifetime
elision, is <code>fn deref&lt;'a&gt;(&amp;'a self) -&gt; &amp;'a Self::Target</code> (and the
associated <code>Target</code> type for <code>Gc&lt;T&gt;</code> would be <code>T</code>).  Thus, the
compiler will ensure that the reference <code>&amp;'a T</code> we extract from the
<code>gc_ref</code> outlive the <code>gc_ref</code> itself; this means that the <code>gc_ref</code>
will be one (of potentially many) root keeping the object from being
reclaimed for the entirety of the lifetime <code>'a</code>, and thus supporting
the <code>Deref</code> trait design on a <code>Gc&lt;T&gt;</code> could work seamlessly on an
entirely non-moving GC.
<br></br>
However, moving objects complicate <code>Deref</code> support; now one needs to
ensure not only that the object remains alive, but also that the
reference <code>&amp;'a T</code> consistently points to the same object that the
original <code>Gc&lt;T&gt;</code> pointed to, and that references to substructure
within the object (e.g. a <code>&amp;Left</code> within a <code>Gc&lt;(Left, Right)&gt;</code> that
has been deref'ed to <code>&amp;(Left, Right)</code>) also retain a consistent view
of the heap structure. Doing this at an acceptable cost is difficult;
I may discuss this more in a future post.
</span>
Second, it is difficult to provide the ergonomics that one expects
from a smart-pointer type analogous to
<code>Rc&lt;T&gt;</code>.</p>

<p>Okay, so that&rsquo;s the outline of the tradeoffs of providing
a &ldquo;GC for everyone&rdquo; in <code>libstd</code>.  What about a more limited
GC feature, where the audience is not &ldquo;every Rust crate&rdquo;, but instead
just the crates linking to a managed runtime.</p>

<a name="GC.as.Interoperation.Feature"></a>
<h3>GC as Interoperation Feature</h3>

<p>GC as an interoperation feature means that Rust would provide
introspective hooks to improve integration with application frameworks
that are using their own garbage collector. One example of this is
Servo&rsquo;s use of the SpiderMonkey Virtual Machine for its Javascript
support.</p>

<p>Servo is relying on SpiderMonkey&rsquo;s garbage collection for memory
management, not only for Javascript values, but even for
<a href="https://blog.mozilla.org/research/2014/08/26/javascript-servos-only-garbage-collector/">native-code DOM objects</a>.</p>

<p>That post describes (unchecked) scenarios where one can end up with
dangling pointers &ndash; that is, they invite unsoundness.  Proper support
for GC-interoperation in Rust could address this; I will discuss this
further down in this post.</p>

<p>Critically, GC-interoperation does not require the same level of
ergonomics that <code>Rc&lt;T&gt;</code> provides. For example, in this context it is
acceptable for <code>Gc&lt;T&gt;</code> to not support <a href="https://doc.rust-lang.org/std/ops/trait.Deref.html"><code>Deref</code></a>.</p>

<p>(Furthermore, in this context, it may even be acceptable to require
unchecked constraints like &ldquo;the programmer must ensure the collector
is not invoked during this extent&rdquo;, or perhaps &ldquo;the programmer must
periodically invoke a call that tells the GC that this is an
acceptable time to do collection work that could move objects.&rdquo;)</p>

<p>Without a <code>Deref</code> trait and with such unchecked requriements, such
interoperation might end up looking something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">double_last</span><span class="p">(</span><span class="n">x</span><span class="o">:</span> <span class="n">Gc</span><span class="o">&lt;</span><span class="n">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;&gt;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ptr</span><span class="o">:</span> <span class="o">*</span><span class="k">mut</span> <span class="n">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">x</span><span class="p">.</span><span class="n">get_ptr</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// during the extent of this block, it is the responsibility</span>
</span><span class='line'>        <span class="c1">// of the double_last author to ensure the GC never gets</span>
</span><span class='line'>        <span class="c1">// invoked (i.e., do not do any allocations to the GC&#39;ed heap</span>
</span><span class='line'>        <span class="c1">// during this unsafe-block).</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="nb">Some</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">).</span><span class="n">last_mut</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>            <span class="o">*</span><span class="n">i</span> <span class="o">=</span> <span class="o">*</span><span class="n">i</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this context, interoperation still requires defining a standard
interface that the third-party collector implementation has to conform
with.</p>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
In truth, even for a conservative collector like <a href="http://www.hboehm.info/gc/">BDW</a>,
one must do more than just &ldquo;swap in a new <code>#[allocator]</code>&rdquo; to actually
integrate it properly; the current Rust standard library does not
provide a way to intercept thread spawns and register the new
stack associated with each new thread.
<br></br>
I only realized this only <a href="https://github.com/swgillespie/boehm_gc_allocator/issues/2">recently</a>.
</span>
In a simple world (e.g., a conservative collector designed to
interoperate with C/C++, such as <a href="http://www.hboehm.info/gc/">boehm-demers-weiser</a> (BDW)), this
standard interface could be nothing more than just &ldquo;swap in a
different <a href="https://doc.rust-lang.org/nightly/book/custom-allocators.html">#[allocator] crate</a> that your GC provides.&rdquo;</p>

<p>(The actual interface is unlikely to be so
simple, but the point is, there is a wide
design space to be explored here.)</p>

<a name="Interoperation.with.a..black.box..GC"></a>
<h4>Interoperation with a &ldquo;black box&rdquo; GC</h4>

<p>One way to look at the difference between &ldquo;GC for pure Rust programs&rdquo;
versus &ldquo;GC for interoperation&rdquo; is that in the former case, the GC
feels deeply integrated with the language and standard library, while
in the latter case, the GC is clearly the concern of some entity
outside the language (and we are just trying to accommodate it as best
we can).</p>

<p>An extreme instance of a GC that is definitely an entity outside the
language is a case where the whole GC heap is treated like a black
box, and the objects inside the heap are never directly exposed to the
application code outside the box.</p>

<p>For example, one can imagine a virtual machine (VM) interface where
the code outside the VM is never given addresses of objects on the
heap. Instead, such foreign code only has <em>handles</em> that indirectly
point to those objects.</p>

<p id="target_anchor_black_box_gc_1" class="fullwidth"></p>


<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };
var handles = object_record("handles", "<h2> Y | <h1> X | <h3> X");

var c = object_record("C", "<f0> Gc(X) | <f1> Box(O)");
c.style = "rounded";
var o = object_record("O", "<f0> Handle(2)");
var x = object_record("X", "<f0> 'a' | <f1> next");
var y = object_record("Y", "<f0> 'b' | <f1> next");
var z = object_record("Z", "<f0> 'c' | <f1> (next)");
x.style = "rounded";
y.style = "rounded";
z.style = "rounded";
var local_x = { id: "local_x", label: "handle_x", shape: "record" };
var local_y = { id: "local_y", label: "handle_y", shape: "record" };
var local_o = { id: "local_o", label: "boxed_o", shape: "record" };

x.next = edge_from_to_ports(":f1", ":id:sw", y);
y.next = edge_from_to_ports(":f1", ":id", z);

o.f0 = edge_from_to_ports(":f0", ":h3", handles);

c.f0 = edge_from_to_ports(":f0", ":id", x);
c.f1 = edge_from_to_ports(":f1", ":id", o);

stack[1] = local_x;
stack[2] = local_y;
stack[3] = local_o;

rust_heap[0] = o;
gc_heap[0] = handles;
handles.x1 = edge_from_to_ports(":h1", ":id", x);
handles.y2 = edge_from_to_ports(":h2", ":id", y);
handles.x3 = edge_from_to_ports(":h3", ":id:sw", x);
local_x.handle = edge_to_port(":h1", handles);
local_y.handle = edge_to_port(":h2", handles);
local_o.box = edge_to_port(":id", o);
gc_heap[2] = x;
gc_heap[3] = y;
gc_heap[4] = z;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_black_box_gc_1", objects, { rankdir:"LR", nodesep:0.2, no_dims: true });
</script>


<p>In this setting, direct references to objects <em>never</em> escape the black
box. Instead, by setting up a level of indirection, the management of
the objects within the GC heap is completely abstracted away.</p>

<p>In a black box GC setting, one would not expose the data structure of
the objects (since they can never be directly addressed
anyway). Instead, one would define functions on handles that extract
the fields and maps them to handles when necessary:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">extern</span> <span class="k">fn</span> <span class="n">handle_data</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="n">Handle</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">char</span><span class="p">;</span>
</span><span class='line'><span class="k">extern</span> <span class="k">fn</span> <span class="n">handle_next</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="n">Handle</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">Handle</span><span class="o">&gt;</span><span class="p">;</span>
</span><span class='line'><span class="k">extern</span> <span class="k">fn</span> <span class="n">handle_set_next</span><span class="p">(</span><span class="n">a</span><span class="o">:</span> <span class="n">Handle</span><span class="p">,</span> <span class="n">b</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">Handle</span><span class="o">&gt;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// sample code interacting with the black box GC</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// all of these predicates hold of the above heap diagram</span>
</span><span class='line'><span class="n">assert_eq</span><span class="o">!</span><span class="p">(</span><span class="n">handle_data</span><span class="p">(</span><span class="n">handle_x</span><span class="p">),</span> <span class="sc">&#39;a&#39;</span><span class="p">);</span>
</span><span class='line'><span class="n">assert_eq</span><span class="o">!</span><span class="p">(</span><span class="n">handle_data</span><span class="p">(</span><span class="n">handle_next</span><span class="p">(</span><span class="n">handle_y</span><span class="p">).</span><span class="n">unwrap</span><span class="p">()),</span> <span class="sc">&#39;c&#39;</span><span class="p">);</span>
</span><span class='line'><span class="n">assert</span><span class="o">!</span><span class="p">(</span><span class="n">handle_next</span><span class="p">(</span><span class="n">handle_next</span><span class="p">(</span><span class="n">handle_y</span><span class="p">).</span><span class="n">unwrap</span><span class="p">()).</span><span class="n">is_none</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// this changes the heap to match the diagram below.</span>
</span><span class='line'><span class="n">handle_set_next</span><span class="p">(</span><span class="n">handle_x</span><span class="p">,</span> <span class="n">handle_next</span><span class="p">(</span><span class="n">handle_y</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor_black_box_gc_2" class="fullwidth"></p>




<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };
// var handles = object_record("handles", "<h2> Y | <h1> X | <h3> X | <h4> (temp for Z)");
var handles = object_record("handles", "<h2> Y | <h1> X | <h3> X");

var c = object_record("C", "<f0> Gc(X) | <f1> Box(O)");
c.style = "rounded";
var o = object_record("O", "<f0> Handle(2)");
var x = object_record("X", "<f0> 'a' | <f1> next");
var y = object_record("Y", "<f0> 'b' | <f1> next");
var z = object_record("Z", "<f0> 'c' | <f1> (next)");
x.style = "rounded";
y.style = "rounded";
z.style = "rounded";
var local_x = { id: "local_x", label: "handle_x", shape: "record" };
var local_y = { id: "local_y", label: "handle_y", shape: "record" };
var local_o = { id: "local_o", label: "boxed_o", shape: "record" };

x.next = edge_from_to_ports(":f1", ":id:w", z);
y.next = edge_from_to_ports(":f1", ":id:n", z);

o.f0 = edge_from_to_ports(":f0", ":h3", handles);

c.f0 = edge_from_to_ports(":f0", ":id", x);
c.f1 = edge_from_to_ports(":f1", ":id", o);

stack[1] = local_x;
stack[2] = local_y;
stack[3] = local_o;

rust_heap[0] = o;
gc_heap[0] = handles;
handles.x1 = edge_from_to_ports(":h1", ":id", x);
handles.y2 = edge_from_to_ports(":h2", ":id", y);
handles.x3 = edge_from_to_ports(":h3", ":id:sw", x);
// handles.z4 = edge_from_to_ports(":h4", ":id:sw", z);
local_x.handle = edge_to_port(":h1", handles);
local_y.handle = edge_to_port(":h2", handles);
local_o.box = edge_to_port(":id", o);
gc_heap[2] = x;
gc_heap[3] = y;
gc_heap[4] = z;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_black_box_gc_2", objects, { rankdir:"LR", nodesep:0.2, no_dims: true });
</script>


<p>In case it isn&rsquo;t clear, supporting interoperation with this kind of
&ldquo;black box&rdquo; GC requires very little from the Rust side; potentially
nothing at all. The object addresses are hidden, so the GC could move
an object and update its address in the handle
array.<label for='handles' class='margin-toggle'> &#8853;</label><input type='checkbox' id='handles' class='margin-toggle'/><span class='marginnote'>If the GC Heap is exposed to multiple threads, then there are complications even with the seemingly simple task of updating the handles array, since one must ensure that if two threads have consistent views of the heap object graph. </span></p>

<p>However, this so-called interoperation is also quite limited in
expressiveness. The defining property of the &ldquo;black box&rdquo; GC, the fact
that it does not expose the addresses of the objects held within, also
means that we cannot expose <code>&amp;</code>-references to the objects or the state
within them, which means we cannot use these objects with the large
number of Rust functions that operate on <code>&amp;</code>-references and slices.</p>

<a name="Digression.on.limits.of..black.box..GC"></a>
<h3>Digression on limits of &ldquo;black box&rdquo; GC</h3>

<p>In addition to the limits regarding exposure of <code>&amp;</code>-references
described above, another issue with &ldquo;black box&rdquo; GC is that
it is not clear whether client code hooking
into the &ldquo;black box&rdquo; GC would be able to instantiate the GC objects
with its own types.</p>

<p>For example, one might think that the objects in the GC heap could be
defined via type parameterization: <code>fn bbox_gc_alloc&lt;T&gt;(t: T) -&gt; Handle;</code>
would create an object on the heap, copy <code>t</code> into it, and return a
handle to that object.</p>

<p>For this to work, the layout of the list cells in the GC heap above
would need to look something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">Cons</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">data</span><span class="o">:</span> <span class="n">T</span><span class="p">,</span>
</span><span class='line'>    <span class="n">next</span><span class="o">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">GcPtr</span><span class="o">&lt;</span><span class="n">Cons</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;&gt;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then constructing a list like the &ldquo;X, Y, Z&rdquo; in the heap diagrams
above would look like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="kd">let</span> <span class="n">handle_z</span> <span class="o">=</span> <span class="n">bbox_gc_alloc</span><span class="p">(</span><span class="n">Cons</span> <span class="p">{</span> <span class="n">data</span><span class="o">:</span> <span class="sc">&#39;c&#39;</span><span class="p">,</span> <span class="n">next</span><span class="o">:</span> <span class="nb">None</span> <span class="p">});</span>
</span><span class='line'><span class="kd">let</span> <span class="n">handle_y</span> <span class="o">=</span> <span class="n">bbox_gc_alloc</span><span class="p">(</span><span class="n">Cons</span> <span class="p">{</span> <span class="n">data</span><span class="o">:</span> <span class="sc">&#39;b&#39;</span><span class="p">,</span> <span class="n">next</span><span class="o">:</span> <span class="nb">None</span> <span class="p">});</span>
</span><span class='line'><span class="kd">let</span> <span class="n">handle_x</span> <span class="o">=</span> <span class="n">bbox_gc_alloc</span><span class="p">(</span><span class="n">Cons</span> <span class="p">{</span> <span class="n">data</span><span class="o">:</span> <span class="sc">&#39;a&#39;</span><span class="p">,</span> <span class="n">next</span><span class="o">:</span> <span class="nb">None</span> <span class="p">});</span>
</span><span class='line'><span class="n">handle_set_next</span><span class="p">(</span><span class="n">handle_y</span><span class="p">,</span> <span class="n">handle_z</span><span class="p">);</span>
</span><span class='line'><span class="n">handle_set_next</span><span class="p">(</span><span class="n">handle_x</span><span class="p">,</span> <span class="n">handle_y</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>But there are two (related) problems:</p>

<ol>
<li><p>How does one instantiate values that <em>unconditionally</em> hold
 pointers to GC objects.  (For example, how do we allocate an
 instance of <code>Cons&lt;GcPtr&lt;Cons&lt;char&gt;&gt;&gt;</code>?)
 <br></br>
 We have already established that the address in the GC Heap are
 not exposed outside of the heap, so the approach of passing in an
 <code>T</code> value that we used with <code>bbox_gc_alloc</code> above will not work,
 because we cannot put our hands on a <code>GcPtr</code> to use for the
 <code>data</code> field.</p></li>
<li><p>How do we get from the <code>struct</code> definition for <code>Cons</code> to
 the family of methods defined in terms of <code>Handle</code>?
 <br></br>
 Every occurrence of <code>GcPtr</code> used for the struct (as seen from
 the point of view of the GC Heap) needs to be mapped to
 a <code>Handle</code> in the functions exposed to the functions outside
 of GC Heap.</p></li>
</ol>


<p>Also, the hidden object addresses may complicate client code trying to
instantiate GC objects with its own types.</p>

<p>It could be that there is a solution to the problem lurking here.
In any case, interoperation with a blackbox GC is not a primary goal,
since the level of indirection and (perhaps more crucially)
the maintenance of the handles array are not ideal.</p>

<a name="Objectives.and.Requirements..oh.no..now.five.problems."></a>
<h2>Objectives and Requirements (oh no, now five problems)</h2>

<p>The two (or perhaps three) kinds of support described above are
distinct features; there is overlap between them, but trying to find a
single solution that solves both problems completely may not be
possible, and in any case we do not want to wait for that single
solution to be discovered.</p>

<p>Since <code>Rc&lt;T&gt;</code> is already a workable solution for many (though not all)
use cases of <code>Gc&lt;T&gt;</code>, the above idealized &ldquo;one GC shared by every
crate&rdquo; is not a main priority right now (and may never be added to the
Rust language).</p>

<p>Let us focus on GC as an interop feature, and dive into what we would
want to get out of it.</p>

<p>There are a number of objectives for Rust/GC integration that are
worth noting, which I will list here and then define and discuss
below.</p>

<ol>
<li><a href="#safety">Safe</a></li>
<li><a href="#modularity">Modular</a></li>
<li><a href="#zero-cost">Zero-Cost</a></li>
<li><a href="#compositionality">Compositional</a></li>
<li><a href="#precision">Precise (Space-Efficient)</a></li>
</ol>


<a name="L.span.id..safety..Safety.with.respect.to.GC..span."></a>
<h3><span id="safety">Safety with respect to GC</span></h3>

<p>If a Rust crate does not use <code>unsafe</code> constructs (<code>unsafe</code> blocks,
attributes or types with &ldquo;unsafe&rdquo; in their name, etc.), then linking
it with a sound set of crates that use GC must maintain soundness.</p>

<p>In other words, linking in a crate that uses no <code>unsafe</code> construct
should not inject any dereferences of dangling pointers, nor any data
races.</p>

<p>By the way, we absolutely do need to provide criteria that says what
<code>unsafe</code> code <em>is</em> allowed to do when linked with a crate that uses
GC. I am going to assume for these initial posts that we will solve
that problem eventually, but not attempt to address it at the outset.</p>

<a name="L.span.id..modularity..Modularity.with.respect.to.GC..span."></a>
<h3><span id="modularity">Modularity with respect to GC</span></h3>

<p>A Rust program that uses GC should be able to link to a crate whose
source code was authored without knowledge of GC.</p>

<p>For example, if I make a parsing library today that works on string
slices <code>&amp;str</code>, you should be able to link that parsing library into a
program that uses GC, without having to worry about whether the
parsing library carries hidden requirements that invalidate
assumptions made by the GC.</p>

<p>Note: A crate being &ldquo;authored without knowledge of GC&rdquo; is a
property of the source code, not the generated object code. Given
such a crate, the Rust compiler may itself inject metadata
related to GC, such as descriptions of object layout, or
automatically-generated code that dictate how objects should
traced by the collector.</p>

<p>Note: A crate being &ldquo;authored without knowledge of GC&rdquo; is entirely
distinct a crate not supporting GC. That is, we may add well a way for
a crate to declare that it is not compatible with GC. (This would
count as having knowledge of GC; in fact, enough knowledge to know, or
at least guess, that its presence would cause the GC to break, or vice
versa.)</p>

<p>If we cannot satisfy this requirement, then the addition of GC
will, at best, split the growing space of library crates (such as
those available on <a href="https://crates.io/">crates.io</a>) into two disjoint
sub-communities: crates that support GC, and those that do not
(since the latter were written without accounting for the
potential presence of a GC).</p>

<p>An aside: I would really like to find a way to combine the
descriptions of &ldquo;modularity&rdquo; and &ldquo;safety&rdquo;, since they seem to be
attempted to express similar or related objectives.</p>

<p>A final note: There are some features available to crates, such as
requiring a specific low-level allocator, that are likely to be
incompatible with a program that uses GC. We need to define these
caveats and incorporate them into the above definition of
&ldquo;modularity&rdquo;, without weakening it to the point of uselessness.
(However, I will not attempt to tackle that here.)</p>

<a name="L.span.id..zero-cost..Zero-Cost.GC..span."></a>
<h3><span id="zero-cost">Zero-Cost GC</span></h3>

<p>If you don&rsquo;t use the GC feature (in whatever form it takes), your code
should not pay for it.</p>

<p>This applies to the quality of the generated code (in execution
time and code size), and also to the source code, with respect to
difficulty in writing a program or library.</p>

<p>There are two forms of the zero-cost property relevant here:</p>

<ol>
<li><p>Strongly zero-cost: A unit of code generation that does not use
 GC should not pay for it.</p>

<p> For example, in the above example of the string parsing module,
 ideally the code generated for parsing <code>&amp;str</code> values should have
 the same performance characteristics, regardless of whether it is
 linked into a program that uses GC or not.</p></li>
<li><p>Weakly zero-cost: A program that does not use GC should not pay
 for it.</p>

<p> (At worst, one can imagine ensuring this property by compiling
 two different versions of each code unit, and then linking to the
 appropriate one. Hopefully we will not need to resort to that.)</p></li>
</ol>


<p>Strongly zero-cost implies weakly zero-cost, but not vice-versa.</p>

<a name="L.span.id..compositionality..Compositional.GC..span."></a>
<h3><span id="compositionality">Compositional GC</span></h3>

<p>One can use a reference to a gc-allocated object (call it a <code>GcRef</code>)
as the field type in a <code>struct</code>, store it into a <code>Vec&lt;GcRef&gt;</code>, and
in general do anything with it that one can do with a normal Rust value.</p>

<p>Furthermore, one should be able to describe, via a Rust type
definition, the layout of a value allocated on the GC heap, allocate
such values there, and acquire a suitable <code>GcRef</code> to the allocated
object.</p>

<p>To be concrete about this, consider the following program,
which uses a hypothetical <code>make_gc_ref</code> function to move
values into a newly-allocated spot on the GC heap, and returns
a reference to that spot. (In the future one will probably use
the <code>box</code> syntax for this, and rely on type-context to inform
box that this is a GC-allocation.)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">demo</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">gc_v</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ref_x1</span> <span class="o">=</span> <span class="n">make_gc_ref</span><span class="p">(</span><span class="s">&quot;data_one&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ref_x2</span> <span class="o">=</span> <span class="n">make_gc_ref</span><span class="p">(</span><span class="s">&quot;data_two&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">v</span> <span class="o">=</span> <span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="n">x1</span><span class="p">,</span> <span class="n">x1</span><span class="p">,</span> <span class="n">x2</span><span class="p">];</span>
</span><span class='line'>        <span class="n">make_gc_ref</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This results in the following diagram:</p>

<p id="target_anchor_demo_composition_1"></p>


<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var x1 = object_record("X1", "<f0> 'data_one'");
var x2 = object_record("X2", "<f0> 'data_two'");

x1.style = "rounded";
x2.style = "rounded";

var gc_v = { id: "gc_v", label: "Gc(V)", shape: "record" };

var v = object_record("V", "<f0> len: 3 | cap: 4 | <f2> ptr: Arr");
v.style = "rounded";
var arr = object_record("Arr", "<f0> Gc(X1) | <f1> Gc(X1) | <f2> Gc(X2)");
arr.color = "blue";

v.f2 = edge_from_to_ports(":f2", ":id", arr);
gc_v.f0 = edge_to_port(":id", v);

arr.f0 = edge_from_to_ports(":f0", ":id", x1);
arr.f1 = edge_from_to_ports(":f1", ":id", x1);
arr.f2 = edge_from_to_ports(":f2", ":id", x2);

stack[0] = gc_v;
rust_heap[0] = arr;
gc_heap[0] = v;
gc_heap[1] = x1;
gc_heap[2] = x2;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_demo_composition_1", objects, { rankdir:"LR", nodesep:0.2 });
</script>


<p>Here, I have made explicit the heap-allocated backing store <code>Arr</code> (in
blue) for the vector that holds the references to <code>x1</code> and <code>x2</code>.</p>

<p>This shows that if we want GC to reasonably usable (i.e., allow GC
references to be used like other Rust values), we need to support
references out of the GC heap and into the Rust heap, and likewise
references out of the Rust heap and into the GC heap.</p>

<p>It can sometimes be simpler (without necessarily eliminating the
fundamental problem) to just a <code>Box</code> rather than a <code>Vec</code>:</p>

<p id="target_anchor_demo_composition_2"></p>


<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };
var c = object_record("C", "<f0> Gc(X) | <f1> Box(O)");
c.style = "rounded";
var o = object_record("O", "<f0> Gc(X)");
var x = object_record("X", "<f0> 'data'");
x.style = "rounded";
var gc_a = { id: "gc_c", label: "Gc(C)", shape: "record" };

gc_a.f0 = edge_to_port(":id", c);

o.f0 = edge_from_to_ports(":f0", ":id", x);

c.f0 = edge_from_to_ports(":f0", ":id", x);
c.f1 = edge_from_to_ports(":f1", ":id", o);

stack[0] = gc_a;
rust_heap[0] = o;
gc_heap[0] = c;
gc_heap[1] = x;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_demo_composition_2", objects, { rankdir:"LR", nodesep:0.2, no_dims: true });
</script>


<p>The program to construct the above picture might look like
this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">demo</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">C</span><span class="p">(</span><span class="n">Gc</span><span class="o">&lt;</span><span class="kt">str</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Box</span><span class="o">&lt;</span><span class="n">Gc</span><span class="o">&lt;</span><span class="kt">str</span><span class="o">&gt;&gt;</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">let</span> <span class="n">gc_c</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">ref_x</span> <span class="o">=</span> <span class="n">make_gc_ref</span><span class="p">(</span><span class="s">&quot;data&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">let</span> <span class="n">box_o</span> <span class="o">=</span> <span class="n">Box</span><span class="o">::</span><span class="n">new</span><span class="p">(</span><span class="n">ref_x</span><span class="p">);</span>
</span><span class='line'>        <span class="n">make_gc_ref</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">ref_x</span><span class="p">,</span> <span class="n">box_o</span><span class="p">))</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(The types in the demo program above assume certain features like
allowing <code>Gc&lt;T&gt;</code> for <code>T: ?Sized</code>, which may or may not be reasonable.)</p>

<p>The compositionality constraint may seem obvious (especially if one
starts by assuming that references to gc-allocated objects will be
values of type <code>Gc&lt;T&gt;</code> for arbtrary <code>T</code>).</p>

<p>But using &ldquo;black box&rdquo; GC interop (as described above) would likely
<em>defeat</em> compositionality.  That is why I point out this objective
explicitly.</p>

<a name="L.a.id..precision..Precision..Space-Efficiency...a."></a>
<h3><a id="precision">Precision (Space-Efficiency)</a></h3>

<p>A 100% precise GC is one that knows the type of every object and field
that it encounters, in terms of being able to classify a word of
memory as an integer or a pointer, and also classify whether a given
word of memory is actually usable according to the type of the value
the word is embedded within.</p>

<p>A space-efficient GC, in essence, is one that is eventually able to
reclaim all garbage, without being subverted by particular details of
the host program or the system state.</p>

<p>(Calling a language implementation space-efficient is a reference to
the <a href="http://www.cesura17.net/~will/professional/research/papers/tail.pdf">asymptotic space complexity</a> of a language implementation.  I am
employing the term here because the objective I want to capture is
more general than just precision.)</p>

<p>A <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/#conservative-gc">conservative GC</a> lacks precision. In other words,
a precise GC is more space-efficient than a conservative GC: There
exists a program that will exhibit worse (asymptotic) space
performance atop a conservative GC than it would atop a precise GC.</p>

<p>We would like Rust to be able to interoperate with 100% precise
collectors.</p>

<p>Ideally, we would also like to be able to interoperate with collectors
that do not support <a href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/#pinning-support">pinning</a>.</p>

<p>Finally, we would like to ensure that the heap patterns associated
with <a href="#compositionality">Compositionality</a> do not cause garbage to go unreclaimed.</p>

<ul>
<li>Note that a precise GC that treats <em>all</em> objects on the &ldquo;Rust Heap&rdquo;
as roots is not very space-efficient: it will fail to collect
cyclic garbage structure like the below.</li>
</ul>


<p id="target_anchor_demo_garbage_cycle_thru_rust_heap"></p>


<script>
var stack = { id: "cluster_stack", label: "Stack", is_subgraph: true };
var rust_heap = { rankdir:"LR", id: "cluster_rust_heap", label: "Rust Heap", is_subgraph: true };
var gc_heap = { id: "cluster_gc_heap", label: "GC Heap", is_subgraph: true, style: "rounded" };

var local_a = { id: "local_a", label: "a", shape: "record" };

var a = object_record("A", "<f0> Some(Gc(B)) | <f1> None");
a.style = "rounded";
var b = object_record("B", "<f0> None | <f1> None");
b.style = "rounded";
var c = object_record("C", "<f0> Some(Gc(B)) | <f1> Some(Box(O))");
c.style = "rounded";
var o = object_record("O", "<f0> Gc(C)");

a.f0 = edge_from_to_ports(":f0", ":id:n", b);

c.f0 = edge_from_to_ports(":f0", ":id", b);
c.f1 = edge_from_to_ports(":f1:s", ":id", o);
o.f0 = edge_from_to_ports(":f0", ":id", c);

stack[1] = local_a;
local_a.ref = edge_to_port(":id", a);

gc_heap[0] = a;
gc_heap[1] = b;
gc_heap[2] = c;
rust_heap[0] = o;

var objects = [stack, gc_heap, rust_heap];
post_objects("target_anchor_demo_garbage_cycle_thru_rust_heap", objects, { rankdir:"LR", nodesep:0.2, no_dims: true});
</script>


<p>In the above diagram, &ldquo;C&rdquo; and &ldquo;O&rdquo; are unreachable by the program
itself (&ldquo;O&rdquo; is owned by the gc-allocated &ldquo;C&rdquo;), but if you treat all
objects in the Rust Heap as roots, then it will classify &ldquo;O&rdquo; as a
root, and &ldquo;C&rdquo; will never be reclaimed.</p>

<p>This is why compositionality can interact with space-efficiency.
Allowing gc-allocated objects to own data allocated on the Rust heap,
while also allowing references to gc-allocated objects to be stored in
values on the Rust heap, then you will encounter cyclic structure like
this. (This was the design bug that led me to withdraw my &ldquo;Take II&rdquo;
<a href="https://github.com/rust-lang/rfcs/pull/244">allocator RFC</a>.)</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>This post was dedicated to identifying criteria that we would
like GC-integration with Rust to satisfy.</p>

<p>Next up: Why is it hard to satisfy the above criteria simultaneously?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GC and Rust Part 0: Garbage Collection Background]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/"/>
    <updated>2015-10-27T14:09:00-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work</id>
    <content type="html"><![CDATA[<p>This post is a prequel to a series of posts discussing why garbage
collection is hard, especially for Rust, and brainstorming about
solutions to the problems we face.</p>

<p>The goal of this post is to provide the background foundational material
about Garbage Collection that the other posts will then build upon.</p>

<!-- more -->


<p>You can skip ahead to the follow-up posts (once they are published) if
you feel you are already well-versed in the low-level mechanics of
garbage collection.</p>

<p>I may add more material to this post in the future if I discover a
need to provide more detail on a particular subtopic, such as &ldquo;write
barriers&rdquo;.</p>

<p>(The body of this post makes heavy use of client-side rendering,
because of author idiosyncrasies.  You may need to wait a moment while
the supporting Javascript loads.)</p>

<p>Update (17 November 2015): It has come to my attention that portions
of the post are not rendering properly in Google Chrome. I will try to
fix this, but in the meantime, you should be able to get the proper
renderings in Safari or Firefox. (I do not yet know about other
browsers.) If your browser is working as original expected, then
you should see a picture load immediately beneath this text.</p>

<p>Update (18 Novemer 2015): many thanks to <code>othermike</code> on reddit who
pointed out <a href="https://www.reddit.com/r/rust/comments/3t6nk7/gc_and_rust_part_1_specifying_the_problem/cx40odj">my bug</a>.
The content should now render properly on Chrome (and hopefully other
browsers too).</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/js_to_dot.js" charset="utf-8"></script>


<script src="http://blog.pnkfx.org/javascripts/gc_rendering.js" charset="utf-8"></script>


<script>
function simple_gc_structure() {
    var rf = make_regfile("RF");
    var a = { id: "A" };
    var b = { id: "B" };
    var c = { id: "C" };
    var d = { id: "D" };
    var e = { id: "E" };
    var f = { id: "F" };
    var g = { id: "G" };
    b.f0 = c;
    d.f0 = a;
    d.f1 = e;
    e.f0 = f;
    f.f0 = e;
    c.f0 = g;

    rf.link(0, a);
    rf.link(1, b);
    rf.link(3, c);

    return [rf, d];
}

function copied_gc_structure() {
    var rf = make_regfile("RF");
    var a = { id: "A" };
    var b = { id: "B" };
    var c = { id: "C" };
    var d = { id: "D" };
    var e = { id: "E" };
    var f = { id: "F" };
    var g = { id: "G" };

    var a2 = { id: "A2", label: "A'" };
    var b2 = { id: "B2", label: "B'" };
    var c2 = { id: "C2", label: "C'" };
    var g2 = { id: "G2", label: "G'" };

    b.f0 = c;
    c.f0 = g;
    d.f0 = a;
    d.f1 = e;
    e.f0 = f;
    f.f0 = e;

    b2.f0 = c2;
    c2.f0 = g2;

    a.fwd = dashed_edge(a2);
    b.fwd = dashed_edge(b2);
    c.fwd = dashed_edge(c2);
    g.fwd = dashed_edge(g2);

    rf.link(0, a2);
    rf.link(1, b2);
    rf.link(3, c2);

    return [rf, d, a, b, c];
}

function simple_gc2() {
    var gc_struct = simple_gc_structure();
    var rf = gc_struct[0];
    var d = gc_struct[1];
    // for_each_reachable([d], hide, { on_edge: hide });
    // for_each_reachable([rf], unhide);
    var content = render_objects([rf, d]);
    return digraph(content, { rankdir:"LR" });
}
</script>




<p id="target_anchor1"></p>


<script>
var gc_struct = simple_gc_structure();
var rf = gc_struct[0];
var d = gc_struct[1];
var content = render_objects([rf]);
post_graph("target_anchor1", digraph(content, { rankdir:"LR" }), { no_dims: true });
</script>


<a name="What.is.Garbage.Collection"></a>
<h2>What is Garbage Collection</h2>

<p>A garbage collector is a component in the runtime for a programming
language that periodically attempts to reclaim memory (without
requiring explicit calls to memory-freeing routines in the programning
language). To do this soundly, the collector must identify blocks of
memory that cannot possibly be used in the future by the program
(i.e., &ldquo;dead objects&rdquo;).</p>

<p>Discussions of garbage collection often equate the notion of &ldquo;dead
object&rdquo; with &ldquo;unreachable object&rdquo;: If no chain of references exists
that could lead the program to an object, then that object cannot be
reached<label for='collecting-more-garbage' class='margin-toggle'> &#8853;</label><input type='checkbox' id='collecting-more-garbage' class='margin-toggle'/><span class='marginnote'>Researchers have explored methods to identify objects as dead even when reachable, such as using <a href="http://pop-art.inrialpes.fr/~fradet/PDFs/LISP94.pdf">&ldquo;parametricity&rdquo;</a>; but I am not aware of any such method being used outside of a research setting. </span>
 (and therefore cannot be used in the future).</p>

<p>When one says &ldquo;garbage collector&rdquo;, one usually means a &ldquo;<em>tracing</em>
garbage collector&rdquo;: a collector that works by identifying the
reachable objects by computing the connected components that include
the &ldquo;roots&rdquo; of the object graph. (The &ldquo;roots&rdquo; are the starting points
from which any chain of references must originate in the source
program.)</p>

<p>So, for example, we might have the following set of
gc-managed objects (labelled &ldquo;A&rdquo; through &ldquo;F&rdquo; below),
along with a register file labelled &ldquo;RF&rdquo;.</p>

<p id="target_anchor2"></p>


<script>
post_objects("target_anchor2", simple_gc_structure(), { rankdir:"LR", no_dims: true });
</script>


<p>In the simple model above, the roots <em>are</em> the processor
registers. Such a model is applicable to a language runtime where all
memory blocks (<em>including</em> the stack frames) are managed by the garbage
collector. (In other words, we are not talking about Rust yet.)</p>

<p>The reachable objects, as stated above, are the connected
components of the graph that includes the roots, highlighted
below.</p>

<p id="target_anchor3"></p>


<script>
// Overriding the `highlight` I put into js_to_dot.js
function highlight(object) {
    object.penwidth = "3.0";
    return object;
}

var objects = simple_gc_structure();
for_each_reachable([objects[0]], { on_node: highlight, on_edge: highlight });
post_objects("target_anchor3", objects, { rankdir:"LR", no_dims: true });
</script>


<p>A garbage collector would determine that the objects
labelled &ldquo;D&rdquo;, &ldquo;E&rdquo;, and &ldquo;F&rdquo; are unreachable, and thus
their storage can be reclaimed.</p>

<a name="L.span.id..how-gc-works..How.Garbage.Collection.works..span."></a>
<h2><span id="how-gc-works">How Garbage Collection works</span></h2>

<p>A garbage collector is often presented as a <em>coroutine</em>
<label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Coroutines are much like subroutines,
except that instead of having a parent-child relationship (where the
child subroutine &ldquo;returns&rdquo; to the parent caller), a call from
coroutine A to coroutine B: saves the current context of where A
currently is, transfers control to B, and the next time B calls A,
resumes the context that was saved at the outset.
<br></br>
In other words, once the linkage has been established between A and B,
then A&rsquo;s calls to B look like <em>returns</em> from the viewpoint of B, (and
B&rsquo;s calls to A look like returns from the viewpoint of A).
</span>
 that is linked in with the main
program. The main program itself is often referred to as a &ldquo;mutator&rdquo;,
since it is the entity that <em>mutates</em> the object graph.  (The
collector does not modify the abstract object graph, but rather the
<em>representation</em> of the object graph in memory.)</p>

<p>The mutator requests memory from some allocation service (usually
deeply integrated with the garbage collector for reasons we will see).
If there is a memory block immediately available to satisfy the
request, then the allocator hands that over. If there is not
sufficient free memory, then the mutator&rsquo;s allocation attempt invokes
the garbage collector coroutine.</p>

<p>Garbage collectors are also often divided into two categories: Copying
collectors, and Mark-Sweep collectors. Both collectors accomplish the
goal of identifying the reachable objects and reclaiming the
remainder, but they do it in different ways.</p>

<p>It is worthwhile to remember at this point that even though our object
graphs above are drawn as abstract circles and arrows, the objects are
represented somehow in memory.</p>

<p>For example, here is one potential representation for the above object
graph, where <code>-</code> denotes some value that the GC knows is not a
memory reference.</p>

<p id="target_anchor4" class=fullwidth></p>


<p>(Assume for this example that every GC allocated
object is made from four consecutive words in memory.)</p>

<script>
function make_memory_label(count, name_callback, val_callback) {
    var addresses = "ADDRESS";
    var contents = "CONTENT";
    var saw_one = true;
    for (i = 0; i < count; i++) {
        if (saw_one) { addresses += " | "; contents += " | ";}
        var name;
        if (name_callback) {
            name = name_callback(i);
        } else {
            name = "0x1";
            name += ("0000" + (i * 8).toString(16)).slice(-4);
        }
        addresses += name;
        if (val_callback) { contents += val_callback(i, name); }
        saw_one = true;
    }
    var label = "{ { " + addresses + " } | { " + contents + " } }";
    return label;
}
function make_memory_addr_val(state) {
var marks = state.marked;
var swept = state.swept;
var a_copied = state.a_copied;
var b_copied = state.b_copied;
var c_copied = state.c_copied;
var g_copied = state.g_copied;
var a_scanned = state.a_scanned;
var b_scanned = state.b_scanned;
var c_scanned = state.c_scanned;
var g_scanned = state.g_scanned;
var addr1=[
          "<nd> 0x10000 "+(swept?"":"(D) ")+"\\l",
          "0x10004 "+(swept?" (next)":"")+"\\l",
          "0x10008 \\l",
          "0x1000c \\l",
          "<na> 0x10010 (A) \\l",
          "0x10014 \\l",
          "0x10018 \\l",
          "0x1001c \\l",
          "<ne> 0x10020 "+(swept?"":"(E) ")+"\\l",
          "0x10024 "+(swept?" (next)":"")+"\\l",
          "0x10028 \\l",
          "0x1002c \\l",
          "<nb> 0x10030 (B) \\l",
          "0x10034 \\l",
          "0x10038 \\l",
          "0x1003c \\l",
         ];
var addr2 = [
          "<nc> 0x10040 (C) \\l",
          "0x10044 \\l",
          "0x10048 \\l",
          "0x1004c \\l",
          "<ny> 0x10050 \\l",
          "0x10054 "+(swept?" (next)":"")+"\\l",
          "0x10058 \\l",
          "0x1005c \\l",
          "<nf> 0x10060 "+(swept?"":"(F) ")+"\\l",
          "0x10064 "+(swept?" (next)":"")+"\\l",
          "0x10068 \\l",
          "0x1006c \\l",
          "<ng> 0x10070 (G) \\l",
          "0x10074 \\l",
          "0x10078 \\l",
          "0x1007c \\l",
         ];
var addr3 = [
          "<na> 0x20000 "+(a_copied?"(A') ":"")+"\\l",
          "0x20004 \\l",
          "0x20008 \\l",
          "0x2000c \\l",
          "<nb> 0x20010 "+(b_copied?"(B') ":"")+"\\l",
          "0x20014 \\l",
          "0x20018 \\l",
          "0x2001c \\l",
          "<nc> 0x20020 "+(c_copied?"(C') ":"")+"\\l",
          "0x20024 \\l",
          "0x20028 \\l",
          "0x2002c \\l",
          "<ng> 0x20030 "+(g_copied?"(G') ":"")+"\\l",
          "0x20034 \\l",
          "0x20038 \\l",
          "<lastg> 0x2003c \\l",
];
var val1 = [
           (swept ? "<vd> (free) " : "<vd> (header)"), // (D)
           (swept ? "<f0> 0x10020" : "<dpa> 0x10010"),
           (swept ? " - "          : "<dpe> 0x10020"),
           " - ",
           (marks ? "<va> (marked)" : a_copied ? "<va> (fwd)" : "<va> (header)"), // (A)
           (a_copied ? "<afwd> 0x20000" : " - "),
           " - ",
           " - ",
           (swept ? "<ve> (free) " : "<ve> (header)"), // (E)
           (swept ? "<f1> 0x10050" : "<epf> 0x10060"),
           " - ",
           " - ",
            // (B)
           (marks ? "<vb> (marked)" : b_copied ? "<vb> (fwd)" : "<vb> (header)"),
           (b_copied ? "<bfwd> 0x20010" : "<bpc> 0x10040"),
           " - ",
           " - ",
          ];
var val2 = [
           (marks ? "<vc> (marked)" : c_copied ? "<vc> (fwd)" : "<vc> (header)"), // (C)
           (c_copied ? "<cfwd> 0x20020" : "<cpg> 0x10070"),
           " - ",
           " - ",
           (swept ? "<vy> (free) " : "<vy> (header)"), // unused
           (swept ? "<f2> 0x10060" : " - "),
           " - ",
           " - ",
           (swept ? "<vf> (free) " : "<vf> (header)"), // (F)
           (swept ? "<f3> null " : " - "),
           (swept ? " - "          : "<fpe> 0x10020"),
           " - ",
           (g_copied ? "<vg> (fwd)" : marks ? "<vg> (marked)" : "<vg> (header) "), // (G)
           (g_copied ? "<gfwd> 0x20030" : " - "),
           " - ",
           " - ",
          ];
var val3 = [
           ((a_scanned || a_copied) ? "<va> (header)" : " - "), // (A')
           " - ",
           " - ",
           " - ",
           // (B')
           (b_scanned ? "<vb> (header) " : b_copied ? "<vb> (header)" : " - "),
           (b_scanned ? "<bpc2> 0x20020 " : b_copied ? "<bpc> 0x10040" : " - "),
           " - ",
           " - ",
           // (C')
           (c_scanned ? "<vc> (header) " : c_copied ? "<vc> (header)" : " - "),
           (c_scanned ? "<cpg2> 0x20030 " : c_copied ? "<cpg> 0x10070" : " - "),
           " - ",
           " - ",
            // (G')
           (g_scanned ? "<vg> (header) " : g_copied ? "<vg> (header)" : " - "),
           " - ",
           " - ",
           " - ",
          ];
    return [addr1, val1, addr2, val2, addr3, val3];
}
function make_graph_in_memory(options) {
    var original = options.original;
    var marking  = options.marking;
    var marked = options.marked;
    var swept  = options.swept;
    var free_list = options.free_list;
    var conservative_r2 = options.conservative_r2;
    var avail = options.avail;
    var rf = make_regfile("RF");
    var addrval = make_memory_addr_val(options);
    var addr1 = addrval[0];
    var val1 = addrval[1];
    var addr2 = addrval[2];
    var val2 = addrval[3];
    var addr3 = addrval[4];
    var val3 = addrval[5];
    var a_copied = options.a_copied;
    var b_copied = options.b_copied;
    var c_copied = options.c_copied;
    var g_copied = options.g_copied;
    var a_scanned = options.a_scanned;
    var b_scanned = options.b_scanned;
    var c_scanned = options.c_scanned;
    var g_scanned = options.g_scanned;
    var highlight_bpc2 = options.highlight_bpc2;
    var highlight_rc2 = options.highlight_rc2;
    var highlight_cfwd = options.highlight_cfwd;
    rf.label = "<id>RF | { { <r0>r0 | <r1>r1 | <r2>r2 | <r3>r3 } |" +
        " { <r0v>"+(a_copied?"0x20000":"0x10010")+
        " | <r1v>"+(b_copied?"0x20010":"0x10030")+
        " | <r2v>"+(conservative_r2?"0x10000":"-")+
        " | <r3v>"+(c_copied?"0x20020":"0x10040")+
        " } }";
    rf.pos = "0,500!";
    var from_space = options.from_space;
    var two_space = options.two_space;
    var two_space_content = !two_space ? "" : [
        'mem3 [shape="record",',
        'pos="-180,500!",',
        'label=\"'+make_memory_label(16,
                function (i) { return addr3[i]; },
                function (i, addr) { return val3[i]; })+'\",',
        '];',
        (!from_space ? "" : a_copied ? 'mem1:afwd:w -> mem3:va:e [style="dashed"];' : ""),
        (!from_space ? "" : b_copied ? 'mem1:bfwd:w -> mem3:vb:e [style="dashed"];' : ""),
        (!from_space ? "" : c_copied ? 'mem2:cfwd:w -> mem3:vc:e ['+(highlight_cfwd ? 'penwidth="3.0",' : '')+'style="dashed"];' : ""),
        (!from_space ? "" : g_copied ? 'mem2:gfwd:w -> mem3:vg:e [style="dashed"];' : ""),
        (b_scanned ? 'mem3:bpc2:e -> hidden_bc2 ['+(highlight_bpc2 ? 'penwidth="3.0",' : '')+'arrowhead="none"];' : b_copied ? 'mem3:bpc:e -> hidden_rc [arrowhead="none"];' : ""),
        (b_scanned ? 'hidden_bc2 -> mem3:vc:e' + (highlight_bpc2 ? '[penwidth="3.0"]':';') : ""),
        (c_scanned ? 'mem3:cpg2:e -> hidden_cg2 [arrowhead="none"];' : c_copied ? 'mem3:cpg:e -> mem2:ng:w;' : ""),
        (c_scanned ? 'hidden_cg2 -> mem3:vg:e;' : ""),
        (avail ? 'avail[pos="-90,375!"]; ' : ''),
        ((avail && avail.trim() != "") ? 'avail -> ' + avail + ';': ''),
    ].join('\n');
    var from_space_content = [
        'mem1 [shape="record",',
        !from_space ? 'style="invis",' : "",
        'pos="120,500!",',
        'label=\"'+make_memory_label(16,
            function (i) { return addr1[i]; },
            function (i, addr) { return val1[i]; })+'\",',
        '];',
        'hidden_ra  [ pos="-50,550!", shape="point", label="", width=0 ];',
        'hidden_rb  [ pos="-50,450!", shape="point", label="", width=0 ];',
        'hidden_rc  [ pos="-30,660!", shape="point", label="", width=0 ];',
        'hidden_da  [ pos="200,590!", shape="point", label="", width=0 ];',
        'hidden_de  [ pos="200,540!", shape="point", label="", width=0 ];',
        'hidden_bc  [ pos="220,590!", shape="point", label="", width=0 ];',
        'hidden_bc2  [ pos="-100,510!", shape="point", label="", width=0 ];',
        'hidden_cg  [ pos="375,590!", shape="point", label="", width=0 ];',
        'hidden_cg2  [ pos="-100,430!", shape="point", label="", width=0 ];',
        'hidden_fe1 [ pos="375,350!", shape="point", label="", width=0 ];',
        'hidden_fe2 [ pos="25,350!", shape="point", label="", width=0 ];',
        'hidden_yf [ pos="375,500!", shape="point", label="", width=0 ];',
        'hidden_fz [ pos="375,450!", shape="point", label="", width=0 ];',
        free_list ? 'free_list [ pos="0,620!", shape="rectangle", label="free-list" ];' : '',
        'mem2 [shape="record",',
        !from_space ? 'style="invis",' : "",
        'pos="300,500!",',
        'label=\"'+make_memory_label(16,
            function (i) { return addr2[i]; },
            function (i, addr) { return val2[i]; })+'\",',
        '];',
    ].join('\n');

    var graph_in_memory = ['digraph { node [fontsize=8]; ',
        'bgcolor="transparent";',
        'layout="neato"; inputscale=72;',
        // 'overlap="false";',
        // 'node [ pin=true ];',
        'rankdir="LR";',
        'nodesep=1.2;',
        // 'rank="same";',
        'splines="curved";',
        // 'node [font = "10px Monospace"];',
        render_node(rf),
        from_space_content,
        // !marking ? 'RF:r0:w -> hidden_ra [arrowhead="none"];' : 'RF:r0:w -> hidden_ra [arrowhead="none",penwidth=3.0];',
        // !marking ? 'hidden_ra -> mem1:na:w;' : 'hidden_ra -> mem1:na:w [label="1", penwidth=3.0];',
        a_copied ? 'RF:r0:w -> mem3:va:e;' : !marking ? 'RF:r0v:e -> mem1:na:w;' : 'RF:r0v:e -> mem1:na:w [label="1", penwidth=3.0];',
        b_copied ? 'RF:r1:w -> mem3:vb:e;' : !marking ? 'RF:r1:w -> hidden_rb [arrowhead="none"];' : 'RF:r1:w -> hidden_rb [arrowhead="none",penwidth=3.0];',
        b_copied ? "" : !marking ? 'hidden_rb -> mem1:nb:w;' : 'hidden_rb -> mem1:nb:w [label="2", penwidth=3.0,penwidth=3.0];',
        c_copied ? 'RF:r3:w -> mem3:vc:e'+(highlight_rc2 ? "[penwidth=3.0]" : "") + ';' : !marking ? 'RF:r3:w -> hidden_rc [arrowhead="none"];' : 'RF:r3:w -> hidden_rc [arrowhead="none",penwidth=3.0];',
        conservative_r2 ? 'RF:r2v:e -> mem1:nd:w [penwidth=3.0];' : '',
        b_scanned ? '' : !marking ? 'hidden_rc -> mem2:nc:w;' : 'hidden_rc -> mem2:nc:w [label="5", penwidth=3.0];',
        two_space ? '' : original ? 'mem1:dpa:e -> hidden_da [arrowhead="none"];' : '',
        two_space ? '' : original ? 'hidden_da -> mem1:va:e;' : '',
        two_space ? '' : original ? 'mem1:dpe:e -> hidden_de [arrowhead="none"];' : '',
        two_space ? '' : original ? 'hidden_de -> mem1:ve:e;' : '',
        two_space ? '' : original ? 'mem1:epf:e -> mem2:nf:w;' : '',
        b_copied ? '' : !marking ? 'mem1:bpc:e -> hidden_bc [arrowhead="none"];' :
                 'mem1:bpc:e -> hidden_bc [arrowhead="none", label="3", penwidth=3.0];',
        b_copied ? '' : !marking ? 'hidden_bc -> mem2:nc:w;' : 'hidden_bc -> mem2:nc:w [penwidth=3.0];',
        c_copied ? '' : !marking ? 'mem2:cpg:e -> hidden_cg [arrowhead="none"];' :
                 'mem2:cpg:e -> hidden_cg [arrowhead="none", label="4", penwidth=3.0];',
        c_copied ? '' : !marking ? 'hidden_cg -> mem2:vg:e;' : 'hidden_cg -> mem2:vg:e [penwidth=3.0];',
        two_space ? '' : original ? 'mem2:fpe:e -> hidden_fe1 [arrowhead="none"];' : '',
        two_space ? '' : original ? 'hidden_fe1 -> hidden_fe2 [arrowhead="none"];' : '',
        two_space ? '' : original ? 'hidden_fe2 -> mem1:ne:w' : '',
        free_list ? 'free_list -> mem1:nd:w [style="dashed",penwidth=3.0]' : '',
        free_list ? 'mem1:f0:e -> hidden_de [style="dashed",penwidth=3.0, arrowhead="none"]' : '',
        free_list ? 'hidden_de -> mem1:ve:e [style="dashed",penwidth=3.0]' : '',
        free_list ? 'mem1:f1:e -> mem2:ny:w [style="dashed",penwidth=3.0]' : '',
        free_list ? 'mem2:f2:e -> hidden_yf [style="dashed",penwidth=3.0, arrowhead="none"]' : '',
        free_list ? 'hidden_yf -> mem2:vf:e [style="dashed",penwidth=3.0]' : '',
        two_space_content,
        '}'].join('\n');

    return graph_in_memory;
}
var graph_in_memory = make_graph_in_memory({from_space:true,original:true});
post_graph("target_anchor4", graph_in_memory, {no_dims:true});
</script>


<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
Regarding the &ldquo;(header)&rdquo; words in the diagram:
Garbage collectors often require that the
GC-managed memory be formatted in a way such that the collector can
&ldquo;parse&rdquo; it when doing a scan over its address space.
<br></br>
As part of this &ldquo;parsing&rdquo;, the GC needs to be able to derive the size
of each object it looks at.
<br></br>
The address-space could be
partitioned into size classes.
Or if objects in a
block are to be variable-sized, the size could be recorded in object
headers (which are often needed anyway to store things like mark bits or other data).
<br></br>
Clever representation techniques exist that avoid using
header words for small objects (like pairs) without requiring size-class
partitioning; but I digress.
</span></p>

<p>In these pictures, there is no difference between an arrow pointing to
the left- verus right-side of a memory cell; so the occurrence of the
pointer to A (<code>0x10010</code>) in <code>r0</code> is no different than the occurrence
of that same value in memory cell <code>0x10004</code> (the first non-header word
of <code>D</code>), even though the arc for the former is pointing at the left
side of the first memory cell of <code>A</code>, and the arc for the latter is
pointing at the right side of that memory cell.</p>

<a name="Mark-Sweep.Collection"></a>
<h3>Mark-Sweep Collection</h3>

<p>A Mark-Sweep collector works by first doing a traversal of the
reachable memory, <em>marking</em> each object it finds (e.g. by setting a
bit reserved in the object header, or in separate mark bitmap if there
is no such bit reserved). This traversal requires some amount of extra
memory in reserve to track remaining work for the trace (e.g. a &ldquo;mark
stack&rdquo; of objects we are in the midst of traversing, and/or a queue of
objects scheduled for future traversal).</p>

<a name="The..Mark..phase"></a>
<h4>The &ldquo;Mark&rdquo; phase</h4>

<p>Here is a sketch of the traversals that the garbage collector
makes in order to mark each reachable object.</p>

<p id="target_anchor5" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,marking:true, marked:true});
post_graph("target_anchor5", graph_in_memory, {no_dims: true});
</script>


<p>As reflected in the diagram above, each object that the GC reaches has
its mark bit set to &ldquo;marked&rdquo; in its header word.</p>

<p>The numbers on the arcs above are meant to correspond to a
hypothetical traversal order as the GC marks the memory; particular
tracing strategies may yield different orders. (No matter what, we
will not trace object &ldquo;G&rdquo; until after we have seen &ldquo;C&rdquo; via some
route.)</p>

<p>Also, I have left the memory for the mark-stack out of the picture; in
this case the mark-stack would not grow very large, but in general one
must anticipate the mark-stack growing as large as the longest path
through the reachable object graph. (The longest path in this case is
three objects long.)</p>

<a name="The..Sweep..phase"></a>
<h4>The &ldquo;Sweep&rdquo; phase</h4>

<p><label for='' class='margin-toggle'>&#8853;</label><input type='checkbox' id='' class='margin-toggle'/><span class='marginnote'>
As previously mentioned, the GC much be able to &ldquo;parse&rdquo; the memory when
scanning the address space.
<br></br>
In the case of the Mark-Sweep collector, in addition to having to be able
to derive the size of each object, we also need the mark bit for each object
to be located at predictable location.
</span>
A Mark-Sweep collector does not move objects, so it must resort to
metadata such as a free-list to track reclaimed memory.  So, after the
marking is finished, the GC then <em>sweeps</em> over the memory: it walks
over the GC-managed address space
and builds up a free-list of blocks that were not marked during the traversal.</p>

<p id="target_anchor6" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,marked:true, swept: true, free_list: true});
post_graph("target_anchor6", graph_in_memory, {no_dims:true});
</script>


<p>(The arcs that make up the free-list above are dashed, to distinguish
them from the &ldquo;real&rdquo; references that make up the object graph. In the
above scheme, the pointer to the next element in the free list is held
in the second word of each free block.<label for='free-list-next' class='margin-toggle'> &#8853;</label><input type='checkbox' id='free-list-next' class='margin-toggle'/><span class='marginnote'>Putting the <code>next</code>-pointers for the free-list into the second word of each four-word block is one way of satisfying the aforementioned requirement that the GC-managed memory be parseable. </span>)</p>

<p>With that, the GC is done; the mutator (i.e. main program) is now free
to take blocks off of the free-list to satisfy memory requests.</p>

<a name="L.span.id..conservative-gc..Conservative.Collection..span."></a>
<h3><span id="conservative-gc">Conservative Collection</span></h3>

<p>A conservative collector is a particular kind of Mark-Sweep collector
where it is not provided enough information to know whether one or
more words of reachable data that it encounters should be interpreted
as a reference or not. Such a collector is forced to assume
(conservatively) that if the encountered datum is an allocated address
on the GC-managed heap, then that could be its purpose from the
perspective of the mutator, and therefore that datum must be treated
as a reference to memory.</p>

<p>In the diagrams above, I said that <code>-</code> denotes some value that the
GC knows is not a memory reference. In a conservative collector
without any type information, the only kind of value that can be
interpreted that way is one that lies outside the addreses space of
the GC-heap.</p>

<p>So for example, if we had the same picture as above, but the register
<code>r2</code> happen to hold an integer with value <code>0x10000</code>, and the
conservative collector is not told &ldquo;<code>r2</code> holds a non-reference at this
point in the execution&rdquo;, then this diagram would result:</p>

<p id="target_anchor_conservative_gc" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true,conservative_r2:true});
post_graph("target_anchor_conservative_gc", graph_in_memory, {no_dims:true});
</script>


<p>That is, even though in the program itself, the value <code>0x10000</code> is not
meant to be interpreted as a memory address, <code>D</code> (and <code>E</code> and <code>F</code>) are
all conservatively classified as live objects.</p>

<a name="Copying.Collection"></a>
<h3>Copying Collection</h3>

<p>A Copying collector moves objects from one location to another as part
of its tracing process, and updates the references in reachable
objects as it goes.</p>

<p>I will first illustrate this using our low-level memory graph,
but I will not draw the edges for the dead objects anymore,
as they add significant clutter to the picture.</p>

<a name="The.Reserved..To-space."></a>
<h4>The Reserved &ldquo;To-space&rdquo;</h4>

<p>First, we need to have some reserved memory to target as we copy
objects.  I have put this target memory (the so-called &ldquo;to-space&rdquo;) on
the left-hand side of the picture; the nearby &ldquo;avail&rdquo; circle is a
local variable in the GC that indicates the starting address that we
can use to copy objects into; so it starts off at the first address,
<code>0x20000</code>.</p>

<p id="target_anchor7" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true, two_space:true, avail: "mem3:na"});
post_graph("target_anchor7", graph_in_memory, {no_dims:true});
</script>


<a name="Copying.from.the.Roots"></a>
<h4>Copying from the Roots</h4>

<p>First we walk over the roots (in our simplified model, the registers),
and copy over all of the objects we see. So the below results after
we scan just the first two registers, copying the objects <code>A</code> and <code>B</code>
into new locations, respectively labelled <code>A'</code> and <code>B'</code>, and updating
<code>avail</code> accordingly.</p>

<p><a id="memory_post_copy_a_and_b"><p id="target_anchor8a" class="fullwidth"></p></a></p>

<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true, two_space:true,
    a_copied:true, b_copied:true, avail: "mem3:nc"});
post_graph("target_anchor8a", graph_in_memory, {no_dims:true});
</script>


<p>Note that as we copy objects from the source memory
(the so-called &ldquo;from-space&rdquo;), we must maintain a map from the
original object to its newly allocated copy. In this model,
this is accomplished by imperatively overwriting the original object
with <code>fwd</code> header marking it as &ldquo;forwarded&rdquo; as well as a &ldquo;forwarding
pointer&rdquo; (the dashed arcs) that points to the new location.</p>

<p>The copies themselves just get the original memory contents, so they
may have pointers to the old objects in the source memory (such as the
<code>B' -&gt; C</code> arc in the picture). Those will get fixed up later.</p>

<p>We still need to scan the rest of the registers, which copies <code>C</code> as
shown below.</p>

<p id="target_anchor8b" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true, two_space:true,
    highlight_rc2: true, highlight_cfwd: true,
    a_copied:true, b_copied:true, c_copied:true, avail: "mem3:ng"});
post_graph("target_anchor8b", graph_in_memory, {no_dims:true});
</script>


<a name="Scan.the..To-space."></a>
<h4>Scan the &ldquo;To-space&rdquo;</h4>

<p>Now that we have finished scanning the roots, we start the fixup
process of scanning over the &ldquo;to-space.&rdquo; Every time we encounter a
pointer into the &ldquo;from-space&rdquo;, there are two cases to consider: Either
it is an already copied object (in which case there will be a
forwarding pointer installed), or it is an object that is not yet
copied.</p>

<p>If its a forwarded object, then we fixup our reference so that it
points to the new copy in the &ldquo;to-space&rdquo;. We see this when the fixup
scan is scanning over <code>B'</code> and sees the <code>B' -&gt; C</code> reference, which it
then rewrites to a <code>B' -&gt; C'</code> reference, highlighted below.</p>

<p id="target_anchor9" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true, two_space:true,
    highlight_bpc2:true,
    a_copied:true, b_copied:true, c_copied:true,
    a_scanned:true, b_scanned:true, avail: "mem3:ng"
    });
post_graph("target_anchor9", graph_in_memory, {no_dims:true});
</script>


<p>The fixup scan is not yet complete; the next object it encounters,
<code>C'</code>, illustrates the other case of a reference to an object (<code>G</code>
here) that has not yet been copied. In this case, it just copies it,
in the same manner that we did when we were scanning the roots. (This
adds the forwarded object to the set of objects enqueued for fixup
scanning.)</p>

<p id="target_anchor10" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({from_space:true,original:true, two_space:true,
    a_copied:true, b_copied:true, c_copied:true, g_copied:true,
    a_scanned:true, b_scanned:true, c_scanned:true, avail: "mem3:lastg:s",
    });
post_graph("target_anchor10", graph_in_memory, {no_dims:true});
</script>


<a name="Reclaim.the..From-space."></a>
<h4>Reclaim the &ldquo;From-space&rdquo;</h4>

<p>Eventually the fixup scan will finish processing all of the &ldquo;to-space&rdquo;
(since there are only a finite number of objects that could be
enqueued). At this point, there will be no more reachable objects in
any part of the from-space, and thus those memory blocks can be
reclaimed in their entirety.</p>

<p id="target_anchor11" class="fullwidth"></p>


<script>
var graph_in_memory = make_graph_in_memory({two_space:true,
    a_copied:true, b_copied:true, c_copied:true, g_copied:true,
    a_scanned:true, b_scanned:true, c_scanned:true, g_scanned:true, avail: "mem3:lastg:s"
    });
post_graph("target_anchor11", graph_in_memory, {no_dims:true});
</script>


<p>Woo, done!</p>

<a name="A.Spectrum.of.Collectors"></a>
<h3>A Spectrum of Collectors</h3>

<p>The mark-sweep and copying collection methods illustrated above
actually form two extreme points on a spectrum of implementation
techhniques.</p>

<p>In practice, many collectors are neither entirely mark-sweep nor
copying, but rather employ a hybrid strategy, where some memory
regions are reclaimed via a copying-collection, while others are
managed via a mark-sweep method. For example, some generational
collectors work by promoting objects from a young space into an older
space via copying collection, but then the last space (with the eldest
objects) can be managed via mark-sweep.</p>

<p>As another example of a hybrid strategy, there exist conservative
collectors (such as &ldquo;mostly copying&rdquo; collectors) where exact type
information is known for the heap-allocated objects, but the types are
not known for the roots (i.e. the registers and values embedded in the
stack). In such systems, it is not safe to move objects that are
referenced via conservatively-scanned words. Such objects are &ldquo;pinned&rdquo;
in place (which means that it cannot be moved by the collector) for
the duration of this collection, and thus space in their memory blocks
can only be reclaimed with via a mark-sweep collection.  However,
objects reachable solely via precisely-scanned words <em>can</em> be moved,
and memory blocks made up solely of such objects can be reclaimed via
a copying-collection strategy.</p>

<a name="L.span.id..pinning-support..Pinning.Support..span."></a>
<h3><span id="pinning-support">Pinning Support</span></h3>

<p>In our discussion to follow, rather than attempt to characterize a
collector as &ldquo;mark-sweep&rdquo; or &ldquo;copying&rdquo;, it will be more useful to
distinguish collectors in terms of whether or not they support
&ldquo;pinning&rdquo;. In a language runtime that supports pinning, a mutator
(i.e. the main program linked with the collector coroutine) can tag
any live object as &ldquo;pinned&rdquo;.</p>

<p>(In the example of &ldquo;mostly copying&rdquo; above, such pinning is
accomplished by putting a reference into a conservatively-scanned
root. However, some language runtimes provide first class support for
pinning; for example, the Microsoft CLR once offerred a
<a href="https://msdn.microsoft.com/en-us/library/1dz8byfh.aspx"><code>pin_ptr</code></a> smart-pointer for Managed C++ that would prevent
a referenced object from moving.)</p>

<p>In other words, in a runtime with pinning, the mutator dictates which
objects can be managed via copying collection. If the runtime does not
support pinning, then it is the <em>collector</em> that dictates which
objects are managed via copying; the mutator cannot rely on the
collector allowing arbitrary objects to be pinned.</p>

<a name="Simplifying.our.diagrams"></a>
<h3>Simplifying our diagrams</h3>

<p>While I am sure it was fun to decode the above renderings of memory
banks, now that we have seen how collectors work at a low-level, I am
going to revert to the earlier high-level object notation.  It should
be easier for you to read, and (just as important) for me to write.</p>

<p id="target_anchor12"></p>


<script>
var gc_struct = simple_gc_structure();
var rf = gc_struct[0];
var d = gc_struct[1];

var a = rf.r0.target;
var b = rf.r1.target;
var c = rf.r3.target;

a_and_b = [a,b];
a_and_b.is_subgraph = true;
a_and_b.id = "cluster_a_and_b";
a_and_b.rank = "same";
a_and_b.style = "invis";

var gc_heap = [];
gc_heap.push(a_and_b);
for_each_reachable([c,d], function (o) { if (o !== rf) { gc_heap.push(o); } })

gc_heap.is_subgraph = true;
gc_heap.style = "invis";
gc_heap.id = "cluster_gc_heap";
var content = render_objects([rf, a_and_b, gc_heap, d]);
post_graph("target_anchor12", digraph(content, {rankdir:"LR"}), {no_dims:true});
</script>


<p>To show a copying collector&rsquo;s intermediate state in a high-level
picture, I will show newly copied objects with prime marks (and, if
possible, in a separately delineated to-space), and a dashed-line for
forwarding pointers.</p>

<p>Here is an example of this style of rendering, using the earlier
example at <a href="#memory_post_copy_a_and_b">the point where</a> a copying
collector had scanned just registers <code>r0</code> and <code>r1</code> (but had not yet
copied <code>C</code> from register <code>r3</code>), highlighting the copied objects and
the newly written references (including the dashed forwarding
pointers).</p>

<p id="target_anchor_simplified_copying"></p>


<script>
var rf = make_regfile("RF");
// rf.label = "{" + rf.label + "}";
var a = { id: "A" };
var b = { id: "B" };
var c = { id: "C" };
var d = { id: "D" };
var e = { id: "E" };
var f = { id: "F" };
var g = { id: "G" };
var a2 = { id: "A2", label: "A'", penwidth: "3.0" };
var b2 = { id: "B2", label: "B'", penwidth: "3.0" };
b.f0 = c;
c.f0 = g;
d.f0 = a;
d.f1 = e;
e.f0 = f;
f.f0 = e;
b2.f0 = c;
a.fwd = highlight(dashed_edge(a2));
b.fwd = highlight(dashed_edge(b2));
rf.link(0, a2, {penwidth: "3.0"});
rf.link(1, b2, {penwidth: "3.0"});
rf.link(3, c);

var a_and_b = [a, b];
a_and_b.is_subgraph = true;
a_and_b.rank="same";
var gc_heap1 = [a_and_b, c, d, e, f, g];
gc_heap1.is_subgraph = true;
gc_heap1.label = "from space";
gc_heap1.id = "cluster_gc_heap1";
var gc_heap2 = [a2, b2];
gc_heap2.is_subgraph = true;
gc_heap2.id = "cluster_gc_heap2";
gc_heap2.label = "to space";
gc_heap2.rank = "same";
gc_heaps = [gc_heap1, gc_heap2];
gc_heaps.is_subgraph = true;
// gc_heaps.id = "cluster_all_gc_heaps";
// gc_heaps.rankdir = "TD";
var objects = [rf, gc_heaps];
post_objects("target_anchor_simplified_copying", objects, {rankdir:"LR",no_dims:true});
</script>


<p>(This rendering is arguably just as clear (or unclear) as our earlier
<a href="#memory_post_copy_a_and_b">memory diagram</a> was, apart from some
annoying edge-crossings due to the graphviz layout engine.)</p>

<a name="Conclusion"></a>
<h2>Conclusion</h2>

<p>Well, I don&rsquo;t know if you learned anything about GC from this post.
I certainly learned a lot about techniques for wrestling with
graphviz.  :)</p>

<p>There will be a followup post soon-ish that will bring Rust into the
picture, discussing what GC and Rust integration even <em>means</em>, and
the host of problems that crop up.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Vis-a-vis, part 1: Visualizing Graphs via viz.js]]></title>
    <link href="http://blog.pnkfx.org/blog/2015/10/12/viz-a-viz-js/"/>
    <updated>2015-10-12T14:10:00-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2015/10/12/viz-a-viz-js</id>
    <content type="html"><![CDATA[<p>This is a post discussing a couple different ways to draw pictures,
mostly those of graphs (nodes and edges, i.e. circles or boxes, and
lines between them).</p>

<p>The technology covered by this post is <a href="https://github.com/mdaines/viz.js/">viz.js</a>, a Javascript
library for rendering graphs specified via the <a href="http://www.graphviz.org/content/dot-language">DOT</a> language.</p>

<!-- more -->


<p>Its meant both as a reference for me to use when I want to remind
myself of my options here, and as a demo of some interesting web
technologies.</p>

<p>I hope in later posts to cover SVG (&ldquo;Scalable Vector Graphics&rdquo;)
itself, and perhaps higher level Javascript libraries such as <a href="http://d3js.org/">D3</a>.</p>

<p>I will focus in these posts on client-side rendering technologies.
Another entirely reasonable option is to render the content to an
image (or SVG, or a JS script that renders into a canvas, et cetera).
However, one of my goals with my documents is to embed all of the
source text into the markdown content; a separate rendering tool would
require some sort of pre-process step, and I am loathe to try to
incoporate that into the <code>Rakefile</code> that Octopress uses.</p>

<a name="viz.js"></a>
<h2>viz.js</h2>

<p>The first item we will cover, since it amongst the simplest to adopt,
is <code>vis.js</code>, a javascript library that provides
<a href="http://www.graphviz.org/">graphviz-style</a> rendering in the browser client.</p>

<p>(<a href="http://www.graphviz.org/">Graphviz</a> is a tool for automatically laying out and
rendering graphs; it is coupled with <a href="http://www.graphviz.org/content/dot-language">DOT</a>, a simple domain-specific
language for describing graph structures by defining the nodes, edges,
and various attributes attached to them, like labels.)</p>

<a name="Hooking.up.the.JS.source"></a>
<h3>Hooking up the JS source</h3>

<p>Since this is using (heavy duty) javascript, you are not likely to
want to put the supporting source code inline in your web page.
Instead, you will need to load it up, either:</p>

<ol>
<li><p>from the original <a href="src=" title="https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js">source site</a>, or</p></li>
<li><p>in a server-side local copy of the file that you deploy alongside
your content
(e.g. put it into the <code>_source/javascripts/</code> directory,
if you are using Octopress for a blog like this one).</p></li>
</ol>


<p>I recommend the latter route, since the linked github repository is
outside of your control, and if it dissapears, you lose the rendering
and your page is broken.</p>

<p>After you have selected your source for the code, you need to
make your page load it up, via a <code>script</code> tag invocation,
like: <code>&lt;script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"&gt;&lt;/script&gt;;</code></p>

<p>This script can take a while to load. You may want to insert a warning,
like this one, before the <code>script</code> invocation.</p>

<script src="http://blog.pnkfx.org/javascripts/viz.js" charset="utf-8"></script>


<a name="Injecting.generated.SVG.into.the.document"></a>
<h3>Injecting generated SVG into the document</h3>

<p>Once the script is loaded, you can start using inline Javascript to
render graphviz-style descriptions of directed graphs to SVG within
the page.</p>

<p>The smallest example of this given in the <code>viz.js</code> documentation
does this by dynamically adding to the <code>innerHTML</code> property:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>  <span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">+=</span> <span class="s2">&quot;&lt;p&gt;Sample addition.&lt;/p&gt;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">+=</span> <span class="nx">Viz</span><span class="p">(</span><span class="s2">&quot;digraph { a -&gt; b; }&quot;</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The above &ldquo;works&rdquo; (even in the context of an Octopress blog post), but
it is a rather brute-force approach. Plus, the resulting composition
of the blog text with the graphics added at the end is not likely to
please you nor your audience.</p>

<p>We can do better: Add a content-less <code>div</code> tag (or <code>p</code> tag, et
cetera), and then search for that element in a <code>script</code> block that
will add our picture to the inner HTML for that tag.</p>

<p>Here is a concrete illustration of the idea (that does not use
Graphviz or <code>viz.js</code>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;target_anchor0&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor0&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s2">&quot;This text was injected.&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>




<div id="target_anchor0"></div>


<script>
    var elem = document.getElementById("target_anchor0");
    elem.innerHTML = "This text was injected.";
</script>


<p>So, now that we know how to insert HTML into our document (even in the
context of the markdown source for a blog post), let us dive into how
to combine that with Graphviz, via <code>viz.js</code>.</p>

<a name="L.code.dot_source..code..holds.DOT.source"></a>
<h3><code>dot_source</code> holds DOT source</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;target_anchor1&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dot_source</span> <span class="o">=</span> <span class="s1">&#39;digraph { rankdir=&quot;LR&quot;; bgcolor=&quot;transparent&quot;; a -&gt; b -&gt; c; }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor1&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">Viz</span><span class="p">(</span><span class="nx">dot_source</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The contents of <code>dot_source</code> make up a DOT program:</p>

<ul>
<li><p><code>digraph</code> means we are making a directed graph,</p></li>
<li><p><code>rankdir="LR"</code> means we want the nodes to prefer horizontal left-to-right layout (the default is to have them vertically stacked top-to-bottom),</p></li>
<li><p><code>bgcolor="transparent"</code> means we want a transparent background (the default is white, which is fine but a little offputting for this site),</p></li>
<li><p><code>a -&gt; b</code> means &ldquo;I want an edge coming out of <code>a</code> and into <code>b</code>&rdquo;; you can chain them together as shown in <code>a -&gt; b -&gt; c</code>.</p></li>
</ul>


<p>Here is how that ends up rendering:</p>

<div id="target_anchor1"></div>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent"; a -> b -> c; }';
    var elem = document.getElementById("target_anchor1");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>It turns out that the generated SVG is actually pretty readable.  That
is, I am able to use &ldquo;Inspect Element&rdquo; in my web browser, and I see
there that the SVG element is actually made up of many <code>g</code> elements
that have each had their <code>class</code> attribute set according to their
role: the whole graph has <code>class="graph"</code>, and then each node and edge
is assigned <code>"node1"</code>, <code>"node2"</code>, <code>"edge1"</code>, <code>"node3"</code>, <code>"edge2"</code>.
(There are also comments embedded in the generated SVG above each
element, so that one can map the element back to the node or edge
in the original <code>dot_source</code> text.)</p>

<p>That is how to use <code>viz.js</code> to embed graphs described via <a href="http://www.graphviz.org/content/dot-language">DOT</a>.</p>

<p>This can be especially useful if you are making a dynamic page where
the user can inject their own graph descriptions, and you want <code>viz.js</code>
to do the heavy lifting of deciding how to lay out the nodes.</p>

<a name="Controlling.node.layout"></a>
<h3>Controlling node layout</h3>

<p>But what if we want more control over the layout of the picture
elements?</p>

<p>For example, one might want more control over layout to
ensure that there is a easy-to-see correspondence between a series of
pictures, or if there is a structural symmetry that is easier to see
if the layout is also symmetrical.</p>

<p>Consider the following example graph:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">&quot;target_anchor2&quot;</span><span class="nt">&gt;</span>Symmetric structure but asymmetric layout: <span class="nt">&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dot_source</span> <span class="o">=</span> <span class="s1">&#39;digraph { rankdir=&quot;LR&quot;; bgcolor=&quot;transparent&quot;; a -&gt; b -&gt; c -&gt; e; b -&gt; d -&gt; e -&gt; a; }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor2&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">Viz</span><span class="p">(</span><span class="nx">dot_source</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor2">Symmetric structure but asymmetric layout: </p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent"; a -> b -> c -> e; b -> d -> e -> a; }';
    var elem = document.getElementById("target_anchor2");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>There are a number of options at this point. We could abandon Graphviz (and <code>viz.js</code>),
and do our diagrams directly in SVG. But, assuming we want to stay within the confines
of <code>viz.js</code>, there are a few things we <em>can</em> do.</p>

<p>First, we can specify initial node positions by adding a <code>pos</code> attribute to
each node that needs it. The default layout engine (called <code>dot</code>) just
ignores such attributes, but other engines, such as the <code>neato</code> layout,
will incorporate such information.</p>

<p>One can switch the layout engine via an argument to the <code>Viz</code> function, but I will instead do it
by setting an attribute in the graph itself.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">&quot;target_anchor3&quot;</span><span class="nt">&gt;&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dot_source</span> <span class="o">=</span> <span class="s1">&#39;digraph { rankdir=&quot;LR&quot;; bgcolor=&quot;transparent&quot;;&#39;</span>
</span><span class='line'>    <span class="c1">// Start of the layout selection code</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;layout=&quot;neato&quot;; inputscale=72;&#39;</span> <span class="c1">// specifying &quot;neato&quot; layout to allow init position specification</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;overlap=&quot;false&quot;;&#39;</span> <span class="c1">// if you leave this out, the engine may put nodes in overlapping spots</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;start=0;&#39;</span> <span class="c1">// seed the RNG (to ensure consistent results)</span>
</span><span class='line'>    <span class="c1">// End of the layout selection code</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;a -&gt; b -&gt; c -&gt; e; b -&gt; d -&gt; e -&gt; a;&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39; }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor3&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">Viz</span><span class="p">(</span><span class="nx">dot_source</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor3"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    // Start of the layout selection code
    dot_source += 'layout="neato"; inputscale=72;' // specifying "neato" layout to allow init position specification
    dot_source += 'overlap="false";' // if you leave this out, the engine may put nodes in overlapping spots
    dot_source += 'start=0;' // seed the RNG (to ensure consistent results)
    // End of the layout selection code
    dot_source += 'a -> b -> c -> e; b -> d -> e -> a;';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor3");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>As you can see, we definitely have a different node layout. It is not
yet directly illustrating the mirror symmetry of the graph structure,
though. To achieve that, we could put the <code>a</code> node inside of a
diamond shape formed by { <code>b</code>, <code>c</code>, <code>d</code>, <code>e</code> }.</p>

<p>We can specify node positions by adding separate declarations for
each of the individual nodes, and then adding <code>pos</code> attributes
for each.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>dot_source += &#39;b [pos=&quot;0,40&quot;]; a [pos=&quot;100,40&quot;]; c [pos=&quot;160,80&quot;];&#39;
</span><span class='line'>dot_source += &#39;d [pos=&quot;160,0&quot;]; e [pos=&quot;220,40&quot;];&#39;
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor4"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    // Start of the layout selection code
    dot_source += 'layout="neato"; inputscale=72;' // specifying "neato" layout to allow init position specification
    dot_source += 'overlap="false";' // if you leave this out, the engine may put nodes in overlapping spots
    dot_source += 'start=0;' // seed the RNG (to ensure consistent results)
    // End of the layout selection code
    // Start of the node positioning code
    dot_source += 'b [pos="0,40"]; a [pos="100,40"]; c [pos="160,80"];'
    dot_source += 'd [pos="160,0"]; e [pos="220,40"];'
    // End of the node positioning code
    dot_source += 'a -> b -> c -> e; b -> d -> e -> a;';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor4");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p><em>That</em> shows the mirror symmetry of the graph.</p>

<p>The careful reader may have noticed an oddity in the above rendering: I had specified
that <code>a</code> have an x-coordinate of 100, while the corresponding x-coordinate for <code>c</code> and <code>d</code> is 160; but
in the rendering, all three of the nodes fall on a vertical line sharing the same x-coordinate.
What happened?</p>

<p>The answer is that the input node positions are by default only as
<em>initial</em> values; the layout engine may still choose to adjust them in
order to &ldquo;improve&rdquo; the layout according to its internal heuristics.</p>

<p>We can override this by <em>pinning</em> the nodes in place. An individual node can be pinned by
putting an exclamation point after the coordinate in its <code>pos</code> attribute, or equivalently by
setting the nodes <code>pin</code> attribute to <code>true</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>dot_source += &#39;b [pos=&quot;0,40&quot;]; a [pos=&quot;100,40!&quot;]; c [pos=&quot;160,80!&quot;];&#39;
</span><span class='line'>dot_source += &#39;d [pos=&quot;160,0!&quot;]; e [pos=&quot;220,40&quot;];&#39;
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor5"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    // Start of the layout selection code
    dot_source += 'layout="neato"; inputscale=72;' // specifying "neato" layout to allow init position specification
    dot_source += 'overlap="false";' // if you leave this out, the engine may put nodes in overlapping spots
    dot_source += 'start=0;' // seed the RNG (to ensure consistent results)
    // End of the layout selection code
    // Start of the node positioning code
    dot_source += 'b [pos="0,40"]; a [pos="100,40!"]; c [pos="160,80!"];'
    dot_source += 'd [pos="160,0!"]; e [pos="220,40"];'
    // End of the node positioning code
    dot_source += 'a -> b -> c -> e; b -> d -> e -> a;';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor5");
    elem.innerHTML = Viz(dot_source,"svg");
</script>


<p>Now we can see that <code>a</code>, <code>c</code>, and <code>d</code> are all pinned in place, and the resulting layout
is perhaps not as nice.</p>

<p>In particular, the <code>a -&gt; b</code> edge does not even have enough room
for its arrow head. We could fix this by pinning the <code>b</code> node in place as well,
but an alternative is to encourage graphviz to put more space between the nodes
via the <code>sep</code> attribute.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>dot_source += &#39;sep=0.2;&#39; // treat each node as 1.2 times larger than it is
</span></code></pre></td></tr></table></div></figure>




<p id="target_anchor6"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    // Start of the layout selection code
    dot_source += 'layout="neato"; inputscale=72;' // specifying "neato" layout to allow init position specification
    dot_source += 'overlap="false";' // if you leave this out, the engine may put nodes in overlapping spots
    dot_source += 'sep=0.2;' // treat each node as 1.2 times larger than it is
    dot_source += 'start=0;' // seed the RNG (to ensure consistent results)
    // End of the layout selection code
    // Start of the node positioning code
    dot_source += 'b [pos="0,40"]; a [pos="100,40!"]; c [pos="160,80!"];'
    dot_source += 'd [pos="160,0!"]; e [pos="220,40"];'
    // End of the node positioning code
    dot_source += 'a -> b -> c -> e; b -> d -> e -> a;';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor6");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>That is a pretty legible graph. Of course, the code to describe it is
quite a bit more complex than our <a href="#target_anchor2">original code</a>;
hopefully I will not feel the need to specify node placement too
often.</p>

<a name="Edge.attributes"></a>
<h3>Edge attributes</h3>

<p>Above we saw examples of node attributes, which can be used to adjust the
node placement and rendering. (The <a href="http://www.graphviz.org/doc/info/attrs.html">family of attributes</a> is much larger,
and includes ways to specify shapes, color, label text, et cetera.)</p>

<p>Graphviz also offers the ability to customize attributes for each
<em>edge</em>.  This can also be useful for influencing layout.
In particular, the <code>len</code> attribute can specify a preferred edge length
(ignored by the <code>dot</code> layout), and the <code>weight</code> attribute can be
increased to encourage the edge to be shorter (or, when <code>len</code> is
specified and relevant, to encourage that edge length to more closely
approximate <code>len</code>).</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">&quot;target_anchor7a&quot;</span><span class="nt">&gt;&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dot_source</span> <span class="o">=</span> <span class="s1">&#39;digraph { rankdir=&quot;LR&quot;; bgcolor=&quot;transparent&quot;;&#39;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;edge [weight=2];&#39;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;a -&gt; b -&gt; c -&gt; e; b -&gt; d -&gt; e -&gt; a [weight=1];&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39; }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor7a&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">Viz</span><span class="p">(</span><span class="nx">dot_source</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here we have used <code>edge [weight=2]</code> to specify a default weight of 2 for all edges,
and then we override that weight for the <code>e -&gt; a</code> edge (and just that edge).
(Note: The <code>dot</code> layout requires integral values for <code>weight</code>.)</p>

<p>Here is the effect of this:</p>

<p id="target_anchor7a"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    dot_source += 'edge [weight=2];'
    dot_source += 'a -> b -> c -> e; b -> d -> e -> a [weight=1];';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor7a");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>Look at that! We can see the mirror symmetry of the graph (depending on
how much we are willing to squint with regards to that <code>e -&gt; a</code> edge),
but we did not have to do any layout hacking.</p>

<p>Unsurprisingly, a different weight-assignment may yield a different layout.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>dot_source += &#39;   { edge [weight=10]; a -&gt; b; e -&gt; a; }&#39;
</span><span class='line'>dot_source += &#39;   { edge [weight=1]; b -&gt; c -&gt; e; b -&gt; d -&gt; e; }&#39;
</span></code></pre></td></tr></table></div></figure>


<p>Here we have moved a portion of the edges into a subgraph, so that we
can override their default <code>weight</code> as a group.</p>

<p id="target_anchor7b"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    dot_source += '   { edge [weight=10]; a -> b; e -> a; }'
    dot_source += '   { edge [weight=1]; b -> c -> e; b -> d -> e; }'
    dot_source += ' }';
    var elem = document.getElementById("target_anchor7b");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>Perhaps more surprising, changing node introduction order in the
source can also affect the layout.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>dot_source += &#39;   b -&gt; a [dir=&quot;back&quot;]; a -&gt; e [dir=&quot;back&quot;];&#39;
</span><span class='line'>dot_source += &#39;   b -&gt; c -&gt; e; b -&gt; d -&gt; e;&#39;
</span></code></pre></td></tr></table></div></figure>


<p>Here, we introduce the nodes <code>b</code> then <code>a</code> then <code>e</code> to encourage them
to be laid out horizontally in that order, then apply the <code>dir</code>
attribute so that the edge between them has its direction reversed.</p>

<p id="target_anchor7c"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    dot_source += '   b -> a [dir="back"]; a -> e [dir="back"];'
    dot_source += '   b -> c -> e; b -> d -> e;'
    dot_source += ' }';
    var elem = document.getElementById("target_anchor7c");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>Finally, if you want to describe a path through the graph, you can
highlight the edges of the path by overriding their <code>color</code> and
<code>penwidth</code> attribute.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">&quot;target_anchor8&quot;</span><span class="nt">&gt;&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dot_source</span> <span class="o">=</span> <span class="s1">&#39;digraph { rankdir=&quot;LR&quot;; bgcolor=&quot;transparent&quot;;&#39;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;edge [weight=2];&#39;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;a -&gt; b -&gt; d;&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39;{ edge [color=&quot;red&quot;,penwidth=&quot;3.0&quot;]; b -&gt; c -&gt; e -&gt; a [weight=1] }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">dot_source</span> <span class="o">+=</span> <span class="s1">&#39; }&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;target_anchor8&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">elem</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">Viz</span><span class="p">(</span><span class="nx">dot_source</span><span class="p">,</span> <span class="s2">&quot;svg&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here again we have used a subgraph to reduce the annotation burden.</p>

<p id="target_anchor8"></p>


<script>
    var dot_source = 'digraph { rankdir="LR"; bgcolor="transparent";'
    dot_source += 'edge [weight=2];'
    dot_source += 'a -> b -> d -> e;';
    dot_source += '{ edge [color="red",penwidth="3.0"]; b -> c -> e -> a [weight=1] }';
    dot_source += ' }';
    var elem = document.getElementById("target_anchor8");
    elem.innerHTML = Viz(dot_source, "svg");
</script>


<p>(One can use subgraphs for a number of other tricks, such as forcing all
nodes in the subgraph to fall into the same <code>rank</code>, which can be another
useful technique for encouraging particular layouts.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[An insight regarding DST grammar for Rust]]></title>
    <link href="http://blog.pnkfx.org/blog/2014/03/13/an-insight-regarding-dst-grammar-for-rust/"/>
    <updated>2014-03-13T07:04:00-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2014/03/13/an-insight-regarding-dst-grammar-for-rust</id>
    <content type="html"><![CDATA[<p>Executive summary: <code>type</code> = <code>unsized</code> ⊎ <code>sized</code>, so we should use
<code>type</code> as our generalization marker, not <code>unsized</code>.</p>

<!-- more -->


<ul>
<li><a href="#background_dst">Background: Dynamically Sized Types (DST)</a></li>
<li><a href="#the_insight">The Insight: <code>type</code> is a better generalization marker</a></li>
<li><a href="#the_examples">Examples ported from DST, Take 5</a></li>
</ul>


<a name="L.a.id..background_dst..Background:.Dynamically.Sized.Types..DST...a."></a>
<h2><a id="background_dst">Background: Dynamically Sized Types (DST)</a></h2>

<p>The Rust team has been discussing incorporating &ldquo;dynamically-sized
types&rdquo; into the static semantics for Rust.  Essentially the idea is to
allow code to describe and name static types whose size is only known
at Runtime.  E.g. the integer vector <code>[int, ..5]</code> is known at compile
time to have five elements, and is considered (statically) sized,
while the vector <code>[int]</code> has unknown size at compile time, and so that
type is called unsized.</p>

<p><a href="http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types/">There</a>
is <a href="http://smallcultfollowing.com/babysteps/blog/2013/06/06/reducing-dst-annotation/">a</a>
series <a href="http://smallcultfollowing.com/babysteps/blog/2013/11/26/thoughts-on-dst-1/">of</a>
blog <a href="http://smallcultfollowing.com/babysteps/blog/2013/11/27/thoughts-on-dst-2">posts</a>
about <a href="http://smallcultfollowing.com/babysteps/blog/2013/11/27/thoughts-on-dst-3/">dynamically</a>
sized <a href="http://smallcultfollowing.com/babysteps/blog/2013/12/02/thoughts-on-dst-4/">types</a>
on <a href="http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-take-5/">niko&rsquo;s</a>
blog.
So I will not dive into the details too much here</p>

<p>The main points are that the compiler wants to know whether a type is
meant to always have a static size, or if it can potentially be
unsized.  In a language without type polymorphism, this might be easy
to determine directly from the parsed type expression (such as in the
vector examples I gave at the outset).  But once you add polymorphism,
things get a litle harder for the compiler.</p>

<p>Anyway, the plan drafted in Niko&rsquo;s
<a href="http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-take-5/">&ldquo;DST, Take 5&rdquo;</a>
is to add an <code>unsized</code> keyword, and then use it as a marker to make
certain spots more general than they are by default.  The reasoning
here is that in the common case, you want a type parameter to
represent a sized type.  (Since there are certain operations you
cannot do with a value of an unsized type, such copying the value into
some other location, the compiler needs to know its size statically so
that it can allocate an appopriate amount of space for it.)</p>

<p>So under that scheme, to write type parameter of most general type,
e.g. for a <code>struct</code> definition that ends with an unsized field,
you need to write:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">struct</span> <span class="n">Named</span><span class="o">&lt;</span><span class="kr">unsized</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">name</span><span class="o">:</span> <span class="o">~</span><span class="kt">str</span><span class="p">,</span>
</span><span class='line'>    <span class="n">payload</span><span class="o">:</span> <span class="n">T</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Accepts solely *sized* Named&lt;T&gt;.</span>
</span><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">Named</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Accepts both sized and *unsized* Named&lt;T&gt;</span>
</span><span class='line'><span class="k">fn</span> <span class="n">bar</span><span class="o">&lt;</span><span class="kr">unsized</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">Named</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That is, you need to use what I will call a &ldquo;generalization&rdquo; marker at
the spot where you bind a type variable, to indicate that the domain of
that type variable is more general than the common-case default of
a sized type.</p>

<p>For defining a trait that can be implemented on any possible type,
including unsized ones, you would need to use the <code>unsized</code> keyword
somewhere there as well.  &ldquo;DST, Take 5&rdquo; proposed
<code>trait Foo&lt;unsized Self&gt; : NormalBounds { ... }</code>
(or <code>trait Foo : unsized + NormalBounds { ... }</code>, but this is broken for
various reasons).
I had been suggesting <code>unsized trait Foo : NormalBounds { ... }</code>,
which Niko rightly objected to (since it is not the trait that is
unsized, but rather potentially its Self type).
Over the Rust work week last week I suggested
<code>trait Foo for unsized : NormalBounds</code> { &hellip; }, which I think is the first
suggestion that Niko and myself could both stomach.  (The reasoning
behind the latter suggestion is that we write <code>impl Trait for
SelfType</code>, so it makes sense to put the generalization marker into the
same position, i.e. filling the placeholder in: <code>Trait for _</code>.)</p>

<a name="L.a.id..the_insight..The.Insight:..code.type..code..is.a.better.generalization.marker..a."></a>
<h2><a id="the_insight">The Insight: <code>type</code> is a better generalization marker</a></h2>

<p>One of the concerns that Niko has pointed out to me is that it is easy
to (mis)read <code>unsized T</code> as saying &ldquo;<code>T</code> must be unsized&rdquo;.  But that is not
what it is saying; it is saying &ldquo;<code>T</code> <em>can</em> be unsized&rdquo;; you can still pass in
a sized type for <code>T</code>.</p>

<p>I was reflecting on that this morning, and I realized something:
The whole point of DST is to partition the type universe into (Sized ⊎ Unsized).
So if you want this construct to be more self-documenting, the
generalization marker should be using some name to describe that union
(Sized ⊎ Unsized), rather than the name <code>unsized</code>.</p>

<p>But we already have a very appropriate name for that union: <code>type</code>!</p>

<p>So that started me thinking: Why don&rsquo;t we use <code>type</code> as our generalization marker?
So the definition of <code>bar</code> in the example above would be written</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">bar</span><span class="o">&lt;</span><span class="k">type</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">Named</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In fact, this can have a very simple explanation: If we keep the <code>Sized</code> trait bound,
then you can just say that</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">...){</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>desugars to</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="k">type</span> <span class="n">T</span><span class="o">:</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">...)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>and in general, any type variable formal binding <code>&lt;T:Bounds&gt;</code> desugars
to <code>&lt;type T:Sized+Bounds&gt;</code></p>

<p>I admit, when I first wrote this, I said &ldquo;hmm, this looks a bit like
C++, is that a problem?&rdquo;  But I&rsquo;m coming to like it.  The biggest
problem I can foresee is that a developer might be confused about when
they are suppposed to write <code>foo&lt;type T&gt;</code> versus <code>foo&lt;T&gt;</code>.  But chances
are that someone who does not understand the distinction will <em>not</em>
suffer if they just guess the answer; if they over-generalize, either:</p>

<ul>
<li><p>the code will compile successfully anyway, in which case there is
no harm, except perhaps w.r.t. forward-compatibility of their
library when they may have wished they had imposed the <code>Sized</code>
bound, or</p></li>
<li><p>the compiler will flag a problem in their code, in which case
hopefully our error messages will suggest to add a <code>:Sized</code> bound
or to just not use <code>type</code> in the binding for <code>T</code>.</p></li>
</ul>


<p>If they under-generalize, then they (or their library&rsquo;s clients) will
discover the problem when they apply <code>foo</code>.</p>

<p>For the trait case, it is a little less obvious what to do.
I think we could likewise write:
<code>trait Foo for type : NormalBounds</code>
for the maximally general case.
<code>trait Foo : NormalBounds</code> would then desugar to
<code>trait Foo for type : Sized + NormalBounds</code></p>

<p>So the point is that you would only use the <code>type</code> keyword when you
wanted to explicitly say &ldquo;I am generalizing over <em>all</em> types, not just
sized ones&rdquo;, and thus are opting into the additional constraints that
that scenario presents.</p>

<p>This approach wouldn&rsquo;t be so palatable under earlier envisioned
designs for DST where e.g. you were restricted to write explicitly
<code>unsized struct S { ... }</code> for structs that could end up being
unsized.  But at this point I think we have collectively decided that
such a restriction is unnecessary and undesired, so there is no worry
that someone might end up having to write <code>type struct S { ... }</code>,
which definitely looks nonsensical.</p>

<p>There is another potential advantage to this approach that I have not
explored much yet: we could also add an <code>Unsized</code> trait bound, and
allow people to write <code>&lt;type X:Unsized&gt;</code> for when they want to
restrict <code>X</code> to unsized types alone.  I am not sure whether this is
actual value in this, but it does not seem absurd to put in a special
case in the coherence checker to allow one to write
<code>impl&lt;X:Sized&gt; SomeTrait for X { ... }</code>
and
<code>impl&lt;X:Unsized&gt; SomeTrait for X { ... }</code>
in order to get full coverage of <code>SomeTrait</code> for all types.</p>

<p>Finally, another obvious (though obviously post Rust 1.0) direction
that this approach suggests is that if we decide to add
parameterization over constants, we can likewise use the <code>const</code>
keyword in the spot where I have written the generalization marker
<code>type</code>, e.g.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">fn</span> <span class="n">foo</span><span class="o">&lt;</span><span class="kr">const</span> <span class="n">N</span><span class="o">:</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">nums</span><span class="o">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="kt">f64</span><span class="p">,</span> <span class="p">..</span><span class="n">N</span><span class="p">])</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(In this case <code>const</code> would not be a generalization marker but instead
a <em>kind</em> marker, since it is changing the domain of the parameter from
being that of a type to being some value within a type.)</p>

<a name="L.a.id..the_examples..Examples.ported.from.DST..Take.5..a."></a>
<h2><a id="the_examples">Examples ported from DST, Take 5</a></h2>

<p>Here are the ported definitions of <code>Rc</code> and <code>RcData</code>.
(Update: had to turn off syntax highlighting to work-around a rendering bug on <code>*</code>.)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>struct Rc&lt;type T&gt; {
</span><span class='line'>    ptr: \*RcData&lt;T&gt;,
</span><span class='line'>    // (a dummy field, just for illustrative purposes)
</span><span class='line'>    dummy: uint,
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>struct RcData&lt;type T&gt; {
</span><span class='line'>    ref_count: uint,
</span><span class='line'>
</span><span class='line'>    #[max_alignment]
</span><span class='line'>    data: T
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>impl&lt;type T&gt; Drop for Rc&lt;T&gt; {
</span><span class='line'>    fn drop&lt;&#39;a&gt;(&amp;&#39;a mut self) {
</span><span class='line'>        unsafe {
</span><span class='line'>            intrinsics::drop(&amp;mut (*self.ptr).data);
</span><span class='line'>            libc::free(self.ptr);
</span><span class='line'>        }
</span><span class='line'>    }
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Here is the <code>ImmDeref</code> example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rust'><span class='line'><span class="k">trait</span> <span class="n">ImmDeref</span><span class="o">&lt;</span><span class="k">type</span> <span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">deref</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;a</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="n">T</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">impl</span><span class="o">&lt;</span><span class="k">type</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">ImmDeref</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">Rc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">fn</span> <span class="n">deref</span><span class="o">&lt;</span><span class="nl">&#39;a</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">&#39;a</span> <span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">&amp;</span><span class="n">&#39;a</span> <span class="n">T</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">unsafe</span> <span class="p">{</span>
</span><span class='line'>            <span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">).</span><span class="n">data</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(I think I need a wider variety of examples, but this is good enough for now.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Updating Octopress post-Mavericks upgrade.]]></title>
    <link href="http://blog.pnkfx.org/blog/2014/03/13/meta-updating-octopress-post-mavericks-upgrade/"/>
    <updated>2014-03-13T06:18:00-04:00</updated>
    <id>http://blog.pnkfx.org/blog/2014/03/13/meta-updating-octopress-post-mavericks-upgrade</id>
    <content type="html"><![CDATA[<p>I decided this morning to write a blog post related to Rust.  I have
not posted to this blog in months, and in the meantime I had upgraded
this computer at home to Mac OS X Mavericks (10.9.2).</p>

<p>So of course my existing set of commands for Octopress workflow did
not work.</p>

<!-- more -->


<p>At first there were dependencies like <code>chunky_png-1.2.7</code> that had to
be satisfied (re-installed, I assume; I am pretty sure I blew away my
previous Homebrew setup during the upgrade; I do not know how much
that overlaps with Ruby&rsquo;s package management system).</p>

<p>The few step was just blind following of the suggestions made by my
tools: <code>rake</code> suggests to run <code>bundle install</code>, and I comply.  And the results
seem promising:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% rake generate
</span><span class='line'>Could not find chunky_png-1.2.7 in any of the sources
</span><span class='line'>Run \`bundle install\` to install missing gems.
</span><span class='line'>% bundle install
</span><span class='line'>Fetching gem metadata from http://rubygems.org/.......
</span><span class='line'>Fetching gem metadata from http://rubygems.org/..
</span><span class='line'>Using rake (0.9.6)
</span><span class='line'>Using RedCloth (4.2.9)
</span><span class='line'>Installing chunky_png (1.2.7)
</span><span class='line'>Using fast-stemmer (1.0.2)
</span><span class='line'>Using classifier (1.3.3)
</span><span class='line'>Using fssm (0.2.10)
</span><span class='line'>Installing sass (3.2.5)
</span><span class='line'>Using compass (0.12.2)
</span><span class='line'>Using directory_watcher (1.4.1)
</span><span class='line'>Installing haml (3.1.8)
</span><span class='line'>Installing kramdown (0.13.8)
</span><span class='line'>Installing liquid (2.3.0)
</span><span class='line'>Using syntax (1.0.0)
</span><span class='line'>Using maruku (0.6.1)
</span><span class='line'>Using posix-spawn (0.3.6)
</span><span class='line'>Using yajl-ruby (1.1.0)
</span><span class='line'>Installing pygments.rb (0.3.7)
</span><span class='line'>Installing jekyll (0.12.0)
</span><span class='line'>Installing rack (1.4.5)
</span><span class='line'>Installing rack-protection (1.3.2)
</span><span class='line'>Using rb-fsevent (0.9.3)
</span><span class='line'>Using rdiscount (1.6.8)
</span><span class='line'>Using redcarpet (2.2.2)
</span><span class='line'>Using rubypants (0.2.0)
</span><span class='line'>Installing tilt (1.3.3)
</span><span class='line'>Installing sinatra (1.3.4)
</span><span class='line'>Installing stringex (1.4.0)
</span><span class='line'>Using bundler (1.3.5)
</span><span class='line'>Your bundle is complete!
</span><span class='line'>Use \`bundle show [gemname]\` to see where a bundled gem is installed.
</span></code></pre></td></tr></table></div></figure>


<p>But I
balked on the second step:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% rake generate
</span><span class='line'>rake aborted!
</span><span class='line'>You have already activated rake 10.1.0, but your Gemfile requires rake 0.9.6. Using bundle exec may solve this.
</span><span class='line'>/Users/pnkfelix/Dev/Sites/pnkfx-blog/Rakefile:2:in \`&lt;top (required)&gt;&#39;
</span><span class='line'>(See full trace by running task with --trace)
</span><span class='line'>% bundle exec
</span><span class='line'>bundler: exec needs a command to run
</span></code></pre></td></tr></table></div></figure>


<p>I did not understand what <code>bundle exec</code> meant here, so I did not do the &ldquo;obvious thing&rdquo;, which apparently is to re-run generate but within bundle, like so:
<code>% bundle exec rake generate</code></p>

<p>Instead I fumbled around trying to figure out what my situation was
with respect to <code>rake:</code> do I need to downgrade to a previous version?
Or do I need to upgraade its subcomponents, and/or my whole site
configuration?</p>

<p>The first things I learned from a couple web interactions:</p>

<p>From <a href="http://stackoverflow.com/questions/17474969/you-have-already-activated-rake-0-9-6-but-your-gemfile-requires-rake-10-1-0-us">stackoverflow</a>
I learned:</p>

<ul>
<li>You can find out what version(s) of a gem you have install, with
the relatively obvious <code>gem list</code> command:</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% gem list rake
</span><span class='line'>
</span><span class='line'>*** LOCAL GEMS ***
</span><span class='line'>
</span><span class='line'>rake (10.1.0, 0.9.6)
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>You can also remove particular versions of a gem, with the <code>gem
uninstall</code> command:</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% gem uninstall rake
</span><span class='line'>
</span><span class='line'>Select gem to uninstall:
</span><span class='line'> 1. rake-0.9.6
</span><span class='line'> 2. rake-10.1.0
</span><span class='line'> 3. All versions
</span><span class='line'>&gt; 1
</span><span class='line'>Successfully uninstalled rake-0.9.6
</span></code></pre></td></tr></table></div></figure>


<p>But these facts and this process did not actually help, because I
still needed <code>rake-0.9.6</code> for my site configuration, for some reason I
have not yet determined (mostly due to lack of trying).</p>

<p>I then did some more guessing and followed some false paths, like
reinstalling the <code>bundler</code> gem, uninstalling and reinstalling rake
(which effectively led to me replacing rake-10.1.0 with rake-10.1.1).</p>

<p>At some point I ran this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% bundle update rake
</span><span class='line'>Fetching gem metadata from http://rubygems.org/........
</span><span class='line'>Fetching gem metadata from http://rubygems.org/..
</span><span class='line'>Resolving dependencies...
</span><span class='line'>Installing rake (0.9.6)
</span><span class='line'>Using RedCloth (4.2.9)
</span><span class='line'>Using chunky_png (1.2.7)
</span><span class='line'>Using fast-stemmer (1.0.2)
</span><span class='line'>Using classifier (1.3.3)
</span><span class='line'>Using fssm (0.2.10)
</span><span class='line'>Using sass (3.2.5)
</span><span class='line'>Using compass (0.12.2)
</span><span class='line'>Using directory_watcher (1.4.1)
</span><span class='line'>Using haml (3.1.8)
</span><span class='line'>Using kramdown (0.13.8)
</span><span class='line'>Using liquid (2.3.0)
</span><span class='line'>Using syntax (1.0.0)
</span><span class='line'>Using maruku (0.6.1)
</span><span class='line'>Using posix-spawn (0.3.6)
</span><span class='line'>Using yajl-ruby (1.1.0)
</span><span class='line'>Using pygments.rb (0.3.7)
</span><span class='line'>Using jekyll (0.12.0)
</span><span class='line'>Using rack (1.4.5)
</span><span class='line'>Using rack-protection (1.3.2)
</span><span class='line'>Using rb-fsevent (0.9.3)
</span><span class='line'>Using rdiscount (1.6.8)
</span><span class='line'>Using redcarpet (2.2.2)
</span><span class='line'>Using rubypants (0.2.0)
</span><span class='line'>Using tilt (1.3.3)
</span><span class='line'>Using sinatra (1.3.4)
</span><span class='line'>Using stringex (1.4.0)
</span><span class='line'>Using bundler (1.3.5)
</span><span class='line'>Your bundle is updated!
</span></code></pre></td></tr></table></div></figure>


<p>but I still got the error:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% rake generate
</span><span class='line'>rake aborted!
</span><span class='line'>You have already activated rake 10.1.1, but your Gemfile requires rake 0.9.6. Using bundle exec may solve this.
</span><span class='line'>/Users/pnkfelix/Dev/Sites/pnkfx-blog/Rakefile:2:in \`&lt;top (required)&gt;&#39;
</span><span class='line'>(See full trace by running task with --trace)
</span></code></pre></td></tr></table></div></figure>


<p>and this is when I finally saw that I had to do:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% bundle exec rake generate
</span></code></pre></td></tr></table></div></figure>


<p>Except that this did not solve everything:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% bundle exec rake generate
</span><span class='line'>## Generating Site with Jekyll
</span><span class='line'>unchanged sass/screen.scss
</span><span class='line'>Configuration from /Users/pnkfelix/Dev/Sites/pnkfx-blog/_config.yml
</span><span class='line'>Building site: source -&gt; public
</span><span class='line'>YAML Exception reading 2013-04-12-better-command-completion-in-bash-aka-resolving-zsh-envy.markdown: invalid byte sequence in US-ASCII
</span><span class='line'>/Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/backtick_code_block.rb:13:in \`gsub&#39;: invalid byte sequence in US-ASCII (ArgumentError)
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/backtick_code_block.rb:13:in \`render_code_block\&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/octopress_filters.rb:12:in \`pre_filter&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/octopress_filters.rb:28:in \`pre_render&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/post_filters.rb:112:in \`block in pre_render&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/post_filters.rb:111:in \`each&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/post_filters.rb:111:in \`pre_render&#39;
</span><span class='line'>  from /Users/pnkfelix/Dev/Sites/pnkfx-blog/plugins/post_filters.rb:166:in \`do_layout&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/post.rb:195:in \`render&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:200:in \`block in render&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:199:in \`each&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:199:in \`render&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:41:in \`process&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/bin/jekyll:264:in \`&lt;top (required)&gt;&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/bin/jekyll:23:in \`load&#39;
</span><span class='line'>  from /Users/pnkfelix/.rbenv/versions/1.9.3-p194/bin/jekyll:23:in \`&lt;main&gt;&#39;
</span></code></pre></td></tr></table></div></figure>


<p>Another web search brought me to a <a href="http://otfusion.org/blog/2013/10/27/os-x-mavericks/">post by a fellow Mavericks user</a> who seems to have a similar attitude to my own about ruby development.
And from that I found the full command I needed</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>% LANG=en_US.utf-8 bundle exec rake generate
</span><span class='line'>## Generating Site with Jekyll
</span><span class='line'>unchanged sass/screen.scss
</span><span class='line'>Configuration from /Users/pnkfelix/Dev/Sites/pnkfx-blog/_config.yml
</span><span class='line'>Building site: source -&gt; public
</span><span class='line'>Successfully generated site: source -&gt; public
</span></code></pre></td></tr></table></div></figure>


<p>And here we are!</p>
]]></content>
  </entry>
  
</feed>
