<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Ricardo Martins</title>
  <subtitle>Thoughts on programming and technology.</subtitle>
  <link rel="self" type="application/atom+xml" href="https://ricardomartins.dev/atom.xml"/>
  <link rel="alternate" type="text/html" href="https://ricardomartins.dev"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  
  <updated>2016-08-03T00:00:00-05:00</updated>
  
  
  
  
  
  
  
  
  
  
  
  
  
  <id>https://ricardomartins.cc/atom.xml</id>
  
  
  <entry xml:lang="en">
    <title>Convenient and idiomatic conversions in Rust</title>
    <published>2016-08-03T00:00:00-05:00</published>
    
    <updated>2016-08-03T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2016/08/03/convenient_and_idiomatic_conversions_in_rust"/>
    
    <id>http://ricardomartins.cc/2016/08/03/convenient_and_idiomatic_conversions_in_rust</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2016/08/03/convenient_and_idiomatic_conversions_in_rust">&lt;div class=&quot;summary&quot;&gt;
  &lt;h1 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;The traits in &lt;code&gt;std::convert&lt;/code&gt; provide a uniform API for converting values to other types&lt;/li&gt;
&lt;li&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Into&amp;lt;U&amp;gt;&lt;/code&gt; are for conversions that &lt;em&gt;cannot&lt;/em&gt; fail and consume the original value&lt;/li&gt;
&lt;li&gt;&lt;code&gt;From&amp;lt;T&amp;gt; for U&lt;/code&gt; converts a value of type &lt;code&gt;T&lt;/code&gt; into one of type &lt;code&gt;U&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Into&amp;lt;U&amp;gt; for T&lt;/code&gt; inverts &lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;’s subject-object relationship&lt;/li&gt;
&lt;li&gt;Implementing &lt;code&gt;From&amp;lt;T&amp;gt; for U&lt;/code&gt; gives us an automatically derived &lt;code&gt;Into&amp;lt;U&amp;gt; for T&lt;/code&gt; implementation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;TryInto&amp;lt;U&amp;gt;&lt;/code&gt; are the equivalent traits for conversions that may fail&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; represent cheap reference-to-reference conversions, with some similarities to &lt;code&gt;Borrow&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;BorrowMut&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;We all convert data from one representation to another with some regularity. There are several situations where this need pops up: converting a wide array of types into a more convenient type, converting “foreign” error types to our libraries’ error types, and encoding and decoding network packets of our custom protocols. The first situation is probably the most common. For instance, in some cases a plain &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; is a convenient representation, so there are readily available ways to convert values of other types, such as &lt;code&gt;VecDeque&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;BinaryHeap&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;amp;[T]&lt;/code&gt;, and &lt;code&gt;&amp;amp;str&lt;/code&gt;, into &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Naturally, there is more one way to convert types in Rust, each with advantages and disadvantages. We could:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build the target types ourselves with struct literals, but that’s tedious, repetitive and exposes implementation details;&lt;/li&gt;
&lt;li&gt;create specialized constructors for each source type (e.g.: &lt;code&gt;new_from_vec_deque&lt;/code&gt;, &lt;code&gt;new_from_binary_heap&lt;/code&gt;, &lt;code&gt;new_from_slice&lt;/code&gt;), but that’s just as tedious and we might miss some cases anyway;&lt;/li&gt;
&lt;li&gt;write generic constructors that accept a certain trait, but that might still cover less cases than we need and require additional constructors;&lt;/li&gt;
&lt;li&gt;cast enum variants to integers and vice-versa, but those conversions may have &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/issues/18154&quot;&gt;unexpected results&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You get the idea: there are myriad ways of converting types, but many of them suck. &lt;em&gt;There has to be a better way!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In this article, we’ll explore how to do it in a more idiomatic way — and if you read the key takeaways you already know how 😉. The traits in the &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/index.html&quot;&gt;&lt;code&gt;std::convert&lt;/code&gt;&lt;/a&gt; module — &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.From.html&quot;&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.Into.html&quot;&gt;&lt;code&gt;Into&amp;lt;U&amp;gt;&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.TryFrom.html&quot;&gt;&lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.TryInto.html&quot;&gt;&lt;code&gt;TryInto&amp;lt;U&amp;gt;&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.AsRef.html&quot;&gt;&lt;code&gt;AsRef&amp;lt;U&amp;gt;&lt;/code&gt;&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.AsMut.html&quot;&gt;&lt;code&gt;AsMut&amp;lt;U&amp;gt;&lt;/code&gt;&lt;/a&gt; — have this exact purpose. Those traits provide a uniform API for type conversion, and we’ll be exploring how we can leverage them to achieve a consistent and ergonomic API. Once you know about them, you’ll start noticing them everywhere in the documentation. I hope that, by the end of this article you’ll probably appreciate them as much as I do.&lt;/p&gt;
&lt;h1 id=&quot;from-and-into&quot;&gt;&lt;code&gt;From&lt;/code&gt; and &lt;code&gt;Into&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.From.html&quot;&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; represents the conversion of a value of type &lt;code&gt;T&lt;/code&gt; into a target type (&lt;code&gt;impl From&amp;lt;T&amp;gt; for TargetType&lt;/code&gt;). This conversion may or may not be computationally expensive, but we can usually assume it isn’t cheap. Let’s have a look at its &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L156-L161&quot;&gt;definition&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub trait&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Sized&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// Performs the conversion.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt; contains a single method signature, &lt;code&gt;from()&lt;/code&gt;, which we’ll have to implement to perform the conversion. Inspecting &lt;code&gt;from()&lt;/code&gt;’s signature, we can tell that it moves (or consumes) the argument. Its return value, &lt;code&gt;Self&lt;/code&gt;, also clues us in to the fact that the conversion &lt;em&gt;may not fail&lt;/em&gt;. Later in this article, we’ll look into &lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt; for conversions that may fail. &lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt; is also a reflexive trait, which means that conversion of a value into its own type (&lt;code&gt;From&amp;lt;T&amp;gt; for T&lt;/code&gt;) is &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L239-L243&quot;&gt;implemented&lt;/a&gt; and returns the argument without modification.&lt;/p&gt;
&lt;p&gt;Reading on, we arrive at the symmetrical companion trait of &lt;code&gt;From&lt;/code&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.Into.html&quot;&gt;&lt;code&gt;Into&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;. Like &lt;code&gt;From&lt;/code&gt;, &lt;code&gt;Into&lt;/code&gt; has a short &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L129-L134&quot;&gt;definition&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub trait&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Into&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Sized&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// Performs the conversion.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we can see in the definition, &lt;code&gt;Into::into()&lt;/code&gt; consumes &lt;code&gt;self&lt;/code&gt; and returns &lt;code&gt;T&lt;/code&gt;, the opposite of &lt;code&gt;From::from()&lt;/code&gt;, which consumes an argument &lt;code&gt;T&lt;/code&gt; and returning &lt;code&gt;Self&lt;/code&gt;. Compare both ways of converting values:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// `from` can be called from either the `From` trait or the target type.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Calling from the target type makes our intention clearer.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; converted_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(original_value);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; converted_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; TargetType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(original_value);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// `into` is usually called directly on the original value, but we can&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// also call it from the Into trait or the source type:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; converted_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; original_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; converted_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Into&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into&lt;/span&gt;&lt;span&gt;(original_value);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While &lt;code&gt;From::from()&lt;/code&gt; focuses on the target type, &lt;code&gt;Into::into()&lt;/code&gt; focuses on the original value; yet both express the same conversion. All the conversions above are equivalent, choosing one of them is a matter of taste. Personally, I prefer using &lt;code&gt;TargetType::from(value)&lt;/code&gt; and &lt;code&gt;value.into()&lt;/code&gt;. The former makes our intention clearer, while the latter is shorter than &lt;code&gt;Into::into(value)&lt;/code&gt;. Note that we might need to add type annotations to disambiguate the intended target type if we opt any form other than &lt;code&gt;TargetType::from()&lt;/code&gt;, which clearly indicates it.&lt;/p&gt;
&lt;p&gt;A nice thing about implementing &lt;code&gt;From&amp;lt;T&amp;gt; for U&lt;/code&gt; is that it implies &lt;code&gt;Into&amp;lt;U&amp;gt; for T&lt;/code&gt;, which means we get an automatic &lt;code&gt;Into&lt;/code&gt; implementation &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L231-L237&quot;&gt;for free&lt;/a&gt; (the opposite isn’t true):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// From implies Into&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Into&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; where&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A secondary advantage of having an &lt;code&gt;Into&lt;/code&gt; implementation (it doesn’t matter if it’s explicit or automatic) is that we can use it to broaden function arguments from a specific type to any type can be converted into the target type, as shown in the following example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Instead of targetting a specific type like this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; do_something&lt;/span&gt;&lt;span&gt;(value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; TargetType&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// We can broaden the accepted types with the following:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; do_something&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Into&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;TargetType&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;(value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; converted_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alright, that’s enough theory. A couple of examples will make it easier to understand how all this works in practice.&lt;/p&gt;
&lt;h2 id=&quot;example-sortedvect&quot;&gt;Example: &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Suppose we have a sorted vector type, &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt;. Since it’s a general data structure, building a &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt; from slice- and list-like types makes sense, so we’ll implement those conversions:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Our simple sorted vector structure is just a wrapper around a Vec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Converting slices into SortedVec is pretty much expected.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ord&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;]&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; from&lt;/span&gt;&lt;span&gt;(slice&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let mut&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; slice&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;to_owned&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;sort&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        SortedVec&lt;/span&gt;&lt;span&gt;(vec)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Converting a Vec is also expected.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// We can sort the vector in place and then put it inside SortedVec.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ord&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;mut&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;sort&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        SortedVec&lt;/span&gt;&lt;span&gt;(vec)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Converting a LinkedList also makes sense, but it has no&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// slice representation, so we&amp;#39;ll have to rely on its iterator.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ord&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;LinkedList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; from&lt;/span&gt;&lt;span&gt;(list&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; LinkedList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let mut&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; list&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;cloned&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;sort&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        SortedVec&lt;/span&gt;&lt;span&gt;(vec)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you might protest that the conversion from &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; is redundant, because we can get a slice from the vector and then convert the slice. That’s absolutely correct, dear reader. However, the implementation above avoids cloning the vector, and, in my opinion, hiding any intermediate steps leads to a more pleasant API.&lt;/p&gt;
&lt;p&gt;As a result of the trait implementations above, we can call &lt;code&gt;SortedVec::from()&lt;/code&gt; without caring if the argument is a slice, &lt;code&gt;Vec&lt;/code&gt; or &lt;code&gt;LinkedList&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Convert a slice&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; sorted&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;vec[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;..&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// ... a vector&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; sorted&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(vec);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// ... a linked list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let mut&lt;/span&gt;&lt;span&gt; linked_list&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; LinkedList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; LinkedList&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;linked_list&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;extend&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; sorted&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(linked_list);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can also go in the opposite direction and implement conversions from &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt; into other types (for instance, into &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;). However, there are some restrictions about implementing traits for non-local, generic types — check &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/error-index.html#E0210&quot;&gt;error 0210&lt;/a&gt; and the related &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rfcs/pull/1023&quot;&gt;Rust RFC 1023&lt;/a&gt;. As a rule of thumb, if the non-local type isn’t generic over some type parameter, you can implement &lt;code&gt;From&lt;/code&gt; for it.&lt;/p&gt;
&lt;h2 id=&quot;example-packettype&quot;&gt;Example: &lt;code&gt;PacketType&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Let’s take a different example. Suppose we are now implementing a library for a network protocol where the first byte in a packet header tells us the packet type. A reasonable solution is representing the packet types with an enumeration, where each variant maps to a packet type. For instance:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Represents a packet type.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Associated with each variant is its raw numeric representation.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; PacketType&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    Data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;  =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // packet carries a data payload&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    Fin&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;   =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // signals the end of a connection&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    State&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // signals acknowledgment of a packet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    Reset&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // forcibly terminates a connection&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    Syn&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;   =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // initiates a new connection with a peer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given this representation, how shall we convert to and from the byte representation?&lt;/p&gt;
&lt;p&gt;The traditional way, very common in C and C++ programs, is to simply cast the values from one type to another. That can also be done in Rust; for instance, converting &lt;code&gt;PacketType::Data&lt;/code&gt; into a byte is as simple as &lt;code&gt;PacketType::Data as u8&lt;/code&gt;. That seems to take care of encoding a &lt;code&gt;PacketType&lt;/code&gt; into a byte representation, but we aren’t done yet.&lt;/p&gt;
&lt;p&gt;Did you notice that each &lt;code&gt;PacketType&lt;/code&gt; variant has an associated value? They define the variants’ representation in the generated code. If we followed the usual Rust style and didn’t assign the variants any values, the numeric representation of each variant would depend on the order they are declared, which can lead to errors if we simply cast enum variants into numeric types. A better way to convert the enum variants to the correct values is an explicit &lt;code&gt;match&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; u8&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; from&lt;/span&gt;&lt;span&gt;(original&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; PacketType&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; u8&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        match&lt;/span&gt;&lt;span&gt; original {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;            PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;  =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;            PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Fin&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;   =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;            PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;            PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;            PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Syn&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;   =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pretty straightforward, right? Since the mapping from &lt;code&gt;PacketType&lt;/code&gt; to &lt;code&gt;u8&lt;/code&gt; is contained in the implementation of &lt;code&gt;From&lt;/code&gt;, we can remove the values assigned to &lt;code&gt;PacketType&lt;/code&gt;’s variants, resulting in a cleaner enum definition.&lt;/p&gt;
&lt;h3 id=&quot;what-about-the-opposite-conversion&quot;&gt;What about the opposite conversion?&lt;/h3&gt;
&lt;p&gt;According to the &lt;a rel=&quot;external&quot; href=&quot;https://www.rust-lang.org/en-US/faq.html#how-can-i-convert-a-c-style-enum-to-an-integer&quot;&gt;Frequently Asked Questions&lt;/a&gt;, converting an enum into an integer can be achieved with a cast, as we saw. However, the opposite conversion can (and I argue that, in many cases, it &lt;em&gt;should&lt;/em&gt;) be made with a &lt;code&gt;match&lt;/code&gt; statement. For ease of use and better ergonomics, implementing &lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt; for conversions in both directions is usually a good idea.&lt;/p&gt;
&lt;p&gt;Casting a &lt;code&gt;PacketType&lt;/code&gt; to &lt;code&gt;u8&lt;/code&gt; is generally safe and correct, with the caveats we saw before, because for every &lt;code&gt;PacketType&lt;/code&gt; variant, there’s a corresponding representation compatible with &lt;code&gt;u8&lt;/code&gt;. However, the reverse is decidedly &lt;strong&gt;not&lt;/strong&gt; true: converting an &lt;code&gt;u8&lt;/code&gt; value without a corresponding &lt;code&gt;PacketType&lt;/code&gt; variant is undefined behavior! Quoth the &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/reference.html#behavior-considered-undefined&quot;&gt;Rust reference&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Behavior considered undefined&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid values in primitive types, even in private fields/locals:
&lt;ul&gt;
&lt;li&gt;A discriminant in an enum not included in the type definition&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Although we can map any &lt;code&gt;PacketType&lt;/code&gt; variant into an &lt;code&gt;u8&lt;/code&gt; value, we can’t do the reverse and map any &lt;code&gt;u8&lt;/code&gt; into a &lt;code&gt;PacketType&lt;/code&gt;: there are too many &lt;code&gt;u8s&lt;/code&gt; and not enough &lt;code&gt;PacketTypes&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;So for the &lt;code&gt;u8&lt;/code&gt; to &lt;code&gt;PacketType&lt;/code&gt; conversion, we can’t simply match on &lt;code&gt;u8&lt;/code&gt; value and return the appropriate &lt;code&gt;PacketType&lt;/code&gt; variant like we did for the opposite conversion. We need a way to signal that the conversion failed, but calling &lt;code&gt;panic!()&lt;/code&gt; is not an acceptable option. We need a fallible &lt;code&gt;From&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;do-or-do-not-there-is-no-try&quot;&gt;“Do or do not; there is no &lt;code&gt;Try&lt;/code&gt;”&lt;/h1&gt;
&lt;p&gt;We saw that the conversions made by &lt;code&gt;From&lt;/code&gt; and &lt;code&gt;Into&lt;/code&gt; must not fail. However, sometimes we deal with types that don’t fully map onto one another, so we need fallible versions of those traits. Fortunately, there’s both &lt;code&gt;TryFrom&lt;/code&gt; and &lt;code&gt;TryInto&lt;/code&gt;, which return a &lt;code&gt;Result&amp;lt;TargetType, ErrorType&amp;gt;&lt;/code&gt;. Both live in &lt;code&gt;std::convert&lt;/code&gt; along with their infallible siblings, but their exact details and implications are &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/issues/33417&quot;&gt;still under debate&lt;/a&gt;, which means they’re still marked as unstable. To use them, we can restrict ourselves to the nightly version of the compiler, use the &lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/try_from&quot;&gt;&lt;code&gt;try_from&lt;/code&gt; crate&lt;/a&gt;, or paste &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L163-L185&quot;&gt;their definitions&lt;/a&gt; somewhere in our crates (they’re really short).&lt;/p&gt;
&lt;p&gt;Let’s have a look at &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L177-L185&quot;&gt;&lt;code&gt;TryFrom&lt;/code&gt;’s definition&lt;/a&gt; (as of Rust 1.10.0):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[unstable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;try_from&amp;quot;&lt;/span&gt;&lt;span&gt;, issue &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;33417&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub trait&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; TryFrom&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Sized&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// The type returned in the event of a conversion error.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    type&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Err&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// Performs the conversion.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; try_from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Err&lt;/span&gt;&lt;span&gt;&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First we have a stability &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/reference.html#attributes&quot;&gt;attribute&lt;/a&gt; marking the trait as unstable, followed by the trait definition itself. We can see it has an associated type, &lt;code&gt;Err&lt;/code&gt;, for the cases where the conversion fails. As expected, we have a &lt;code&gt;try_from&lt;/code&gt; method instead of &lt;code&gt;from&lt;/code&gt;, which returns &lt;code&gt;Result&amp;lt;Self, Self::Err&amp;gt;&lt;/code&gt; instead of &lt;code&gt;Self&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Keeping with our example, we would have:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; TryFrom&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; PacketType&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    type&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Err&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; ParseError&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; try_from&lt;/span&gt;&lt;span&gt;(original&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; u8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Err&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        match&lt;/span&gt;&lt;span&gt; original {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;            0&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Data&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;            1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Fin&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;            2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;State&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;            3&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Reset&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;            4&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;PacketType&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Syn&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;ParseError&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;InvalidPacketType&lt;/span&gt;&lt;span&gt;(n))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we return the corresponding &lt;code&gt;PacketType&lt;/code&gt; variant for values which can be mapped and an error for the remaining ones. This error type preserves the original value, which is potentially useful for debugging purposes, but we could just discard it instead.&lt;/p&gt;
&lt;h1 id=&quot;asref-and-asmut&quot;&gt;&lt;code&gt;AsRef&lt;/code&gt; and &lt;code&gt;AsMut&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;Last but not least, we’re going to examine the remaining traits in the &lt;code&gt;std::convert&lt;/code&gt; module: &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.AsRef.html&quot;&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/convert/trait.AsMut.html&quot;&gt;&lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;. Like the other traits in this module, they are used to implement conversions among types. However, whereas the other traits consume values and may perform costly operations, &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; are used to implement cheap, reference-to-reference conversions.&lt;/p&gt;
&lt;p&gt;As you have probably guessed from their names, &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; converts an immutable reference to a value into another immutable reference, while &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; does the same for mutable references.&lt;/p&gt;
&lt;p&gt;Since they’re both very similar, we’re going to explore them at the same time. Let’s start with &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L77-L99&quot;&gt;their definitions&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub trait&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// Performs the conversion.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub trait&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsMut&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    /// Performs the conversion.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both take references to &lt;code&gt;self&lt;/code&gt; and return references to the target type with the same mutability as &lt;code&gt;self&lt;/code&gt;. Using these traits requires no more than calling &lt;code&gt;as_ref()&lt;/code&gt; or &lt;code&gt;as_mut()&lt;/code&gt; on a value, depending on which conversion we need, like so: &lt;code&gt;value.as_ref()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Implementing &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; is sensible and easy when the source type is a wrapper around the target type, like the &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt; example we used before. Since &lt;code&gt;SortedVec&amp;lt;T&amp;gt;&lt;/code&gt; relies on a &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, implementing both traits is painless:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// SortedVec&amp;lt;T&amp;gt; is a tuple struct, containing a single Vec&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Implementing AsRef&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt; for SortedVec&amp;lt;T&amp;gt; only requires&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// returning a reference to SortedVec&amp;lt;T&amp;gt;&amp;#39;s single field.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Implementing AsMut&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt; is just as easy.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// Note that this allows the user to mutate the underlying Vec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// such that it&amp;#39;s no longer sorted, so you might want to avoid&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/// implementing this trait!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsMut&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        &amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; also allow us to broaden the argument type from a specific reference type to any type that can be cheaply converted to the target reference type, just like &lt;code&gt;Into&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; manipulate_vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; V&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;(vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; V&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;usize&lt;/span&gt;&lt;span&gt;, ()&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Now we can call `manipulate_vector` with a Vec&amp;lt;T&amp;gt; or anything that can&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// be cheaply converted to Vec&amp;lt;T&amp;gt;, such as SortedVec&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; sorted_vec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; SortedVec&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; manipulate_vector&lt;/span&gt;&lt;span&gt;(sorted_vec) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; are very similar to &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/borrow/trait.Borrow.html&quot;&gt;&lt;code&gt;Borrow&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/borrow/trait.BorrowMut.html&quot;&gt;&lt;code&gt;BorrowMut&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;, but semantically different. The Rust Programming Language Book discusses those &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/borrow-and-asref.html&quot;&gt;differences in detail&lt;/a&gt;, but as a rule of thumb, we choose &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; when we want to convert references or when writing generic code, and &lt;code&gt;Borrow&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;BorrowMut&amp;lt;T&amp;gt;&lt;/code&gt; when we wish to disregard whether a value is owned or borrowed (for instance, we might want a value to have the same &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/hash/trait.Hash.html&quot;&gt;hash&lt;/a&gt; independently of it being owned or not).&lt;/p&gt;
&lt;p&gt;There are a few interesting &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/convert.rs#L191-L229&quot;&gt;generic implementations&lt;/a&gt; for &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// As lifts over &amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; where&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// As lifts over &amp;amp;mut&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; where&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;as_ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// AsMut lifts over &amp;amp;mut&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsMut&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; where&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AsMut&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;U&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; as_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; &amp;amp;mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; U&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;as_mut&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those generic implementations may look intimidating, but looks are deceiving. Reading them slowly, we can see the traits are implemented for &lt;em&gt;references&lt;/em&gt; to types that implement &lt;code&gt;AsRef&amp;lt;U&amp;gt;&lt;/code&gt; or &lt;code&gt;AsMut&amp;lt;U&amp;gt;&lt;/code&gt; (&lt;code&gt;&amp;amp;&#39;a T where T: AsRef&amp;lt;U&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;amp;&#39;a mut T where T: AsRef&amp;lt;U&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;amp;&#39;a mut T where T: AsMut&amp;lt;U&amp;gt;&lt;/code&gt;). We can also see that every implementation dereferences the argument, which is a reference.&lt;/p&gt;
&lt;p&gt;The result is rather useful: these trait implementations make references to references (to references to references…) behave as if they were simple, direct references. That is to say, they make multiple-level deep references such as &lt;code&gt;&amp;amp;&amp;amp;&amp;amp;&amp;amp;vec&lt;/code&gt; (in the case of the first implementation) and &lt;code&gt;&amp;amp;&amp;amp;&amp;amp;&amp;amp; mut vec&lt;/code&gt; (in the case of the second) equivalent to &lt;code&gt;&amp;amp;vec&lt;/code&gt;, while the third implementation makes &lt;code&gt;&amp;amp;mut &amp;amp;mut vec&lt;/code&gt; equivalent to &lt;code&gt;&amp;amp;mut vec&lt;/code&gt;. After those conversions, any compatible conversions we explicitly implemented can be applied.&lt;/p&gt;
&lt;h1 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h1&gt;
&lt;p&gt;In this article we dove into &lt;code&gt;std::convert&lt;/code&gt; and explored how we can use its traits — &lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Into&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;TryInto&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt; — to achieve a uniform type conversion API. The table below summarizes the characteristics of those traits.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;th&gt;receives&lt;/th&gt;&lt;th&gt;returns&lt;/th&gt;&lt;th&gt;can fail?&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Self&lt;/code&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Result&amp;lt;Self, E&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Into&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;self&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TryInto&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;self&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;self&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;mut&lt;/code&gt; &lt;code&gt;self&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;mut&lt;/code&gt; &lt;code&gt;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;In short:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Into&amp;lt;T&amp;gt;&lt;/code&gt;, and their fallible counterparts, &lt;code&gt;TryFrom&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;TryInto&amp;lt;T&amp;gt;&lt;/code&gt;, operate on &lt;em&gt;values&lt;/em&gt; and perform conversions that may be costly;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AsRef&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;AsMut&amp;lt;T&amp;gt;&lt;/code&gt;, on the other hand, take references to values and perform cheap reference-to-reference conversions;&lt;/li&gt;
&lt;li&gt;We can look at &lt;code&gt;From::from()&lt;/code&gt; as if it were a woodchipper that we can feed with any of the approved types of wood;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;From&amp;lt;T&amp;gt; for U&lt;/code&gt; implies &lt;code&gt;Into&amp;lt;U&amp;gt; for T&lt;/code&gt;, it’s usually preferable to implement only the former and get the other for free,&lt;/li&gt;
&lt;li&gt;We can make our methods more general by using those traits as type constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that you know about these traits, go ahead and use them in your crates. Your API will be more ergonomic and idiomatic, and its users will appreciate the convenience.&lt;/p&gt;
&lt;p&gt;I hope you found this article useful! What should we explore next? Tell me on Twitter (&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/meqif&quot;&gt;@meqif&lt;/a&gt;) or send me an email (&lt;a href=&quot;mailto:words@ricardomartins.cc&quot;&gt;words@ricardomartins.cc&lt;/a&gt;). You can also discuss the article on &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4w14yd/convenient_and_idiomatic_conversions_in_rust/&quot;&gt;reddit&lt;/a&gt;. If you don’t want to miss the next articles, sign up for my newsletter in the form below. 👇&lt;/p&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Interior mutability in Rust, part 3: behind the curtain</title>
    <published>2016-07-11T00:00:00-05:00</published>
    
    <updated>2016-07-11T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain"/>
    
    <id>http://ricardomartins.cc/2016/07/11/interior-mutability-behind-the-curtain</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain">&lt;div class=&quot;summary&quot;&gt;
  &lt;h1 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UnsafeCell&lt;/code&gt; is the keystone for building interior mutability types (&lt;code&gt;Cell&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UnsafeCell&lt;/code&gt; wraps around a value and provides a raw mutable pointer to it&lt;/li&gt;
&lt;li&gt;It depends on a special compiler path that avoids undefined behavior related to the raw pointer&lt;/li&gt;
&lt;li&gt;It lacks synchronization primitives and has a very bare-bones API&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; provide convenient APIs to access their &lt;code&gt;UnsafeCell&lt;/code&gt;’s inner value, with negligible-to-none run-time overhead&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt; provide synchronized access to &lt;code&gt;UnsafeCell&lt;/code&gt;’s inner value&lt;/li&gt;
&lt;li&gt;Avoid using &lt;code&gt;UnsafeCell&lt;/code&gt; except when you’re absolutely sure you don’t want any of the other types&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;This article is part of a series about interior mutability in Rust. You can read &lt;a href=&quot;/2016/06/08/interior-mutability&quot;&gt;part 1 here&lt;/a&gt; and &lt;a href=&quot;/2016/06/25/interior-mutability-thread-safety&quot;&gt;part 2 here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In the previous articles, we looked at interior mutability in Rust from a practical standpoint, but we didn’t explore the magic that made it work. In this article we’ll pull back the curtain and &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/The_Wizard_of_Oz_(1939_film)&quot;&gt;stare at the man lurking behind&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A good place to start is reading the definition of &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L155-L161&quot;&gt;&lt;code&gt;Cell&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L318-L325&quot;&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/rwlock.rs#L68-L73&quot;&gt;&lt;code&gt;RwLock&lt;/code&gt;&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/mutex.rs#L115-L125&quot;&gt;&lt;code&gt;Mutex&lt;/code&gt;&lt;/a&gt; to gather some clues. Luckily, a pattern quickly emerges: all of them contain a field with a common type: &lt;code&gt;UnsafeCell&lt;/code&gt;.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; We’ll first explore what it is, then figure out how it is used by those types.&lt;/p&gt;
&lt;h1 id=&quot;what-is-unsafecell&quot;&gt;What is &lt;code&gt;UnsafeCell&lt;/code&gt;?&lt;/h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html&quot;&gt;&lt;code&gt;UnsafeCell&lt;/code&gt;&lt;/a&gt; is defined in the documentation as “the core primitive for interior mutability in Rust”. Indeed, we stumbled on it every time we looked at the definition of types that provide interior mutability. However, for all its apparent power, its definition seems rather boring:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[lang &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;unsafe_cell&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[stable(feature &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;rust1&amp;quot;&lt;/span&gt;&lt;span&gt;, since &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; UnsafeCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it? The keystone for interior mutability looks like a &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/structs.html#tuple-structs&quot;&gt;newtype struct&lt;/a&gt; with some weird stuff before?&lt;/p&gt;
&lt;p&gt;Those strange lines right above the structure definition are compiler attributes. We can mostly ignore the second, as it simply marks the function as stable since version 1.0.0 of the compiler, meaning it can be used in any channel (stable, beta, and nightly). The first one is more interesting: it’s a &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/lang-items.html&quot;&gt;lang item&lt;/a&gt;, a sort of special wink and nudge to the compiler. I’ll get to it later.&lt;/p&gt;
&lt;p&gt;Apart from &lt;code&gt;new()&lt;/code&gt; and &lt;code&gt;into_inner()&lt;/code&gt;, which are humdrum methods, there’s also a &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L954-L956&quot;&gt;&lt;code&gt;get()&lt;/code&gt;&lt;/a&gt; method:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt; *mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;value &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;as *const&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; as *mut&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even though it’s a small method, we can tell it’s somewhat unusual: it takes an immutable reference to the inner value (&lt;code&gt;&amp;amp;self.value&lt;/code&gt;) and then &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/casting-between-types.html#coercion&quot;&gt;casts&lt;/a&gt; it twice: first into a raw constant pointer (&lt;code&gt;*const T&lt;/code&gt;), and then into a raw mutable pointer (&lt;code&gt;*mut T&lt;/code&gt;), which is returned to the caller.&lt;/p&gt;
&lt;p&gt;Raw pointers, eh? That’s new. Let’s take a look.&lt;/p&gt;
&lt;h2 id=&quot;raw-pointers&quot;&gt;Raw pointers&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/raw-pointers.html&quot;&gt;Raw pointers&lt;/a&gt; are similar to references, which we are used to. Both point to a memory address, but there are important differences. References are smart: they have safety guarantees (such as pointing to valid memory and never being null), borrow checking and lifetimes. Raw pointers, on the other hand, are… well, raw. They have none of those features, and simply point to a memory address, like pointers in C. Most importantly, they don’t have aliasing or mutability guarantees, unlike references. There are two kinds of raw pointers: constant (&lt;code&gt;*const T&lt;/code&gt;) and mutable (&lt;code&gt;*mut T&lt;/code&gt;). The difference between them is that mutation is not directly allowed on constant pointers, but we can easily cast them into mutable pointers and then mutate the value.&lt;/p&gt;
&lt;p&gt;You might have noticed that &lt;code&gt;get()&lt;/code&gt; isn’t marked &lt;code&gt;unsafe&lt;/code&gt;, even though we are coercing an immutable reference into a raw mutable pointer and dropping Rust’s safety guarantees along the way. Shouldn’t this trip up some alarms?&lt;/p&gt;
&lt;p&gt;Coercing (i.e., converting) an immutable reference into a raw constant pointer isn’t too bad. It could be argued that it’s safe, since the immutability of the reference is preserved and we’re starting from a reference, which has the safety guarantees we saw above, so the resulting raw pointer won’t be invalid or null. Going from a raw constant pointer to a raw &lt;em&gt;mutable&lt;/em&gt; pointer, on the other hand, seems much worse, because we’re suddenly saying it’s fine to mutate a value we have no business mutating. Going from there back to a &lt;em&gt;mutable&lt;/em&gt; reference is &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/nomicon/transmutes.html&quot;&gt;definitively bad&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thinking some more about it, those conversions aren’t actually dangerous by themselves, as they have no side-effects on their own. It’s actually using (i.e., dereferencing) the raw pointers that’s potentially dangerous. As such, when we try to dereference the pointer returned by &lt;code&gt;get()&lt;/code&gt; like in &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=e7ba86944009a4564fb74aa931c0eb79&quot;&gt;this example&lt;/a&gt;, the compiler tells us that we’re about to do something potentially dangerous:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error: dereference of raw pointer requires unsafe function or block [E0133]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Surrounding the dereference with an unsafe block signals to the compiler that we’re taking responsibility for all potential badness that may come. In the example, we know the pointer is safe because it was created from a reference and, most importantly, we didn’t mutate its value, so it’ll work &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=0ce6d15aba4fe5b21bd6c667a853791a&quot;&gt;as expected&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even so, mutating non-mutable data is considered &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/reference.html#behavior-considered-undefined&quot;&gt;undefined behavior&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mutating non-mutable data (that is, data reached through a shared reference or data owned by a let binding), unless that data is contained within an UnsafeCell&amp;lt;U&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, we’re back at the beginning: what makes &lt;code&gt;UnsafeCell&lt;/code&gt; special?&lt;/p&gt;
&lt;h2 id=&quot;-a-dash-of-magic-&quot;&gt;✨ A dash of magic ✨&lt;/h2&gt;
&lt;p&gt;Remember the lang item that preceded &lt;code&gt;UnsafeCell&lt;/code&gt;’s definition? Here it is again:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[lang &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;unsafe_cell&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It triggers special treatment by the compiler: &lt;code&gt;UnsafeCell&lt;/code&gt; gets a special marker that follows it during the various compilation phases, until it finally triggers a &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/librustc_trans/abi.rs#L369-L382&quot;&gt;particular code path&lt;/a&gt;. This section of code checks for the presence of that marker and, if it is present, avoids setting two &lt;a rel=&quot;external&quot; href=&quot;http://llvm.org&quot;&gt;LLVM&lt;/a&gt; attributes that get applied to regular types: namely, that the value is read-only and there are no aliases. Those attributes, when present, may allow some additional optimization by LLVM, which can interfere with the behavior we want for &lt;code&gt;UnsafeCell&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, that doesn’t mean we absolutely can’t get similar results without the lang item — we can&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;, but that’s purely coincidental and relies on undefined behavior which may eat our laundry, depending on the compiler’s mood (i.e., the generated code may change unexpectedly).&lt;/p&gt;
&lt;p&gt;That aside, notice that there is no synchronization inside &lt;code&gt;get()&lt;/code&gt;, which makes &lt;code&gt;UnsafeCell&lt;/code&gt; unsafe to be used by multiple threads and is thus marked &lt;code&gt;!Sync&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=1c993b661b3194f5554f8751e946894e&amp;amp;version=nightly&amp;amp;backtrace=0&quot;&gt;little experiment&lt;/a&gt; shows that using an &lt;code&gt;UnsafeCell&lt;/code&gt; incurs no run-time costs after compiler optimization, and is nearly indistinguishable from a “raw” variable, as expected from Rust’s zero-overhead abstractions.&lt;/p&gt;
&lt;p&gt;And that’s it for &lt;code&gt;UnsafeCell&lt;/code&gt;. It’s a little amazing, but this tiny structure with a very simple method and some compiler support is enough to build upon and create all the other interior mutability types we explored before. A dash of magic is enough. ✨&lt;/p&gt;
&lt;h1 id=&quot;how-is-it-used&quot;&gt;How is it used?&lt;/h1&gt;
&lt;p&gt;Now that we know what &lt;code&gt;UnsafeCell&lt;/code&gt; is like, let’s explore how the other types build upon it.&lt;/p&gt;
&lt;h2 id=&quot;cell&quot;&gt;&lt;code&gt;Cell&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Let’s start with &lt;code&gt;Cell&lt;/code&gt;, the simplest of the bunch. &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L155-L161&quot;&gt;Its definition&lt;/a&gt; is exceedingly succinct:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; UnsafeCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This suggests that &lt;code&gt;Cell&lt;/code&gt; merely provides a nicer API to access the inner value contained in &lt;code&gt;UnsafeCell&lt;/code&gt;. If we take a gander at &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L194-L196&quot;&gt;&lt;code&gt;Cell::get&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L211-L215&quot;&gt;&lt;code&gt;Cell::set&lt;/code&gt;&lt;/a&gt;, we can see that &lt;code&gt;UnsafeCell::get()&lt;/code&gt; is enough to implement both methods, and that the implementation details, such as the unsafe blocks, are hidden from the user:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsafe&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;() }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;, value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        *&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There’s an important detail in &lt;code&gt;Cell&lt;/code&gt;’s &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L163&quot;&gt;impl declaration&lt;/a&gt;: it’s restricted to &lt;code&gt;Copy&lt;/code&gt; types.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Copy&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without this restriction, we would be able to create instances of &lt;code&gt;Cell&lt;/code&gt; around &lt;code&gt;!Copy&lt;/code&gt; types, such as &lt;code&gt;&amp;amp;mut T&lt;/code&gt; (mutable references), which is a &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/marker/trait.Copy.html#when-can-my-type-not-be-copy&quot;&gt;terrible idea&lt;/a&gt;: doing so would create aliased mutable references and break the aliasing rules.&lt;/p&gt;
&lt;h2 id=&quot;refcell&quot;&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;RefCell&lt;/code&gt; is only slightly more complicated than &lt;code&gt;Cell&lt;/code&gt;. It contains an &lt;code&gt;UnsafeCell&lt;/code&gt; field with the inner value, just like &lt;code&gt;Cell&lt;/code&gt;, and a &lt;code&gt;Cell&lt;/code&gt; with a borrow flag to track the borrow state:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; RefCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    borrow&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;BorrowFlag&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; UnsafeCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We saw in the &lt;a href=&quot;/2016/06/08/interior-mutability&quot;&gt;first article&lt;/a&gt; of the series that we need to call &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L438-L446&quot;&gt;&lt;code&gt;borrow&lt;/code&gt;&lt;/a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L486-L494&quot;&gt;&lt;code&gt;borrow_mut&lt;/code&gt;&lt;/a&gt; on &lt;code&gt;RefCell&lt;/code&gt; before accessing the value inside. Both methods have similar implementations and convert the raw pointer they get from &lt;code&gt;UnsafeCell::get()&lt;/code&gt; to the value back into a reference with &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/raw-pointers.html#references-and-raw-pointers&quot;&gt;&lt;code&gt;&amp;amp;*&lt;/code&gt;&lt;/a&gt;. For brevity’s sake, we’ll look at just &lt;code&gt;RefCell::borrow()&lt;/code&gt;, since &lt;code&gt;RefCell::borrow_mut()&lt;/code&gt; is very similar.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; borrow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ref&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    match&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; BorrowRef&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;borrow) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        Some&lt;/span&gt;&lt;span&gt;(b)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ref&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; &amp;amp;*&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;() },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            borrow&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; b,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        None&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; panic!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;RefCell&amp;lt;T&amp;gt; already mutably borrowed&amp;quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There’s the call to &lt;code&gt;UnsafeCell::get()&lt;/code&gt; and conversion back into a reference. Where’s the update to &lt;code&gt;RefCell&lt;/code&gt;’s borrow state, though?&lt;/p&gt;
&lt;p&gt;Reading &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L593-L604&quot;&gt;&lt;code&gt;BorrowRef::new()&lt;/code&gt;&lt;/a&gt; makes things clear. Roughly, when that method is called, it checks &lt;code&gt;RefCell&lt;/code&gt;’s &lt;code&gt;borrow&lt;/code&gt; field (which it received as argument) and updates it if the value can be borrowed. Since the borrow field is a &lt;code&gt;Cell&lt;/code&gt;, &lt;code&gt;BorrowRef&lt;/code&gt; can mutate it, even though it received an immutable reference to it!&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L486-L494&quot;&gt;&lt;code&gt;RefCell::borrow_mut()&lt;/code&gt;&lt;/a&gt; is very similar, except that it calls &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libcore/cell.rs#L824-L835&quot;&gt;&lt;code&gt;BorrowRefMut::new()&lt;/code&gt;&lt;/a&gt; instead of &lt;code&gt;BorrowRef::new()&lt;/code&gt;, and returns a mutable reference (to be precise, it returns a &lt;code&gt;RefMut&lt;/code&gt;, which implements &lt;code&gt;DerefMut&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;We can conclude, then, that &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; are lightweight wrappers around &lt;code&gt;UnsafeCell&lt;/code&gt;, giving us a convenient API to access &lt;code&gt;UnsafeCell&lt;/code&gt;’s inner value and shielding us from dangerous pointer dereferences. In the case of &lt;code&gt;Cell&lt;/code&gt;, there’s no run-time cost after optimization, while &lt;code&gt;RefCell&lt;/code&gt;’s dynamic borrow checking mechanism incurs a small overhead. Additionally, &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; are “tainted” by &lt;code&gt;UnsafeCell&lt;/code&gt;’s &lt;code&gt;!Sync&lt;/code&gt; marker.&lt;/p&gt;
&lt;h2 id=&quot;rwlock-and-mutex&quot;&gt;&lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;In contrast to &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt; are more complex data structures which provide synchronized access to the inner value, allowing them to implement &lt;code&gt;Sync&lt;/code&gt; and honor that guarantee. We won’t be diving deep into them, but looking at &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/rwlock.rs#L195-L200&quot;&gt;&lt;code&gt;RwLock::read()&lt;/code&gt;&lt;/a&gt; we can see similarities to &lt;code&gt;RefCell::borrow()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; LockResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RwLockReadGuard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;read&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        RwLockReadGuard&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;*&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner,&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;data)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Untangling that a little, we can see that first an inner lock&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; is locked, then a &lt;code&gt;ReadLockReadGuard&lt;/code&gt; is created. Similarly to what &lt;code&gt;BorrowRef&lt;/code&gt; does for &lt;code&gt;RefCell&lt;/code&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/rwlock.rs#L461-L470&quot;&gt;&lt;code&gt;RwLockReadGuard::new()&lt;/code&gt;&lt;/a&gt; converts the raw pointer it got after calling &lt;code&gt;UnsafeCell::get()&lt;/code&gt; into a reference:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;unsafe fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; new&lt;/span&gt;&lt;span&gt;(lock&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;rwlock StaticRwLock&lt;/span&gt;&lt;span&gt;, data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;rwlock UnsafeCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;              -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; LockResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RwLockReadGuard&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;rwlock&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    poison&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map_result&lt;/span&gt;&lt;span&gt;(lock&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;poison&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;borrow&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; |&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        RwLockReadGuard&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            __lock&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; lock,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            __data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;*&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/rwlock.rs#L247-L252&quot;&gt;&lt;code&gt;RwLock::write()&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sync/mutex.rs#L237-L242&quot;&gt;&lt;code&gt;Mutex::lock()&lt;/code&gt;&lt;/a&gt; follow a similar pattern to &lt;code&gt;RwLock::read()&lt;/code&gt;, so there’s no need to explore them individually.&lt;/p&gt;
&lt;h1 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h1&gt;
&lt;p&gt;In this article we learned that far from relying on arcane magic, interior mutability is achieved thanks to &lt;code&gt;UnsafeCell&lt;/code&gt;, a neat little structure that allows the creation of more ergonomic abstractions on top of it.&lt;/p&gt;
&lt;p&gt;Since its API involves unsafe operations, using it directly is a little cumbersome. In nearly every case where we need interior mutability, we are better served by &lt;code&gt;Cell&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt;, and &lt;code&gt;Mutex&lt;/code&gt; instead. There are a few cases where you might want to avoid the overhead of those types by &lt;code&gt;UnsafeCell&lt;/code&gt; directly, such as implementing new locks and concurrent data structures, but those aren’t common tasks unless you work in academia. 😉&lt;/p&gt;
&lt;p&gt;Whew! This concludes the series on interior mutability. I hope you enjoyed it! Special thanks to everyone who has commented on both this and the previous articles. Your support and corrections are deeply appreciated. 💜&lt;/p&gt;
&lt;p&gt;What should we explore next? Tell me on Twitter (&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/meqif&quot;&gt;@meqif&lt;/a&gt;) or send me an email (&lt;a href=&quot;mailto:words@ricardomartins.cc&quot;&gt;words@ricardomartins.cc&lt;/a&gt;). You can also discuss the article on &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4sbax3/interior_mutability_in_rust_part_3_behind_the/&quot;&gt;reddit&lt;/a&gt;. If you don’t want to miss the next articles, sign up for my newsletter in the form below. 👇&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Many other types depend on &lt;code&gt;UnsafeCell&lt;/code&gt;, such as &lt;code&gt;Condvar&lt;/code&gt;, the &lt;code&gt;Sender&lt;/code&gt; and &lt;code&gt;Receiver&lt;/code&gt; structures used created by &lt;code&gt;std::sync::mpsc::channel&lt;/code&gt;, thread-local variables (created with the &lt;code&gt;thread_local&lt;/code&gt; macro), private data structures used in the compiler implementation, and some others I won’t bother to list. &lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Compare the result when running &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=dce59aa6a210a9c5010b921b1579559b&amp;amp;version=stable&amp;amp;backtrace=0&quot;&gt;this example&lt;/a&gt; in debug mode and release mode. In release mode the compiler assumed that the value is never changed, so the call to &lt;code&gt;println!&lt;/code&gt; doesn’t show the update! Thanks to &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4sbax3/interior_mutability_in_rust_part_3_behind_the/d5864zn&quot;&gt;/u/derKha&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4sbax3/interior_mutability_in_rust_part_3_behind_the/d588nt5&quot;&gt;/u/notriddle&lt;/a&gt; for their examples. &lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;That inner lock is actually a native OS lock. You can read the implementation for the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sys/unix/rwlock.rs&quot;&gt;Unix one&lt;/a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/blob/1.10.0/src/libstd/sys/windows/rwlock.rs&quot;&gt;Windows one&lt;/a&gt;. Both rely on &lt;code&gt;UnsafeCell&lt;/code&gt; as well. &lt;a href=&quot;https://ricardomartins.dev/2016/07/11/interior-mutability-behind-the-curtain/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Interior mutability in Rust, part 2: thread safety</title>
    <published>2016-06-25T00:00:00-05:00</published>
    
    <updated>2016-06-25T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety"/>
    
    <id>http://ricardomartins.cc/2016/06/25/interior-mutability-thread-safety</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety">&lt;div class=&quot;summary&quot;&gt;
  &lt;h1 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;We can have thread-safe interior mutability through &lt;code&gt;Mutex&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; and the various &lt;code&gt;Atomic*&lt;/code&gt; types in &lt;code&gt;std::sync&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Mutex&lt;/code&gt; allows only one thread at a time, has no direct thread-unsafe counterpart, but can be thought of as only giving &lt;code&gt;&amp;amp;mut T&lt;/code&gt; references&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RwLock&lt;/code&gt; is equivalent to &lt;code&gt;RefCell&lt;/code&gt;, and also allows multiple readers or one writer&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Atomic&lt;/code&gt; types are equivalent to &lt;code&gt;Cell&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::sync::Arc&lt;/code&gt; is the thread-safe version of &lt;code&gt;std::rc::Rc&lt;/code&gt;, necessary to share references among threads&lt;/li&gt;
&lt;li&gt;These thread-safe types have additional run-time cost compared to their unsynchronized counterparts&lt;/li&gt;
&lt;li&gt;In Rust, we lock/protect data, not code&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;This article is part of a series about interior mutability in Rust. You can read &lt;a href=&quot;/2016/06/08/interior-mutability&quot;&gt;part 1 here&lt;/a&gt; and &lt;a href=&quot;/2016/07/11/interior-mutability-behind-the-curtain&quot;&gt;part 3 here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In the &lt;a href=&quot;/2016/06/08/interior-mutability&quot;&gt;previous article&lt;/a&gt;, we looked into &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/cell/struct.Cell.html&quot;&gt;&lt;code&gt;Cell&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/cell/struct.RefCell.html&quot;&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/a&gt; as a way to achieve interior mutability—the ability to mutate particular fields in a structure regardless of its exterior (explicit or declared) mutability.&lt;/p&gt;
&lt;p&gt;However, neither &lt;code&gt;Cell&lt;/code&gt; nor &lt;code&gt;RefCell&lt;/code&gt; are appropriate to share data among threads. Since &lt;code&gt;Cell&lt;/code&gt; has no borrow checking mechanisms and its operations aren’t &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Linearizability&quot;&gt;atomic&lt;/a&gt;, it’s possible to have &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Race_condition#Software&quot;&gt;race conditions&lt;/a&gt; where we read outdated values and lose updates. &lt;code&gt;RefCell&lt;/code&gt;, on the other hand, has run-time borrow checking, but will panic when there are conflicting borrows, such as borrowing a mutably borrowed value. Additionally, &lt;code&gt;RefCell&lt;/code&gt; uses a &lt;code&gt;Cell&lt;/code&gt; to keep track of the borrow state. This means that even if you were careful and checked it before borrowing, you would risk mutably borrowing the value in multiple threads simultaneously, because its run-time borrow checks aren’t atomic either.&lt;/p&gt;
&lt;p&gt;Because of those issues, both &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; are marked &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/marker/trait.Sync.html&quot;&gt;&lt;code&gt;!Sync&lt;/code&gt;&lt;/a&gt;, which means they’re unsafe to be used in more than one thread.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Additionally, we need to share references to the cell among threads, but the reference counter type we explored previously, &lt;code&gt;Rc&lt;/code&gt;, is also not appropriate to be used in this scenario. The reference counter fields inside &lt;code&gt;Rc&lt;/code&gt; are wrapped by &lt;code&gt;Cell&lt;/code&gt;, so they would get erroneous values in a threaded program sooner or later. The presence of &lt;code&gt;!Sync&lt;/code&gt; fields is “infectious”. Since &lt;code&gt;Rc&lt;/code&gt; contains two &lt;code&gt;Cell&lt;/code&gt; fields, their &lt;code&gt;!Sync&lt;/code&gt; markers propagate to the entire &lt;code&gt;Rc&lt;/code&gt; structure. &lt;code&gt;Rc&lt;/code&gt; is also marked &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/marker/trait.Send.html&quot;&gt;&lt;code&gt;!Send&lt;/code&gt;&lt;/a&gt; — unsafe to send (move) to other threads. Likewise, &lt;code&gt;!Send&lt;/code&gt; is just as “infectious” as &lt;code&gt;!Sync&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We could implement both traits ourselves in our types, but since those traits are rather important, they’re marked as unsafe. So, we need to tell the Rust compiler we know what we’re doing by prefixing their &lt;code&gt;impl&lt;/code&gt; declarations with the &lt;code&gt;unsafe&lt;/code&gt; keyword. For instance, if we wanted to make the nodes in the &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ccf40fae2347519fcae7dd42ddf5ed6&quot;&gt;example&lt;/a&gt; of the previous article &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;unsafe impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Send&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;unsafe impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Sync&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This does make the compiler shut up and allows us to get on with it, but what does it mean?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; are automatically derived by the compiler for most types. If a type contains a &lt;code&gt;!Send&lt;/code&gt; or &lt;code&gt;!Sync&lt;/code&gt; field, the “taint” always spreads to the parent types. By explicitly implementing those traits, we’re implicitly telling the user of our API that our types are thread-safe (&lt;code&gt;Sync&lt;/code&gt;) and that they can be moved between threads safely (&lt;code&gt;Send&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;When we say our types are &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; without actually introducing synchronization mechanisms, we’re disrespecting the “contracts” associated with those traits and misleading the user. They’d get run-time panics or bad results due to race conditions. Not a happy situation, at all.&lt;/p&gt;
&lt;h1 id=&quot;thread-safe-interior-mutability&quot;&gt;Thread-safe interior mutability&lt;/h1&gt;
&lt;p&gt;Fortunately, Rust gives us good tools to achieve interior mutability in a thread-safe way without much effort. More than that, it does so in such a way that the borrow checker will have our backs most of the time, so we can’t shoot ourselves in the feet.&lt;/p&gt;
&lt;p&gt;One of the really nice aspects about Rust is that once you get the hang of the borrow system, you can use the same reasoning with interior mutability in a single thread (&lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt;) and in concurrent programs.&lt;/p&gt;
&lt;h2 id=&quot;for-copy-values&quot;&gt;For &lt;code&gt;Copy&lt;/code&gt; values&lt;/h2&gt;
&lt;p&gt;For &lt;code&gt;Copy&lt;/code&gt; values (eg., integers), instead of &lt;code&gt;Cell&lt;/code&gt;, we have &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/atomic/index.html&quot;&gt;&lt;code&gt;Atomic&lt;/code&gt;&lt;/a&gt; types (&lt;code&gt;std::sync::atomic::*&lt;/code&gt;) that rely on assembly instructions to prevent data races:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html&quot;&gt;&lt;code&gt;AtomicBool&lt;/code&gt;&lt;/a&gt;, a boolean type,&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/atomic/struct.AtomicIsize.html&quot;&gt;&lt;code&gt;AtomicIsize&lt;/code&gt;&lt;/a&gt;, a signed integer type,&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html&quot;&gt;&lt;code&gt;AtomicUsize&lt;/code&gt;&lt;/a&gt;, an unsigned integer type, and&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html&quot;&gt;&lt;code&gt;AtomicPtr&lt;/code&gt;&lt;/a&gt;, a raw pointer type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even though there are only four types, you can can build on &lt;code&gt;AtomicPtr&lt;/code&gt; to implement additional ones. Alternatively, you can use crates, such as the &lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/atom/&quot;&gt;&lt;code&gt;atom&lt;/code&gt; crate&lt;/a&gt;, to do so with a simple API. Quick disclaimer: I haven’t tried &lt;code&gt;atom&lt;/code&gt; but the example in &lt;a rel=&quot;external&quot; href=&quot;https://github.com/slide-rs/atom/blob/master/readme.md&quot;&gt;its README&lt;/a&gt; looks nice, and a quick glance at the source code looks exactly like what I would expect.&lt;/p&gt;
&lt;p&gt;Using an atomic type is a bit more involved than doing the same with a &lt;code&gt;Cell&lt;/code&gt;. Taking again the naive reference counter example of the previous article, using an &lt;code&gt;AtomicUsize&lt;/code&gt; we’d have:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;atomic&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;AtomicUsize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ordering&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reference_count&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; AtomicUsize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; clone&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;reference_count&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;fetch_add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Ordering&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Relaxed&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, instead of simply assigning a new value to &lt;code&gt;reference_count&lt;/code&gt;, we called &lt;code&gt;fetch_add&lt;/code&gt; to atomically increment it. The first parameter is the increment size, while the second is new. An &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/struct.RwLock.html&quot;&gt;&lt;code&gt;Ordering&lt;/code&gt;&lt;/a&gt; tells the compiler (and the CPU) how much freedom it has to reorder instructions. I won’t delve into that, as the official documentation explains it in sufficient detail.&lt;/p&gt;
&lt;h2 id=&quot;for-non-copy-values&quot;&gt;For non-Copy values&lt;/h2&gt;
&lt;p&gt;For non-copy values, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/struct.RwLock.html&quot;&gt;&lt;code&gt;std::sync::RwLock&lt;/code&gt;&lt;/a&gt; is the counterpart to &lt;code&gt;RefCell&lt;/code&gt;. Like &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; has semantics very similar to our old friend the borrow system, and allows either several “readers” or one “writer”, but not both at the same time, nor several “writers”.&lt;/p&gt;
&lt;p&gt;Unlike &lt;code&gt;RefCell&lt;/code&gt;, however, &lt;code&gt;RwLock&lt;/code&gt; doesn’t panic when there are incompatible borrows: if a thread needs a mutable reference, it will just have to wait until the other threads release the lock (i.e., stop using the borrowed values).&lt;/p&gt;
&lt;p&gt;We can get shared, read-only references with &lt;code&gt;read&lt;/code&gt; (equivalent to &lt;code&gt;borrow&lt;/code&gt; in &lt;code&gt;RefCell&lt;/code&gt;), or exclusive, mutable references with &lt;code&gt;write&lt;/code&gt; (&lt;code&gt;borrow_mut&lt;/code&gt;, respectively).&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Converting the &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ccf40fae2347519fcae7dd42ddf5ed6&quot;&gt;graph example&lt;/a&gt; in the previous article to use &lt;code&gt;RwLock&lt;/code&gt; instead of &lt;code&gt;RefCell&lt;/code&gt; is straightforward: replace &lt;code&gt;RefCell&lt;/code&gt; declarations with &lt;code&gt;RwLock&lt;/code&gt;, change &lt;code&gt;borrow&lt;/code&gt; to &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;borrow_mut&lt;/code&gt; to &lt;code&gt;write&lt;/code&gt;. We also need to replace &lt;code&gt;Rc&lt;/code&gt; with &lt;code&gt;Arc&lt;/code&gt; to be able to move references to other threads, but I’ll describe that later.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;thread;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Arc&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; RwLock&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Represents a reference to a node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// This makes the code less repetitive to write and easier to read.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Arc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RwLock&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;_Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The private representation of a node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The public representation of a node, with some syntactic sugar.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Creates a new node with no edges.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; new&lt;/span&gt;&lt;span&gt;(inner&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _Node&lt;/span&gt;&lt;span&gt; { inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; inner, adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;[] };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        Node&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RwLock&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(node)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Adds a directed edge from this node to other node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;, other&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;write&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;Failed to acquire a write lock on node&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            .&lt;/span&gt;&lt;span&gt;adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;push&lt;/span&gt;&lt;span&gt;(other&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Graph&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Graph&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; with_nodes&lt;/span&gt;&lt;span&gt;(nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        Graph&lt;/span&gt;&lt;span&gt; { nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; nodes }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Create some nodes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_3&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Connect some of the nodes (with directed edges)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_2);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_3);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_3&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Add nodes to graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Arc&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;with_nodes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;vec!&lt;/span&gt;&lt;span&gt;[node_1, node_2, node_3]));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Spawn a new thread that will print information about every node in the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // graph.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // The new scope makes this block more obviously different from the code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // surrounding it and lets us group variables that will be moved into the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // new thread, such as &amp;quot;graph&amp;quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; guard&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;Failed to acquire a read lock&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        thread&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;spawn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;move ||&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            for&lt;/span&gt;&lt;span&gt; _&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;10&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;                // Show every node in the graph and list their neighbors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                for&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in &amp;amp;&lt;/span&gt;&lt;span&gt;graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;nodes {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                    let&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;read&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;message);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                    let&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                    let&lt;/span&gt;&lt;span&gt; neighbours&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;adjacent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                        .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                        .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;read&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;message)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;                        .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;_&amp;gt;&amp;gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;                    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;node ({}) is connected to: {:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, value, neighbours);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;                println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;-------------&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;                // Give the main thread a chance to run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;                thread&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;yield_now&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    for&lt;/span&gt;&lt;span&gt; _&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;10&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        // Update the value of every node in the graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        for&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in &amp;amp;&lt;/span&gt;&lt;span&gt;graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;nodes {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            let mut&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;write&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;Failed to acquire a write lock&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        // Give the other thread a chance to run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        thread&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;yield_now&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Wait for the other thread to end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guard&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;join&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;Error joining thread&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can view the differences between the single- and multi-threaded versions in this &lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/meqif/bd8a85654b230e8ecd1d3344fc707de9/revisions&quot;&gt;gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Apart from creating a new thread that prints the graph’s information and a new loop in the main thread that updates the node’s values, the only important differences are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Arc&amp;lt;RwLock&amp;lt;_&amp;gt;&amp;gt;&lt;/code&gt; instead of &lt;code&gt;Rc&amp;lt;RefCell&amp;lt;_&amp;gt;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Every call to &lt;code&gt;borrow&lt;/code&gt; and &lt;code&gt;borrow_mut&lt;/code&gt; was replaced with &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt;, respectively.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I encourage you to make these changes yourself starting from the &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ccf40fae2347519fcae7dd42ddf5ed6&quot;&gt;previous article’s code&lt;/a&gt;. Making small, incremental changes and compiling the intermediate versions usually helps me get an intuitive feel for how the API works.&lt;/p&gt;
&lt;p&gt;Note that, unlike &lt;code&gt;borrow&lt;/code&gt; and &lt;code&gt;borrow_mut&lt;/code&gt;, &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; return a &lt;code&gt;LockResult&lt;/code&gt;, which is a type alias for &lt;code&gt;Result&amp;lt;Guard, PoisonError&amp;lt;Guard&amp;gt;&amp;gt;&lt;/code&gt;, and requires us to &lt;code&gt;match&lt;/code&gt;, &lt;code&gt;unwrap&lt;/code&gt; or &lt;code&gt;expect&lt;/code&gt; it. The &lt;code&gt;Guard&lt;/code&gt; is automatically coerced into a reference, so we can pretty much ignore it.&lt;/p&gt;
&lt;p&gt;In my experience, you rarely need to deal with the error case for either &lt;code&gt;read&lt;/code&gt; or &lt;code&gt;write&lt;/code&gt;, as it only happens if another thread with a mutable reference (i.e., a successful &lt;code&gt;write&lt;/code&gt;) panics. In that case, you have a more serious bug elsewhere that you need to take care of.&lt;/p&gt;
&lt;p&gt;Both &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; will block the thread until it gets the requested lock. Since you may not want to wait indefinitely, you can also call &lt;code&gt;try_read&lt;/code&gt; and &lt;code&gt;try_write&lt;/code&gt; instead, which won’t block and return an error if they couldn’t get a lock.&lt;/p&gt;
&lt;p&gt;Besides &lt;code&gt;RwLock&lt;/code&gt;, there is also &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/struct.Mutex.html&quot;&gt;&lt;code&gt;std::sync::Mutex&lt;/code&gt;&lt;/a&gt;, whose name comes from “mutual exclusion”, because it guarantees mutually exclusive access to the wrapped value, i.e., only one thread can access it at a time. Because of this, it’s always safe to mutate the value once you get access to it.&lt;/p&gt;
&lt;p&gt;We can look at &lt;code&gt;Mutex&lt;/code&gt; as if it were an &lt;code&gt;RwLock&lt;/code&gt; without &lt;code&gt;read&lt;/code&gt;, only able to give the caller mutable references. In this sense, it’s more constraining than the regular borrow system or an &lt;code&gt;RwLock&lt;/code&gt;, which allow either multiple simultaneous readers (with immutable references) or only one writer (a mutable reference) at a time. Even if we want an innocent immutable reference, we must get full permission to the inner value.&lt;/p&gt;
&lt;p&gt;As there is only one kind of borrow for &lt;code&gt;Mutex&lt;/code&gt; values, &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; are replaced by a single &lt;code&gt;lock&lt;/code&gt; method, which will block the thread until the current lock owner releases it (i.e., the other borrow ends). Like with &lt;code&gt;RwLock&lt;/code&gt;, if you don’t want to block the thread when the value isn’t available, you can call &lt;code&gt;try_lock&lt;/code&gt; instead, which will either give you the lock/mutable reference or an error (&lt;code&gt;Err&lt;/code&gt;).&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;reference-counting&quot;&gt;Reference counting&lt;/h2&gt;
&lt;p&gt;As I mentioned earlier, &lt;code&gt;std::rc::Rc&lt;/code&gt; lacks synchronization control, which makes it unsafe to be used by multiple threads. Its thread-safe counterpart is &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/struct.Arc.html&quot;&gt;&lt;code&gt;Arc&lt;/code&gt;&lt;/a&gt;, which lives in &lt;code&gt;std::sync&lt;/code&gt;, along with &lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Arc&lt;/code&gt; is very similar to &lt;code&gt;Rc&lt;/code&gt; but relies on &lt;code&gt;AtomicUsize&lt;/code&gt; for the reference counter, which makes it safe to be updated by more than one thread, unlike &lt;code&gt;Rc&lt;/code&gt;, which uses &lt;code&gt;Cell&amp;lt;usize&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Rc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ptr&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Shared&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RcBox&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; RcBox&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strong&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    weak&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;pub struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Arc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ptr&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Shared&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;ArcInner&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; ArcInner&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: ?&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strong&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; atomic&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;AtomicUsize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    weak&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; atomic&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;AtomicUsize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Arc&lt;/code&gt;’s API is identical to &lt;code&gt;Rc&lt;/code&gt;’s, which makes replacing one with the other a simple matter of searching and replacing the name and correcting the import.&lt;/p&gt;
&lt;h1 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h1&gt;
&lt;p&gt;In the previous article, we learned that interior mutability in Rust can be achieved through &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; in single-threaded programs, supported by &lt;code&gt;Rc&lt;/code&gt; where necessary. In this article, we saw the same can be done in a safe way in concurrent programs with &lt;code&gt;Atomic&lt;/code&gt; types and &lt;code&gt;RwLock&lt;/code&gt;, with the help of &lt;code&gt;Arc&lt;/code&gt;.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;th&gt;Single thread&lt;/th&gt;&lt;th&gt;Multiple threads&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Copy value&lt;/td&gt;&lt;td&gt;&lt;code&gt;Cell&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Atomic*&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Non-Copy value&lt;/td&gt;&lt;td&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;RwLock&lt;/code&gt;, &lt;code&gt;Mutex&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Reference counter&lt;/td&gt;&lt;td&gt;&lt;code&gt;Rc&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Arc&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The table above summarizes the types to be used in single- and multi-threaded scenarios.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type of access&lt;/th&gt;&lt;th&gt;Borrow checker&lt;/th&gt;&lt;th&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;RwLock&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;Mutex&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;shared / read-only&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;borrow&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;read&lt;/code&gt;&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;exclusive / writable&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;mut T&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;borrow_mut&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;write&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;lock&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;This second table highlights the similarities between the borrow checker, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; and, to a lesser degree, &lt;code&gt;Mutex&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You could ask, “Why bother opting for &lt;code&gt;RefCell&lt;/code&gt; and &lt;code&gt;Rc&lt;/code&gt; if &lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt; have identical semantics and very similar APIs?”&lt;/p&gt;
&lt;p&gt;Unfortunately, the types we explored in this article (&lt;code&gt;Atomic&lt;/code&gt; types, &lt;code&gt;RwLock&lt;/code&gt;, &lt;code&gt;Mutex&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt;) depend on synchronization primitives with higher run-time overhead than their naive counterparts, and we’ll want to avoid them whenever possible.&lt;/p&gt;
&lt;p&gt;We can have a regular &lt;code&gt;Rc&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; combination for variables that aren’t shared with other threads, and their synchronized versions for the bits you want to parallelize. Because the API and semantics are similar in both cases, we will have little cognitive overhead using both.&lt;/p&gt;
&lt;p&gt;Another important point we must also pay attention to, is the semantics of the wrapping. For instance, &lt;code&gt;Arc&amp;lt;Vec&amp;lt;RwLock&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; is different from &lt;code&gt;Arc&amp;lt;RwLock&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;. With the first, we can’t concurrently mutate the vector itself, but we can mutate its stored values. This is a consequence of &lt;code&gt;Arc&lt;/code&gt; implementing &lt;code&gt;Deref&lt;/code&gt; but not &lt;code&gt;DerefMut&lt;/code&gt;, meaning we can only get immutable references to the vector (which contains lockable elements). With the second form, we get an immutable reference to &lt;code&gt;RwLock&lt;/code&gt;, but since it can give us both kinds of references through &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt;, we can mutate the vector, adding or removing elements. However, we lose the ability to concurrently mutate the values: once a thread gets a mutable reference to the vector, the others will have to wait, while the first form allows us to have one thread mutating each element in parallel.&lt;/p&gt;
&lt;p&gt;In short, &lt;code&gt;Arc&amp;lt;Vec&amp;lt;RwLock&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; allows us to mutate all elements of the vector in parallel if we wish to do so, while &lt;code&gt;Arc&amp;lt;RwLock&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; allows only one thread to modify the vector (and its values), leaving other threads waiting for the lock.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;T&lt;/code&gt; is itself wrapped by &lt;code&gt;Arc&lt;/code&gt;, we would be unable to mutate the stored values at all (because &lt;code&gt;Arc&lt;/code&gt; coerces only to immutable references). We would need a monstrosity like &lt;code&gt;Arc&amp;lt;RwLock&amp;lt;Vec&amp;lt;Arc&amp;lt;RwLock&amp;lt;T&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; to be able to concurrently mutate both the vector and its elements, but we should take this a hint to rethink how you want to parallelize your code.&lt;/p&gt;
&lt;p&gt;Exploring interior mutability in a concurrent environment made me realize that Rust is different from other languages regarding locks. Whereas in other languages we use locks to protect code fragments, in Rust we use them to protect access to data.&lt;/p&gt;
&lt;p&gt;In addition, locks are so similar in use to Rust’s borrow mechanisms that they feel like a thread-safe generalization of those mechanisms. Personally, I find this way much easier to reason about than the classic, C way.&lt;/p&gt;
&lt;p&gt;Finally, I know it’s tempting, but don’t throw interior mutability everywhere just to make the borrow checker shut up. Consider carefully whether the situation really calls for interior mutability or a refactor of your data structures. This goes doubly so for concurrent programs, not only because &lt;code&gt;RwLock&lt;/code&gt;, &lt;code&gt;Mutex&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt; incur additional run-time costs, but also because synchronization is easy to mess up and leave you with race conditions. Fortunately, Rust’s borrow checker gives us precious guidance and makes them much less likely. Race conditions are nasty to debug, be especially careful about dropping your locks as soon as possible.&lt;/p&gt;
&lt;p&gt;That’s it. Now you know enough to effectively employ interior mutability in your programs, whether they are single- or multi-threaded. Well done! 🎉&lt;/p&gt;
&lt;p&gt;My thanks to &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4puabs/interior_mutability_in_rust_part_2_thread_safety/d4octag&quot;&gt;/u/Manishearth&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4puabs/interior_mutability_in_rust_part_2_thread_safety/d4o0cna&quot;&gt;/u/Steel_Neuron&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4puabs/interior_mutability_in_rust_part_2_thread_safety/d4pgcxy&quot;&gt;/u/diwic&lt;/a&gt; for their feedback.&lt;/p&gt;
&lt;p&gt;I hope you found this article useful and/or interesting. As always, if you found a mistake or have any questions, please ping me on Twitter (&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/meqif&quot;&gt;@meqif&lt;/a&gt;) or send me an email (&lt;a href=&quot;mailto:words@ricardomartins.cc&quot;&gt;words@ricardomartins.cc&lt;/a&gt;). You can also join the discussion on &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4puabs/interior_mutability_in_rust_part_2_thread_safety/&quot;&gt;reddit&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;We can implement a marker trait or its negation for a type. Currently this only works with marker traits, such as &lt;code&gt;Sync&lt;/code&gt; and &lt;code&gt;Send&lt;/code&gt;, which don’t have associated methods but provide useful type information. There is work being done toward generalizing this feature, called negative traits, to any trait (&lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/rust/issues/13231&quot;&gt;rust-lang/rust #13231&lt;/a&gt;). &lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Actually, &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; will return &lt;code&gt;Result&amp;lt;RwLockReadGuard&amp;gt;&lt;/code&gt; or &lt;code&gt;Result&amp;lt;RwLockWriteGuard&amp;gt;&lt;/code&gt;, respectively. &lt;code&gt;RwLockReadGuard&lt;/code&gt; implements &lt;code&gt;Deref&lt;/code&gt;, and &lt;code&gt;RwLockWriteGuard&lt;/code&gt; implements both &lt;code&gt;Deref&lt;/code&gt; and &lt;code&gt;DerefMut&lt;/code&gt;, which are transparently coerced into mutable (&lt;code&gt;&amp;amp;T&lt;/code&gt;) and immutable (&lt;code&gt;&amp;amp;mut T&lt;/code&gt;) references, respectively. &lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Similarly to &lt;code&gt;RwLock&lt;/code&gt;, calling &lt;code&gt;lock&lt;/code&gt; on a &lt;code&gt;Mutex&lt;/code&gt; will return a &lt;code&gt;Result&amp;lt;MutexGuard&amp;gt;&lt;/code&gt;, which implements both &lt;code&gt;Deref&lt;/code&gt; and &lt;code&gt;DerefMut&lt;/code&gt;, and can be coerced into &lt;code&gt;&amp;amp;T&lt;/code&gt; or &lt;code&gt;&amp;amp;mut T&lt;/code&gt;, respectively. &lt;a href=&quot;https://ricardomartins.dev/2016/06/25/interior-mutability-thread-safety/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Interior mutability in Rust: what, why, how?</title>
    <published>2016-06-08T00:00:00-05:00</published>
    
    <updated>2016-06-08T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2016/06/08/interior-mutability"/>
    
    <id>http://ricardomartins.cc/2016/06/08/interior-mutability</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2016/06/08/interior-mutability">&lt;blockquote&gt;
&lt;p&gt;Rust is like doing parkour while suspended on strings &amp;amp; wearing protective gear. Yes, it will sometimes look a little ridiculous, but you’ll be able to do all sorts of cool moves without hurting yourself. – &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4l44z3/why_should_i_use_rust/d3k7ayi&quot;&gt;llogiq on reddit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;summary&quot;&gt;
  &lt;h1 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Interior mutability is when you have an immutable reference (&lt;code&gt;&amp;amp;T&lt;/code&gt;) but you can mutate the destination&lt;/li&gt;
&lt;li&gt;It’s useful when you need mutable fields inside immutable data structures&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::cell::Cell&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;std::cell::RefCell&amp;lt;T&amp;gt;&lt;/code&gt; can be used to achieve interior mutability&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Cell&lt;/code&gt; wraps &lt;code&gt;Copy&lt;/code&gt; values and doesn’t have borrow checking&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RefCell&lt;/code&gt; wraps any kind of value, has run-time borrow checking, and requires “locking” with &lt;code&gt;borrow&lt;/code&gt; or &lt;code&gt;borrow_mut&lt;/code&gt;, which give you an immutable or mutable reference, respectively&lt;/li&gt;
&lt;li&gt;Neither are safe to be directly used in a multi-threaded environment. Use &lt;code&gt;Mutex&lt;/code&gt; or &lt;code&gt;RwLock&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;This article is part of a series about interior mutability in Rust. You can read &lt;a href=&quot;/2016/06/25/interior-mutability-thread-safety&quot;&gt;part 2 here&lt;/a&gt; and &lt;a href=&quot;/2016/07/11/interior-mutability-behind-the-curtain&quot;&gt;part 3 here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Sometimes data structures need to mutate one or more of their fields even when they are declared immutable. This may sound surprising at first, but you’ve probably relied on this behavior before, like when you clone a reference counted wrapper such as &lt;code&gt;Rc&lt;/code&gt;, or when you lock a &lt;code&gt;Mutex&lt;/code&gt;. However, in Rust, mutability is an all-or-nothing attribute: either a variable is declared as mutable and all of its fields are also mutable (if it is a &lt;code&gt;struct&lt;/code&gt;), or it’s declared immutable and so are all of its fields. How do we get selective field mutability? Something mysterious is afoot.&lt;/p&gt;
&lt;p&gt;Have you ever wondered how &lt;code&gt;Rc&lt;/code&gt; is implemented? Let’s have a try! A naive first solution would be something like the following:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reference_count&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; clone&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;reference_count &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You probably spotted the problem right away: &lt;code&gt;clone&lt;/code&gt; takes a read-only reference to &lt;code&gt;self&lt;/code&gt;, so the reference count can’t be updated! Dang it.&lt;/p&gt;
&lt;p&gt;We could implement a special, differently-named cloning function that takes &lt;code&gt;&amp;amp;mut self&lt;/code&gt;, but that is awful for usability (because it defies the convention of simply checking if a type implements &lt;code&gt;Clone&lt;/code&gt;), and forces the user of our API to always declare mutable instances of that type. We also know that the reference counted wrappers in the standard library (&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/rc/struct.Rc.html&quot;&gt;&lt;code&gt;std::rc::Rc&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/sync/struct.Arc.html&quot;&gt;&lt;code&gt;std::sync::Arc&lt;/code&gt;&lt;/a&gt;) don’t rely on that solution, which suggests there’s another way.&lt;/p&gt;
&lt;p&gt;So, how did they solve this problem in &lt;code&gt;Rc&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt;? Does the standard library rely on some sort of specially nasty magic? Not at all!&lt;/p&gt;
&lt;p&gt;This is an instance of &lt;strong&gt;interior mutability&lt;/strong&gt;, and the Rust language provides you with tools to easily and cleanly solve this sort of situation.&lt;/p&gt;
&lt;h1 id=&quot;what&quot;&gt;What?&lt;/h1&gt;
&lt;p&gt;Interior mutability is a concept that many programmers new to Rust have never come across before or haven’t had to explicitly think about. It’s also more visible in Rust than in most other programming languages because we have to think about the mutability or not of variables and function arguments. This is even more evident when we look at immutable vs. mutable as shared vs. exclusive access to objects. The unspoken heuristic is that avoiding mutability when possible is good.&lt;/p&gt;
&lt;p&gt;And yet, in some cases you need a few mutable fields in data structures, whether they’re mutable or not. Interior mutability gives you that additional flexibility and allows you to hide implementation details from the user of your API, while preserving (some measure of) access safety.&lt;/p&gt;
&lt;p&gt;To explain what interior mutability is, it’s better to step back a little and start with something you’re familiar about: exterior mutability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exterior mutability&lt;/strong&gt; is the sort of mutability you get from mutable references (&lt;code&gt;&amp;amp;mut T&lt;/code&gt;). The type of declaration, &lt;code&gt;&amp;amp;T&lt;/code&gt; or &lt;code&gt;&amp;amp;mut T&lt;/code&gt;, makes it clear if you’re free to update a variable or call mutating methods on objects. Exterior mutability is checked and enforced at compile-time, as you know:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Foo&lt;/span&gt;&lt;span&gt; { x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; u32&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Foo&lt;/span&gt;&lt;span&gt; { x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The borrow checker will complain about this and abort compilation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let mut&lt;/span&gt;&lt;span&gt; bar&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Foo&lt;/span&gt;&lt;span&gt; { x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// &amp;#39;bar&amp;#39; is mutable, so you can change the content of any of its fields&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bar&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you have an immutable reference, you can’t change the value. Conversely, because there is no field-level mutability in Rust, if you want to mutate a single field, you need to make the entire structure mutable, and that’s it. Or is it? Not so fast.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interior mutability&lt;/strong&gt;, in contrast, is when you have an immutable reference (i.e., &lt;code&gt;&amp;amp;T&lt;/code&gt;) but you can mutate the data structure. As I mentioned before, that’s what happens when you clone an &lt;code&gt;Rc&lt;/code&gt; or lock a &lt;code&gt;Mutex&lt;/code&gt; (both &lt;code&gt;Mutex::lock&lt;/code&gt; and &lt;code&gt;Mutex::try_lock&lt;/code&gt; work in immutable instances).&lt;/p&gt;
&lt;p&gt;A simple example will make the difference clearer. Suppose we have a simple structure like the following:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Point&lt;/span&gt;&lt;span&gt; { x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; i32&lt;/span&gt;&lt;span&gt;, y&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; i32&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An immutable &lt;code&gt;Point&lt;/code&gt; can be seen as an immutable memory chunk, whose fields (sections of the memory chunk) can’t have their content changed at all. When you declare an immutable &lt;code&gt;Point&lt;/code&gt; your hands are tied.&lt;/p&gt;
&lt;p&gt;Consider now a slightly different, magically-enhanced &lt;code&gt;MagicPoint&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; MagicPoint&lt;/span&gt;&lt;span&gt; { x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; i32&lt;/span&gt;&lt;span&gt;, y&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Magic&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;i32&lt;/span&gt;&lt;span&gt;&amp;gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;responsive-picture&quot;&gt;
  &lt;picture&gt;
    &lt;source media=&quot;(min-width: 600px)&quot; srcset=&quot;diagram.png 1x, diagram-hd.png 2x&quot;&gt;
    &lt;source srcset=&quot;diagram-small.png 1x, diagram-small-hd.png 2x&quot;&gt;
    &lt;img src=&quot;diagram.png&quot; alt=&quot;Representation of Point and MagicPoint&quot;&gt;
  &lt;/picture&gt;
&lt;/div&gt;
&lt;p&gt;For now, ignore how &lt;code&gt;Magic&lt;/code&gt; works, and think of it as a pointer to a mutable memory address, a new layer of indirection. Like previously, if you have an immutable &lt;code&gt;MagicPoint&lt;/code&gt;, you can’t assign new values to any of its fields. However, in this case you don’t need to change the content of &lt;code&gt;y&lt;/code&gt;, only the destination of that magical pointer, i.e., the other memory chunk, and that one &lt;em&gt;is&lt;/em&gt; mutable!&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/06/08/interior-mutability/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;To be clear, even though the API for &lt;code&gt;Magic&lt;/code&gt; will make it seem as if you’re relying on indirection to access and update the wrapped value, the memory representation of &lt;code&gt;MagicPoint&lt;/code&gt; will actually be flat.&lt;/p&gt;
&lt;p&gt;Note that when you rely on interior mutability, you are giving up the compile-time safety guarantees that exterior mutability gives you. As we’ll see next, it’s not that bad, provided you’re careful.&lt;/p&gt;
&lt;h1 id=&quot;how&quot;&gt;How?&lt;/h1&gt;
&lt;p&gt;So, how can we get magical mutable pointers? Fortunately for us, the Rust standard library provides two wrappers, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/cell/struct.Cell.html&quot;&gt;&lt;code&gt;std::cell::Cell&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/cell/struct.RefCell.html&quot;&gt;&lt;code&gt;std::cell::RefCell&lt;/code&gt;&lt;/a&gt;, that allow us to introduce interior mutability in externally immutable instances of data structures. With &lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; in our collective toolbelts, we can harness the power of interior mutability.&lt;/p&gt;
&lt;p&gt;Both wrappers provide interior mutability and give up compile-time borrow checking on the inner value, but give different safety guarantees and serve different purposes. The most obvious difference between them is that &lt;code&gt;RefCell&lt;/code&gt; makes run-time borrow checks, while &lt;code&gt;Cell&lt;/code&gt; does not.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cell&lt;/code&gt; is quite simple to use: you can read and write a &lt;code&gt;Cell&lt;/code&gt;’s inner value by calling &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;set&lt;/code&gt; on it. Since there are no compile-time or run-time checks, you do have to be careful to avoid some bugs the borrow checker would stop you from writing, such as accidentally overwriting the wrapped value:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Cell&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; foo&lt;/span&gt;&lt;span&gt;(cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;u32&lt;/span&gt;&lt;span&gt;&amp;gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;set&lt;/span&gt;&lt;span&gt;(value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; new_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    foo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;cell);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;set&lt;/span&gt;&lt;span&gt;(new_value);&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // oops, we clobbered the work done by foo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In contrast, a &lt;code&gt;RefCell&lt;/code&gt; requires you to call &lt;code&gt;borrow&lt;/code&gt; or &lt;code&gt;borrow_mut&lt;/code&gt; (immutable and mutable borrows) before using it, yielding a pointer to the value. Its borrow semantics are identical to externally mutable variables: you can have either a mutable borrow on the inner value or several immutable borrows, so the kind of bug I mentioned earlier is detected in run-time.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Cell&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; new&lt;/span&gt;&lt;span&gt;(inner&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        NaiveRc&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; inner,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; references&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; usize&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Clone&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; clone&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        NaiveRc&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; wrapped&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;references before cloning: {:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, wrapped&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;references&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; wrapped_clone&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; wrapped&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;references after cloning: {:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, wrapped&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;references&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;clone references: {:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, wrapped_clone&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;references&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Calling &lt;code&gt;borrow&lt;/code&gt; or &lt;code&gt;borrow_mut&lt;/code&gt; on a mutably borrowed &lt;code&gt;RefCell&lt;/code&gt; will cause a panic, as will calling &lt;code&gt;borrow_mut&lt;/code&gt; on a immutably borrowed value. This aspect makes &lt;code&gt;RefCell&lt;/code&gt; unsuitable to be used in a parallel scenario; you should use a thread-safe type (like a &lt;code&gt;Mutex&lt;/code&gt; or a &lt;code&gt;RwLock&lt;/code&gt;, for example) instead.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;RefCell&lt;/code&gt; will stay “locked” until the pointer you received falls out of scope, so you might want to declare a new block scope (ie., &lt;code&gt;{ ... }&lt;/code&gt;) while working with the borrowed value, or even explicitly &lt;code&gt;drop&lt;/code&gt; the borrowed value when you’re done with it, to avoid unpleasant surprises.&lt;/p&gt;
&lt;p&gt;Another significant difference between &lt;code&gt;Cell&lt;/code&gt; and &lt;code&gt;RefCell&lt;/code&gt; is that &lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt; requires that the inner value &lt;code&gt;T&lt;/code&gt; implements &lt;code&gt;Copy&lt;/code&gt;, while &lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; has no such restriction. Often, you won’t want copy semantics on your wrapped types, so you’ll have to use &lt;code&gt;RefCell&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Put succinctly, &lt;code&gt;Cell&lt;/code&gt; has &lt;code&gt;Copy&lt;/code&gt; semantics and provides &lt;em&gt;values&lt;/em&gt;, while &lt;code&gt;RefCell&lt;/code&gt; has &lt;code&gt;move&lt;/code&gt; semantics and provides &lt;em&gt;references&lt;/em&gt;.&lt;/p&gt;
&lt;h1 id=&quot;why&quot;&gt;Why?&lt;/h1&gt;
&lt;p&gt;There are a few general cases that call for interior mutability, such as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Introducing mutability inside of something immutable&lt;/li&gt;
&lt;li&gt;Mutating implementations of &lt;code&gt;Clone&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Implementation details of logically immutable methods&lt;/li&gt;
&lt;li&gt;Mutating reference-counted variables&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;introducing-mutability-inside-of-something-immutable&quot;&gt;Introducing mutability inside of something immutable&lt;/h2&gt;
&lt;p&gt;Returning to the &lt;code&gt;NaiveRc&lt;/code&gt; example in the introduction, reference-counting pointers, like &lt;code&gt;Rc&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt;, need internal mutability. When you clone those pointers, the reference counter inside them has to be updated, whether they’re mutable or not. Without interior mutability, you would be forced to always use mutable pointers, which would allow mutation of the inner value and may be undesired.&lt;/p&gt;
&lt;p&gt;For instance, consider the following naive reference counted wrapper:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Cell&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;a T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;let&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NaiveRc&lt;/span&gt;&lt;span&gt; { inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;, references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;) };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; // it works!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;= &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;  // beep boop, x is immutable,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;                     // you can&amp;#39;t assign a new value to any of its fields!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;mutating-implementations-of-clone&quot;&gt;Mutating implementations of &lt;code&gt;Clone&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Way back in the introduction, we noticed that cloning a reference-counted value (&lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;) needs to increment the reference counter. This is simply a special case of the previous point, but it deserves reiterating.&lt;/p&gt;
&lt;p&gt;On the other hand, dropping such a value requires decrementing the reference counter, but &lt;code&gt;drop&lt;/code&gt; works with mutable references (&lt;code&gt;fn drop(&amp;amp;mut self)&lt;/code&gt;), so there’s no problem there.&lt;/p&gt;
&lt;h2 id=&quot;implementation-details-of-logically-immutable-methods&quot;&gt;Implementation details of logically immutable methods&lt;/h2&gt;
&lt;p&gt;For instance, you might want to amortize the running time of an expensive algorithm operating on your data structure by using a cache inside it. The cache must be able to be updated even when the data structure itself is immutable.&lt;/p&gt;
&lt;h2 id=&quot;mutating-reference-counted-variables&quot;&gt;Mutating reference-counted variables&lt;/h2&gt;
&lt;p&gt;Suppose we need multiple references to some objects. For example, when connecting nodes in a graph. “&lt;em&gt;Oh, that’s easy&lt;/em&gt;”, you think. “&lt;em&gt;I’ll just wrap my nodes in &lt;code&gt;Rc&lt;/code&gt; or &lt;code&gt;Arc&lt;/code&gt; and call it a day&lt;/em&gt;”. That a perfectly reasonable line of though, and it would work… if you never, ever needed to mutate nodes. Once you try building the graph by incrementally adding and connecting nodes, the compiler will give you grief. Oh no, what is going on? Unfortunately for us, &lt;code&gt;Rc&lt;/code&gt; preserves safety by only giving you shared (i.e., immutable) references when you call &lt;code&gt;clone&lt;/code&gt;. Quoth the &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/stable/std/rc/&quot;&gt;&lt;code&gt;std::rc&lt;/code&gt; module documentation&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Rc&amp;lt;T&amp;gt; type provides shared ownership of an immutable value. Destruction is deterministic, and will occur as soon as the last owner is gone.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You could call &lt;code&gt;get_mut&lt;/code&gt; to receive an &lt;code&gt;Option&amp;lt;&amp;amp;mut T&amp;gt;&lt;/code&gt;, but that would work only once: &lt;code&gt;get_mut&lt;/code&gt; only returns a mutable reference as if there is only one “strong” reference to the value.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ricardomartins.dev/2016/06/08/interior-mutability/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; Foiled again!&lt;/p&gt;
&lt;p&gt;Fortunately, you can use interior mutability here: use &lt;code&gt;Rc&amp;lt;Cell&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; or &lt;code&gt;Rc&amp;lt;RefCell&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;. That way you can &lt;code&gt;clone&lt;/code&gt; the reference-counted wrapper as much as you want and still modify the innermost value wrapped by &lt;code&gt;Cell&lt;/code&gt; or &lt;code&gt;RefCell&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can see a first try at a solution &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=bd01037fd9b9bb3d1a15bde61f580c6f&quot;&gt;in this example in the Rust Playground&lt;/a&gt;. As you can see, the problem is solved, but the solution is verbose and ugly. Not only that, the user of our API is aware of implementation details! What gives? Where’s the elegant abstraction I promised a few paragraphs above?&lt;/p&gt;
&lt;p&gt;Now that you’ve seen and understood how this works, I can show you a cleaner version:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RefCell&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;rc&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Rc&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// A graph can be represented in several ways. For the sake of illustrating how&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// interior mutability works in practice, let&amp;#39;s go with the simplest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// representation: a list of nodes.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Each node has an inner value and a list of adjacent nodes it is connected to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// (through a directed edge).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// That list of adjacent nodes cannot be the exclusive owner of those nodes, or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// else each node would have at most one edge to another node and the graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// couldn&amp;#39;t also own these nodes.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// We need to wrap Node with a reference-counted box, such as Rc or Arc. We&amp;#39;ll&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// go with Rc, because this is a toy example.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// However, Rc&amp;lt;T&amp;gt; and Arc&amp;lt;T&amp;gt; enforce memory safety by only giving out shared&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// (i.e., immutable) references to the wrapped object, and we need mutability to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// be able to connect nodes together.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The solution for this problem is wrapping Node in either Cell or RefCell, to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// restore mutability. We&amp;#39;re going to use RefCell because Node&amp;lt;T&amp;gt; doesn&amp;#39;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// implement Copy (we don&amp;#39;t want to have independent copies of nodes!).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// Represents a reference to a node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// This makes the code less repetitive to write and easier to read.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Rc&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RefCell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;_Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The private representation of a node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;// The public representation of a node, with some syntactic sugar.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;NodeRef&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Creates a new node with no edges.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; new&lt;/span&gt;&lt;span&gt;(inner&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _Node&lt;/span&gt;&lt;span&gt; { inner_value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; inner, adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;[] };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        Node&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Rc&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;RefCell&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(node)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Adds a directed edge from this node to other node.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;, other&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;borrow_mut&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;push&lt;/span&gt;&lt;span&gt;(other&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clone&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Graph&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Graph&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; with_nodes&lt;/span&gt;&lt;span&gt;(nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        Graph&lt;/span&gt;&lt;span&gt; { nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; nodes }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Create some nodes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; node_3&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Connect some of the nodes (with directed edges)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_2);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_3);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    node_3&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_adjacent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;node_1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Add nodes to graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;with_nodes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;vec!&lt;/span&gt;&lt;span&gt;[node_1, node_2, node_3]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Show every node in the graph and list their neighbors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    for&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in&lt;/span&gt;&lt;span&gt; graph&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;nodes&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;borrow&lt;/span&gt;&lt;span&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        let&lt;/span&gt;&lt;span&gt; neighbours&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;adjacent&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;borrow&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner_value)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;            .&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;_&amp;gt;&amp;gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;node ({}) is connected to: {:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, value, neighbours);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you ignore the loop that prints out the graph’s information, now the user doesn’t know how a &lt;code&gt;Node&lt;/code&gt; is implemented. This version’s usability can still be improved by implementing the &lt;code&gt;std::fmt::Debug&lt;/code&gt; trait for &lt;code&gt;Node&lt;/code&gt; and &lt;code&gt;Graph&lt;/code&gt;, for instance.&lt;/p&gt;
&lt;p&gt;You can &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ccf40fae2347519fcae7dd42ddf5ed6&quot;&gt;play with this example&lt;/a&gt; in the Rust Playground. Try changing some things yourself! I find breaking things helps me consolidate new knowledge. I suggest:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Replacing &lt;code&gt;RefCell&lt;/code&gt; with &lt;code&gt;Cell&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Removing &lt;code&gt;RefCell&lt;/code&gt; and using &lt;code&gt;Rc&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Removing &lt;code&gt;Rc&lt;/code&gt; and using &lt;code&gt;RefCell&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You could also try replacing &lt;code&gt;Rc&lt;/code&gt; with &lt;code&gt;Arc&lt;/code&gt;, but you wouldn’t notice anything different. &lt;code&gt;Arc&lt;/code&gt; is a thread-safe version of &lt;code&gt;Rc&lt;/code&gt;, which comes with a performance cost and doesn’t really make sense in single-threaded programs.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ce1029d16433114f6bdda32b2e9fc03&quot;&gt;An alternative solution&lt;/a&gt; could involve wrapping the adjacent node vector in a &lt;code&gt;RefCell&lt;/code&gt; instead of wrapping the node itself. That can also work, depending on what you intend to do, but it is semantically different from the previous solution, as you would be unable to mutate a node’s inner value in addition to its list of adjacent nodes.&lt;/p&gt;
&lt;h1 id=&quot;which-to-pick&quot;&gt;Which to pick?&lt;/h1&gt;
&lt;p&gt;If &lt;code&gt;RefCell&lt;/code&gt; can explode in your face and shouldn’t be used “raw” in a multi-threaded program, why bother using it?&lt;/p&gt;
&lt;p&gt;While &lt;code&gt;Cell&lt;/code&gt; is a good choice for many cases, there are a few reasons you might want to use &lt;code&gt;RefCell&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The wrapped value doesn’t implement &lt;code&gt;Copy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Only &lt;code&gt;RefCell&lt;/code&gt; has run-time checks. In some scenarios you’d rather kill the program than risk corrupting data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RefCell&lt;/code&gt; exposes pointers to the stored value, &lt;code&gt;Cell&lt;/code&gt; doesn’t.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a rule of thumb, choose &lt;code&gt;Cell&lt;/code&gt; if your wrapped value implements &lt;code&gt;Copy&lt;/code&gt; (such as primitive values, like integers and floats). If the wrapped value is a &lt;code&gt;struct&lt;/code&gt;, doesn’t implement &lt;code&gt;Copy&lt;/code&gt; &lt;strong&gt;or&lt;/strong&gt; you need dynamically checked borrows, use &lt;code&gt;RefCell&lt;/code&gt; instead.&lt;/p&gt;
&lt;h1 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;th&gt;Cell&lt;/th&gt;&lt;th&gt;RefCell&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Semantics&lt;/td&gt;&lt;td&gt;Copy&lt;/td&gt;&lt;td&gt;Move&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Provides&lt;/td&gt;&lt;td&gt;Values&lt;/td&gt;&lt;td&gt;References&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Panics?&lt;/td&gt;&lt;td&gt;Never&lt;/td&gt;&lt;td&gt;Mixed borrows or more than one mutable borrow&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Use with&lt;/td&gt;&lt;td&gt;Primitive types&lt;/td&gt;&lt;td&gt;Structures or non-Copy types&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The table above summarizes what you learned in this blog post.&lt;/p&gt;
&lt;p&gt;I hope you found this article useful and/or interesting. As always, if you found a mistake or have any questions, please ping me on Twitter (&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/meqif&quot;&gt;@meqif&lt;/a&gt;) or send me an email (&lt;a href=&quot;mailto:words@ricardomartins.cc&quot;&gt;words@ricardomartins.cc&lt;/a&gt;). You can also join the discussion on &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4na9p6/interior_mutability_in_rust_what_why_how/&quot;&gt;reddit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4na9p6/interior_mutability_in_rust_what_why_how/d425bxq&quot;&gt;Steve Klabnik&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4na9p6/interior_mutability_in_rust_what_why_how/d42dtcz&quot;&gt;/u/critiqjo&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4na9p6/interior_mutability_in_rust_what_why_how/d42gsdm&quot;&gt;/u/birkenfield&lt;/a&gt; kindly pointed out, &lt;code&gt;Mutex&lt;/code&gt; and &lt;code&gt;RwLock&lt;/code&gt; already have interior mutability, so there’s no need to put a &lt;code&gt;Cell&lt;/code&gt; inside them. In multi-threaded scenarios you should use &lt;code&gt;Mutex&lt;/code&gt; and &lt;code&gt;RwLock&lt;/code&gt; without an additional &lt;code&gt;Cell&lt;/code&gt; or &lt;code&gt;RefCell&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.reddit.com/r/rust/comments/4na9p6/interior_mutability_in_rust_what_why_how/d42sn3z&quot;&gt;/u/krdln&lt;/a&gt; suggested the alternative graph implementation above.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;If you are familiar with C and this reminds you of &lt;code&gt;const&lt;/code&gt; pointers (whose value also can’t change but the content at the destination memory address can), you are in the right track. &lt;code&gt;y&lt;/code&gt; would be something like a &lt;code&gt;int *const&lt;/code&gt;. &lt;a href=&quot;https://ricardomartins.dev/2016/06/08/interior-mutability/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;I really don’t want to get into the strong and weak reference thing now. Suffice it to say that strong references stop objects from being destroyed, while weak references don’t. &lt;a href=&quot;https://ricardomartins.dev/2016/06/08/interior-mutability/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Practical differences between Rust closures and functions</title>
    <published>2015-10-12T00:00:00-05:00</published>
    
    <updated>2015-10-12T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2015/10/12/practical_differences_between_rust_closures_and_functions"/>
    
    <id>http://ricardomartins.cc/2015/10/12/practical_differences_between_rust_closures_and_functions</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2015/10/12/practical_differences_between_rust_closures_and_functions">&lt;p&gt;Elizabeth &lt;a rel=&quot;external&quot; href=&quot;https://users.rust-lang.org/t/taking-suggestions-for-the-new-rust-faq/2813/27&quot;&gt;asks an interesting question&lt;/a&gt;: “What’s the difference between a function and a closure that doesn’t enclose any variable?”&lt;/p&gt;
&lt;p&gt;When I read that question, I was intrigued. Using closures instead of functions tends to be more costly because closures capture some of the environment, and that has some overhead. In practice, we usually don’t think about the difference when programming, and the choice of one over the other comes down to personal preference and what feels right.&lt;/p&gt;
&lt;p&gt;However, Rust has a reasonably smart compiler that can take advantage from a wide array of optimisations, and &lt;a rel=&quot;external&quot; href=&quot;http://blog.rust-lang.org/2015/05/11/traits.html&quot;&gt;zero cost abstractions&lt;/a&gt; is one of Rust’s strengths, so it’s also reasonable to expect little difference between a function and a closure with no free variables (i.e., no enclosed variables) after optimisation.&lt;/p&gt;
&lt;p&gt;This matter can be unfolded into several smaller questions, but for the sake of pragmatism I will be focusing on the differences in the code generated by the &lt;strike&gt;current stable&lt;/strike&gt; nightly release of the compiler, &lt;code&gt;rustc 1.5.0-nightly (7bf4c885f 2015-09-26)&lt;/code&gt;. The easiest way to compare the generated assembly code is to compile the two different versions with &lt;code&gt;rustc -C opt-level=2 --emit asm&lt;/code&gt; and check the differences with &lt;code&gt;diff&lt;/code&gt;. Comparing only the optimised code will help us avoid drowning in inconsequential differences, since the debug builds are only useful for development and aren’t supposed to be used in production. 😉&lt;/p&gt;
&lt;p&gt;Alright, let’s go ahead and compare the following two examples (adapted from Elizabeth’s question):&lt;/p&gt;
&lt;h3 id=&quot;function&quot;&gt;Function&lt;/h3&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; double&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;    2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(double);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Make sure the result isn&amp;#39;t optimised away&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;{:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;i32&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;closure&quot;&gt;Closure&lt;/h3&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span&gt; x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Make sure the result isn&amp;#39;t optimised away&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;{:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;i32&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I made both versions available on the Rust playground: &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=344b0fb2cca9d4618951&amp;amp;version=stable&quot;&gt;function&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?gist=9ad2695b4083e0a4b7ee&amp;amp;version=stable&quot;&gt;closure&lt;/a&gt;. If you want to see for yourself the output of running &lt;code&gt;diff&lt;/code&gt; on the resulting files, &lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/meqif/6c9e451a4a56c8d23f37&quot;&gt;here you go&lt;/a&gt;. Be warned: the diff is “noisy” because some CPU registers are used in one version but not in the other, and there is also &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Name_mangling&quot;&gt;name mangling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Looking at the generated assembly code, the only significant difference is that the code corresponding to the body of the function/closure, &lt;code&gt;2 * x&lt;/code&gt;, is preceded by a call to &lt;code&gt;__rust_allocate&lt;/code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/rt/heap/fn.allocate.html&quot;&gt;&lt;code&gt;std::rt::heap::allocate&lt;/code&gt;&lt;/a&gt;), and followed by a call to &lt;code&gt;__rust_deallocate&lt;/code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/rt/heap/fn.deallocate.html&quot;&gt;&lt;code&gt;std::rt::heap::deallocate&lt;/code&gt;&lt;/a&gt;), but only in the version where a closure is used.&lt;/p&gt;
&lt;div&gt;&lt;strike&gt;That makes sense: the closure is actually an instance of `FnOnce`, which we can see being created and destroyed with `allocate` and `deallocate`, respectively.&lt;/strike&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;: After I published this post, &lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/huon_w/status/654111077425266688&quot;&gt;Huon Wilson&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/dot_dash/status/654218821906092032&quot;&gt;Björn Steinbrink&lt;/a&gt; took a look to the generated assembly code and concluded that the extra allocation is actually an instance of the vector &lt;code&gt;v&lt;/code&gt; that isn’t being optimized away in the closure version, which is a little surprising. Björn suspects [&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/dot_dash/status/654219152991879168&quot;&gt;1&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/dot_dash/status/654219428880629760&quot;&gt;2&lt;/a&gt;] this is due to a different set of optimizations being applied in each version. Huon also pointed out that closures are never implicitly on the heap, as he explains in an &lt;a rel=&quot;external&quot; href=&quot;http://huonw.github.io/blog/2015/05/finding-closure-in-rust/&quot;&gt;excellent blog post&lt;/a&gt; about closures. Thanks for the precious feedback, Huon and Björn!&lt;/p&gt;
&lt;p&gt;For more details about how closures are implemented in Rust, check the &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/stable/book/closures.html#closure-implementation&quot;&gt;Closures chapter&lt;/a&gt; in the official book, as well as Huon Wilson’s &lt;a rel=&quot;external&quot; href=&quot;http://huonw.github.io/blog/2015/05/finding-closure-in-rust/&quot;&gt;blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also ran a small benchmark pitting both versions against each other, but there is no measurable difference between both versions.&lt;/p&gt;
&lt;p&gt;The bottom line is, &lt;strong&gt;for most users there is no practical difference between functions and closures without captured variables&lt;/strong&gt;. Use whatever seems right. Personally, I prefer using closures when they’re small and used in one place (like in the previous examples), and functions otherwise. Remember Harold Abelson’s advice:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Programs must be written for people to read, and only incidentally for machines to execute.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;bonus-round-named-closure&quot;&gt;Bonus round: named closure&lt;/h2&gt;
&lt;p&gt;Before hitting “Publish”, I discussed that observation with a friend unfamiliar with Rust, and he thought it might be interesting to check if there was any difference between using a closure directly in the argument, as previously, and using a named closure, i.e., assigning the closure to a variable and passing it to &lt;code&gt;map&lt;/code&gt;, like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; double&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; = |&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span&gt; x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; vec!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    let&lt;/span&gt;&lt;span&gt; w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;map&lt;/span&gt;&lt;span&gt;(double);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    // Make sure the result isn&amp;#39;t optimised away&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;{:?}&amp;quot;&lt;/span&gt;&lt;span&gt;, w&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;i32&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since both the Rust compiler and LLVM (the compiler infrastructure that powers the compiler) are smart, the intermediate variable is optimises away, generating exactly the same code for this version as it did for the one with an anonymous closure.&lt;/p&gt;
&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/JakeGoulding/status/654486706935230464&quot;&gt;Jake Goulding&lt;/a&gt; noticed I goofed up and used the nightly release of the compiler instead of the stable release I meant to use. I recompiled the examples with the current stable &lt;code&gt;rustc 1.3.0 (9a92aaf19 2015-09-15)&lt;/code&gt; and generated &lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/meqif/ee9459f6440ede652665&quot;&gt;a new diff&lt;/a&gt;. As you can see in this diff, the extra allocation &lt;em&gt;is&lt;/em&gt; optimised away, just like it should. I apologize for the mistake. Thank you, Jake!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Bleeding hearts and sharp bits</title>
    <published>2014-04-09T00:00:00-05:00</published>
    
    <updated>2014-04-09T00:00:00-05:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2014/04/09/bleeding-hearts-and-sharp-bits"/>
    
    <id>http://ricardomartins.cc/2014/04/09/bleeding-hearts-and-sharp-bits</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2014/04/09/bleeding-hearts-and-sharp-bits">&lt;blockquote&gt;
&lt;p&gt;If you can’t dance, don’t blame the dance floor.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http://heartbleed.com&quot;&gt;Heartbleed&lt;/a&gt;, as you’ve probably read by now, is a serious security issue resulting from a bug in &lt;a rel=&quot;external&quot; href=&quot;http://openssl.org&quot;&gt;OpenSSL&lt;/a&gt; which allows an attacker to freely read the memory of the affected servers. Serious 💩, indeed.&lt;/p&gt;
&lt;p&gt;Some people were quick to point their fingers at the language used for implementation of the SSL standard in the OpenSSL project—that is to say, C—and are clamoring for a new implementation in what they deem a safer language, such as &lt;a rel=&quot;external&quot; href=&quot;http://www.rust-lang.org/&quot;&gt;Rust&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http://golang.org/&quot;&gt;Go&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, C is an old language and in many aspects it’s little more than assembly language dressed up. It has sharp edges and people cut themselves on those very often — dealing explicitly with memory allocation and pointers is prone to error, even for experienced programmers. I agree that having to deal with all the minutiae is cumbersome and usually unnecessary in the modern day. However, I believe the problem isn’t so much that the language allows you to shoot yourself in the foot but that many programmers are careless.&lt;/p&gt;
&lt;p&gt;Let’s have a look at the &lt;a rel=&quot;external&quot; href=&quot;http://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=ssl/t1_lib.c;h=b82fadace66e764b47ab2d854621ad89b804e8d2#l2582&quot;&gt;code&lt;/a&gt; before the &lt;a rel=&quot;external&quot; href=&quot;http://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=96db9023b881d7cd9f379b0c154650d6c108e9a3&quot;&gt;fix&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;dtls1_process_heartbeat&lt;/span&gt;&lt;span&gt;(SSL &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsigned char *&lt;/span&gt;&lt;span&gt;p &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;= &amp;amp;&lt;/span&gt;&lt;span&gt;s-&amp;gt;s3-&amp;gt;rrec.data[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span&gt;pl;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsigned short&lt;/span&gt;&lt;span&gt; hbtype;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsigned int&lt;/span&gt;&lt;span&gt; payload;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    unsigned int&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 16&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; /* Use minimum padding */&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rather boring variable declaration, although the names could be better (what kind of mischievous monster names a length variable &lt;code&gt;payload&lt;/code&gt;?).&lt;/p&gt;
&lt;p&gt;That SSL type is rather opaque, but following the trail, one ends up with this structure:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;typedef struct&lt;/span&gt;&lt;span&gt; ssl3_record_st&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        int&lt;/span&gt;&lt;span&gt; type;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;               /* type of record */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned int&lt;/span&gt;&lt;span&gt; length;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;    /* How many bytes available */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned int&lt;/span&gt;&lt;span&gt; off;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;       /* read/write offset into &amp;#39;buf&amp;#39; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned char *&lt;/span&gt;&lt;span&gt;data;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;    /* pointer to the record data */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned char *&lt;/span&gt;&lt;span&gt;input;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;   /* where the decode bytes are */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned char *&lt;/span&gt;&lt;span&gt;comp;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;    /* only used with decompression - malloc()ed */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned long&lt;/span&gt;&lt;span&gt; epoch;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;    /* epoch number, needed by DTLS1 */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned char&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt; seq_num&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;8&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt; /* sequence number, needed by DTLS1 */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } SSL3_RECORD;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anyway, the argument &lt;code&gt;s&lt;/code&gt; is read as a SSL3 record and &lt;code&gt;char p&lt;/code&gt; is left pointing to &lt;code&gt;s&lt;/code&gt;’s data. So far, nothing unusual or interesting. Onwards!&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;/* Read type and payload length first */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hbtype &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;= *&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;n2s&lt;/span&gt;&lt;span&gt;(p, payload);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pl &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt; p;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zHtjSoU.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ok, let’s go through this slowly.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt; is of type &lt;code&gt;char&lt;/code&gt;, so they’re jumping over the first byte and copying the first two bytes to &lt;code&gt;hbtype&lt;/code&gt; (which is a &lt;code&gt;short&lt;/code&gt;). This is because the heartbeat extension sticks this stuff into the data portion of &lt;code&gt;SSL3_RECORD&lt;/code&gt;, so some gymnastics is needed to access it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;n2s&lt;/code&gt; and &lt;code&gt;s2n&lt;/code&gt; are defined in &lt;code&gt;ssl/ssl_locl.h&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;#define&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; n2s&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;c&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;s&lt;/span&gt;&lt;span&gt;)	((s&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;(((&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;unsigned int&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;span&gt;]))&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			    (((&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;unsigned int&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;]))    )),c&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;#define&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; s2n&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;c&lt;/span&gt;&lt;span&gt;)	((&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt;c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;unsigned char&lt;/span&gt;&lt;span&gt;)(((s)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;0x&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;ff&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-9&quot;&gt;			  c&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;unsigned char&lt;/span&gt;&lt;span&gt;)(((s)    )&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;amp;0x&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;ff&lt;/span&gt;&lt;span&gt;)),c&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;n2s&lt;/code&gt; is supposed to read two &lt;code&gt;chars&lt;/code&gt; and return them inside an integer (or anything with at least 2 bytes). What it actually does is read two of whatever the &lt;code&gt;c&lt;/code&gt; pointer says its size is and return the result of arithmetical OR between them. A pedantic detail but dangerous if misused. I suppose strong type checking could be useful here to prevent mistakes.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;s2n&lt;/code&gt; is similar but does the opposite—dump two &lt;code&gt;chars&lt;/code&gt; into an integer.&lt;/p&gt;
&lt;p&gt;So, we read a couple of bytes, convert them to a &lt;code&gt;short&lt;/code&gt; and assign that to &lt;code&gt;payload&lt;/code&gt;, which is the payload length.&lt;/p&gt;
&lt;p&gt;Then &lt;code&gt;pl&lt;/code&gt; is changed to point to the payload data, including the two bytes indicating its supposed length.&lt;/p&gt;
&lt;p&gt;What’s becomes apparent if you’re following the code carefully is that the heartbeat payload length hasn’t been checked for validity yet and, as we’ll later see, isn’t before it’s used. This is probably the most common kind of error in C, which makes it somewhat more appalling because it should be at the forefront of the programmer’s mental checks.&lt;/p&gt;
&lt;p&gt;Later on, there’s this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;if&lt;/span&gt;&lt;span&gt; (hbtype &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;==&lt;/span&gt;&lt;span&gt; TLS1_HB_REQUEST)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        unsigned char *&lt;/span&gt;&lt;span&gt;buffer,&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; *&lt;/span&gt;&lt;span&gt;bp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        int&lt;/span&gt;&lt;span&gt; r;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        /* Allocate memory for the response, size is 1 bytes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;         * message type, plus 2 bytes payload length, plus&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;         * payload, plus padding&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;         */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        buffer &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; OPENSSL_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; +&lt;/span&gt;&lt;span&gt; payload &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+&lt;/span&gt;&lt;span&gt; padding);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bp &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt; buffer;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;        /* Enter response type, length and copy payload */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;        *&lt;/span&gt;&lt;span&gt;bp&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;++ =&lt;/span&gt;&lt;span&gt; TLS1_HB_RESPONSE;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        s2n&lt;/span&gt;&lt;span&gt;(payload, bp);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;        memcpy&lt;/span&gt;&lt;span&gt;(bp, pl, payload);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bp &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;+=&lt;/span&gt;&lt;span&gt; payload;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First a buffer for the response is allocated, then a region of memory is copied. Both their sizes depend on the payload length received earlier and it wasn’t bound-checked!&lt;/p&gt;
&lt;p&gt;This allows an attacker to send a heartbeat with an arbitrary payload length (up to 64KB (2&lt;sup&gt;16&lt;/sup&gt; bytes) of memory) and a much smaller payload body, leading to reads beyond the SSL record. 64KB seems small but it’s enough to get SSL certificates, passwords, cookies, whatever is reachable.&lt;/p&gt;
&lt;p&gt;I’m not entirely sure that this mistake is of the sort that a cleverer language would catch, since it’s likely that the &lt;code&gt;memcpy&lt;/code&gt; will happen within the application’s memory. If it tried to reach outside, the kernel would take notice and kill it with a Segmentation Fault, turning this issue into a less threatening program termination bug.&lt;/p&gt;
&lt;p&gt;I know I shouldn’t be surprised at how trusting most programmers are about user input, but these people are programming a &lt;em&gt;cryptography library&lt;/em&gt;. They should know better. Scratch that, everyone &lt;em&gt;trusts&lt;/em&gt; them to know better and to be paranoid. To say I’m disappointed is putting it lightly.&lt;/p&gt;
&lt;p&gt;While I agree that it would benefit everyone if a safer language was used for this sort of software, I do not agree that the blame lies entirely with C. Careless mistakes can happen with any language. The language used may reduce the likelihood that a mistake comes up in places with serious consequences but vigilance is absolutely essential.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry xml:lang="en">
    <title>Reboot</title>
    <published>2014-01-14T00:00:00-06:00</published>
    
    <updated>2014-01-14T00:00:00-06:00</updated>
    
    <author>
      <name>Ricardo Martins</name>
    </author>
    <link rel="alternate" type="text/html" href="https://ricardomartins.dev/2014/01/14/reboot"/>
    
    <id>http://ricardomartins.cc/2014/01/14/reboot</id>
    
    <content type="html" xml:base="https://ricardomartins.dev/2014/01/14/reboot">&lt;p&gt;New layout, new almost everything.&lt;/p&gt;
&lt;aside&gt;&lt;p&gt;Yes, I know it&#39;s hard to tell.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;This was mostly an excuse to start over and play with HTML5 and CSS. Nothing too fancy and somewhat responsive.&lt;/p&gt;
&lt;p&gt;Since I tend to make parenthetical comments, I played a little with the &lt;code&gt;aside&lt;/code&gt; tag, mostly in conjunction with CSS flexboxes for ease of positioning and responsive design. While they worked well in Chrome (both desktop and mobile), I ran into some issues in other browsers.&lt;/p&gt;
&lt;p&gt;At the time of writing, the state of flexbox support across browsers isn’t very encouraging: &lt;a rel=&quot;external&quot; href=&quot;http://stackoverflow.com/tags/flexbox/info&quot;&gt;most browsers support some version of flexbox&lt;/a&gt; but Chrome is the only one whose current (and most popular) version has support for the latest working draft, while Firefox has a sadly incomplete implementation even in the latest beta (27.0 at the time of writing). I guess I will have to wait some more time or come up with alternative solutions.&lt;/p&gt;
&lt;p&gt;The current version of this blog makes use of the following code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://davecoyle.com/tech-notes/jekyll-templates-for-atom-rss/&quot;&gt;RSS and Atom templates&lt;/a&gt; courtesy of &lt;a rel=&quot;external&quot; href=&quot;https://davecoyle.com/&quot;&gt;Dave Coyle&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/havvg/havvg.github.com/blob/master/sitemap.xml&quot;&gt;Sitemap&lt;/a&gt; by &lt;a rel=&quot;external&quot; href=&quot;http://toni.uebernickel.info/&quot;&gt;Toni Uebernickel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
</feed>
