<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SomeB1oody</title>
    <description>The latest articles on DEV Community by SomeB1oody (@someb1oody).</description>
    <link>https://dev.to/someb1oody</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2563425%2F66f2ab20-9536-4814-9f8b-5b6ab698a194.png</url>
      <title>DEV Community: SomeB1oody</title>
      <link>https://dev.to/someb1oody</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/someb1oody"/>
    <language>en</language>
    <item>
      <title>[Advanced Rust] 2.1. API Design Principles of Unsurprising - Naming Tips, Implementing Common Traits</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Sat, 01 Aug 2026 17:01:22 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-21-api-design-principles-of-unsurprising-naming-tips-implementing-common-traits-1b02</link>
      <guid>https://dev.to/someb1oody/advanced-rust-21-api-design-principles-of-unsurprising-naming-tips-implementing-common-traits-1b02</guid>
      <description>&lt;p&gt;&lt;strong&gt;Full title:&lt;/strong&gt; [Advanced Rust] 2.1. API Design Principles of Unsurprising - Naming Tips, Implementing Common Traits (Debug, Send, Sync, and Unpin)&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1.1. What Is the Unsurprising Principle?
&lt;/h2&gt;

&lt;p&gt;The unsurprising principle is also called the least-surprise principle. It means that &lt;strong&gt;the APIs you write should be as intuitive as possible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Users should be able to guess what an interface does just by looking at it. At the very least, your interface should not surprise them. &lt;strong&gt;Its core idea is to stay close to what users already know&lt;/strong&gt;, so they do not need to relearn concepts. For example, if an interface name contains &lt;code&gt;error&lt;/code&gt;, users will probably guess that it is used for error handling.&lt;/p&gt;

&lt;p&gt;In other words, we need our interfaces to be predictable, which requires attention to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming&lt;/li&gt;
&lt;li&gt;Implementing common traits&lt;/li&gt;
&lt;li&gt;Ergonomic traits&lt;/li&gt;
&lt;li&gt;Wrapper types&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2.1.2. Naming Tips
&lt;/h2&gt;

&lt;p&gt;Interface names should follow conventions so their behavior is easy to infer. Here, conventions means the conventions commonly used in the Rust standard library and Rust community.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A method named &lt;code&gt;iter&lt;/code&gt; (or ending with &lt;code&gt;iter&lt;/code&gt;) will most likely take &lt;code&gt;&amp;amp;self&lt;/code&gt; as an argument and return an iterator&lt;/li&gt;
&lt;li&gt;A method named &lt;code&gt;into_inner&lt;/code&gt; will most likely take &lt;code&gt;self&lt;/code&gt; as an argument and return the wrapped type&lt;/li&gt;
&lt;li&gt;A type named &lt;code&gt;SomethingError&lt;/code&gt; should implement &lt;code&gt;std::error::Error&lt;/code&gt; and appear in various &lt;code&gt;Result&lt;/code&gt; types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using the same common names for the same purposes helps users understand the API.&lt;/strong&gt; This leads to another conclusion: &lt;strong&gt;things with the same name should behave in the same way&lt;/strong&gt;, otherwise users will probably write incorrect code.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1.3. Implementing Common Traits
&lt;/h2&gt;

&lt;p&gt;Users usually assume that everything in an interface works “as expected,” for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can print any type with &lt;code&gt;{:?}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can send anything to another thread&lt;/li&gt;
&lt;li&gt;Every type is &lt;code&gt;Clone&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when writing code, actively implement most standard traits, even if you do not need them immediately.&lt;/p&gt;

&lt;p&gt;From another angle, users cannot implement foreign traits for foreign types themselves because that would violate the orphan rule. That makes it hard for them to add the traits they want to your types. So you should actively implement most standard traits, so your types can satisfy the traits most users expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1.4. It Is Recommended to Implement the &lt;code&gt;Debug&lt;/code&gt; Trait
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Almost all types can and should implement the &lt;code&gt;Debug&lt;/code&gt; trait&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The simplest and best way is to use &lt;code&gt;#[derive(Debug)]&lt;/code&gt;. Note that a derived trait will add the same bound to any generic parameter.&lt;/p&gt;

&lt;p&gt;An example makes this clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Pair&lt;/code&gt; struct implements the &lt;code&gt;Debug&lt;/code&gt; trait through derive, so it automatically adds the bound &lt;code&gt;T: Debug&lt;/code&gt; to the generic parameter &lt;code&gt;T&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The type of the &lt;code&gt;Pair&lt;/code&gt; fields in &lt;code&gt;main&lt;/code&gt; is &lt;code&gt;i32&lt;/code&gt;, which implements &lt;code&gt;Debug&lt;/code&gt;, so it can be printed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pair { a: 5, b: 10 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if I change the field type to something that does not implement &lt;code&gt;Debug&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Dave"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Nick"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0277]: `Person` doesn't implement `Debug`
  --&amp;gt; src/main.rs:18:22
   |
18 |     println!("{:?}", pair);
   |               ----   ^^^^ `Person` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |               |
   |               required by this formatting parameter
   |
   = help: the trait `Debug` is not implemented for `Person`
   = note: add `#[derive(Debug)]` to `Person` or manually `impl Debug for Person`
help: the trait `Debug` is implemented for `Pair&amp;lt;T&amp;gt;`
  --&amp;gt; src/main.rs:7:10
   |
 7 | #[derive(Debug)]
   |          ^^^^^
note: required for `Pair&amp;lt;Person&amp;gt;` to implement `Debug`
  --&amp;gt; src/main.rs:8:8
   |
 7 | #[derive(Debug)]
   |          ----- in this derive macro expansion
 8 | struct Pair&amp;lt;T&amp;gt; {
   |        ^^^^ - type parameter would need to implement `Debug`
   = help: consider manually implementing `Debug` to avoid undesired bounds
help: consider annotating `Person` with `#[derive(Debug)]`
   |
 3 + #[derive(Debug)]
 4 | struct Person {
   |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;We can also manually implement &lt;code&gt;Debug&lt;/code&gt; by using the various &lt;code&gt;debug_xxx&lt;/code&gt; helper methods provided by &lt;code&gt;fmt::Formatter&lt;/code&gt; in the standard library:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;debug_struct&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;debug_tuple&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;debug_list&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;debug_set&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;debug_map&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.debug_struct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pair"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We manually implement the &lt;code&gt;Debug&lt;/code&gt; trait instead of using &lt;code&gt;#[derive(Debug)]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fmt&lt;/code&gt; is the method that must be defined when implementing &lt;code&gt;fmt::Debug&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;f: &amp;amp;mut fmt::Formatter&amp;lt;'_&amp;gt;&lt;/code&gt; provides the formatting context and tools&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;f.debug_struct("Pair")&lt;/code&gt; declares that the value should be formatted as a debug struct with fields, and sets the struct name to &lt;code&gt;"Pair"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.field("a", &amp;amp;self.a)&lt;/code&gt; and &lt;code&gt;.field("b", &amp;amp;self.b)&lt;/code&gt; add the &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; fields to &lt;code&gt;Pair&lt;/code&gt; and associate each field with its value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.finish()&lt;/code&gt; completes the formatting builder and returns the result to be printed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pair { a: 1, b: 2 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2.1.5. It Is Recommended to Implement the &lt;code&gt;Send&lt;/code&gt;, &lt;code&gt;Unpin&lt;/code&gt;, and &lt;code&gt;Sync&lt;/code&gt; Traits
&lt;/h2&gt;

&lt;p&gt;If your type does not implement &lt;code&gt;Send&lt;/code&gt;, it cannot be moved to another thread (for example, &lt;code&gt;thread::spawn&lt;/code&gt; requires &lt;code&gt;T: Send&lt;/code&gt;). Wrapping a &lt;code&gt;!Send&lt;/code&gt; value in &lt;code&gt;Mutex&amp;lt;T&amp;gt;&lt;/code&gt; does not help either: &lt;code&gt;Mutex&amp;lt;T&amp;gt;&lt;/code&gt; is only &lt;code&gt;Send&lt;/code&gt;/&lt;code&gt;Sync&lt;/code&gt; when &lt;code&gt;T: Send&lt;/code&gt;, so it still cannot be shared across threads.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; does not implement &lt;code&gt;Send&lt;/code&gt;, so it cannot be used across threads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can write a simple tuple struct ourselves to implement it manually (of course, it will not have &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;'s reference counting feature):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;MyBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;MyBox&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;MyBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;into_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MyBox&lt;/code&gt; implements &lt;code&gt;Send&lt;/code&gt;, so it can be used across threads&lt;/li&gt;
&lt;li&gt;Traits such as &lt;code&gt;Send&lt;/code&gt; that act only as markers and do not provide concrete behavior are called &lt;em&gt;marker traits&lt;/em&gt;. Marker traits provide &lt;strong&gt;compile-time information&lt;/strong&gt; but do not add behavior. So implementing &lt;code&gt;Send&lt;/code&gt; for &lt;code&gt;MyBox&lt;/code&gt; does not require any method body&lt;/li&gt;
&lt;li&gt;Manually implementing &lt;code&gt;Send&lt;/code&gt; is unsafe, so we must add the &lt;code&gt;unsafe&lt;/code&gt; marker before the &lt;code&gt;impl&lt;/code&gt; block. &lt;strong&gt;Rust's type system normally infers &lt;code&gt;Send&lt;/code&gt; automatically to ensure thread safety&lt;/strong&gt;, while a manual &lt;code&gt;Send&lt;/code&gt; implementation may &lt;strong&gt;bypass Rust's safety checks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Types that do not implement &lt;code&gt;Sync&lt;/code&gt; cannot be shared across threads through &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; (the atomic reference-counted pointer, the multithreaded version of &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;), and they also cannot be stored in &lt;code&gt;static&lt;/code&gt; items that require &lt;code&gt;Sync&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.borrow_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; does not implement &lt;code&gt;Sync&lt;/code&gt;, so it cannot be shared across threads with &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;Unpin&lt;/code&gt; means “can be unpinned.” It is a &lt;em&gt;marker trait&lt;/em&gt; used to indicate &lt;strong&gt;whether a type can be safely moved out of a &lt;code&gt;Pin&lt;/code&gt;&lt;/strong&gt;, that is, &lt;strong&gt;whether it can bypass the restrictions of &lt;code&gt;Pin&amp;lt;P&amp;gt;&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most types are &lt;strong&gt;&lt;code&gt;Unpin&lt;/code&gt; by default&lt;/strong&gt;. Self-referential types are usually made &lt;code&gt;!Unpin&lt;/code&gt; by embedding a marker such as &lt;code&gt;std::marker::PhantomPinned&lt;/code&gt; (or another &lt;code&gt;!Unpin&lt;/code&gt; field). Rust does not automatically treat “has a self-reference” as &lt;code&gt;!Unpin&lt;/code&gt;; without such a marker, the type would still be &lt;code&gt;Unpin&lt;/code&gt;, and moving it could invalidate internal pointers.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If your type does not implement any of the above traits, it is recommended that you state that in the documentation.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.17. Orphan Rules, Coherence, and Consistency - Blanket and Covered Implementations</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Sat, 01 Aug 2026 05:25:42 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-117-orphan-rules-coherence-and-consistency-blanket-and-covered-implementations-3n9l</link>
      <guid>https://dev.to/someb1oody/advanced-rust-117-orphan-rules-coherence-and-consistency-blanket-and-covered-implementations-3n9l</guid>
      <description>&lt;h2&gt;
  
  
  1.17.1. Coherence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Coherence means that for a given type and method, there is only one correct choice for the implementation of that method on that type.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The orphan rule means that as long as either the trait or the type is in the local crate, you can implement that trait for that type.&lt;/strong&gt; For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A type you define locally can implement the &lt;code&gt;Debug&lt;/code&gt; trait&lt;/li&gt;
&lt;li&gt;You can implement a trait you define locally for &lt;code&gt;bool&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You cannot implement &lt;code&gt;Debug&lt;/code&gt; for &lt;code&gt;bool&lt;/code&gt;, because neither side is local&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;There are exceptions to the orphan rule&lt;/em&gt;, which we will discuss below.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.17.2. Blanket Implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A blanket implementation, also called a general implementation, means that Rust allows a default implementation for every type that satisfies a trait bound.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Its template is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MyTrait&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means implementing &lt;code&gt;MyTrait&lt;/code&gt; for all types that implement some trait.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ToString&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means implementing &lt;code&gt;ToString&lt;/code&gt; for all types that implement &lt;code&gt;Display&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This example is not yet written in template form. In template form, it would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ToString&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Display&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note that only the crate that defines the trait is allowed to use blanket implementations. Adding a blanket implementation to an existing trait is a breaking change.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.17.3. Fundamental Types
&lt;/h2&gt;

&lt;p&gt;Some types are so fundamental that we need to allow anyone to implement traits for them, even if that would violate the orphan rule. These types are marked &lt;code&gt;#[fundamental]&lt;/code&gt;, and currently include &lt;code&gt;&amp;amp;T&lt;/code&gt;, &lt;code&gt;&amp;amp;mut T&lt;/code&gt;, &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt;, and &lt;code&gt;Pin&amp;lt;P&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One extra note: the main purpose of &lt;code&gt;Pin&amp;lt;P&amp;gt;&lt;/code&gt; is to &lt;strong&gt;ensure that a value cannot be moved&lt;/strong&gt;, that is, to prevent operations such as &lt;code&gt;std::mem::replace&lt;/code&gt;, &lt;code&gt;std::mem::swap&lt;/code&gt;, or &lt;code&gt;std::mem::take&lt;/code&gt; from changing the value’s physical address&lt;/li&gt;
&lt;li&gt;For the purpose of the orphan rule, these types are actually erased before orphan-rule checking takes place&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: using blanket implementations on fundamental types is also considered a breaking change.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.17.4. Covered Implementation
&lt;/h2&gt;

&lt;p&gt;Sometimes you need to implement an external trait for an external type, which is called a covered implementation. This uses one narrow exemption established by the orphan rule: it allows an external trait to be implemented for an external type in very specific cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: covered implementation can refer either to Covered Implementation or Override Implementation. Here it refers to Covered Implementation. Override implementation means that when a struct implements a trait and provides its own methods, it can override the default implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The template for this form is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;P1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="n"&gt;Pn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ForeignTrait&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="n"&gt;Tn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;T0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;P1..=Pn&lt;/code&gt; and &lt;code&gt;T1..=T0&lt;/code&gt; refer to a number of parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This form is allowed only if all of the following conditions are met:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At least one of &lt;code&gt;T1..=Tn&lt;/code&gt; is a local type&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;T&lt;/code&gt; (where &lt;code&gt;T&lt;/code&gt; is one of the generic types in &lt;code&gt;P1..=Pn&lt;/code&gt;) may appear before the first such local type&lt;/li&gt;
&lt;li&gt;A generic type parameter &lt;code&gt;P&lt;/code&gt; may appear in &lt;code&gt;T0..Ti&lt;/code&gt; as long as it is wrapped by some intermediate type

&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;T&lt;/code&gt; appears as a type parameter of another type, such as &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, then &lt;code&gt;T&lt;/code&gt; is considered wrapped&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;T&lt;/code&gt; appears only by itself, or behind a fundamental type such as &lt;code&gt;&amp;amp;T&lt;/code&gt;, then it is not wrapped&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implements the external &lt;code&gt;From&amp;lt;MyType&amp;gt;&lt;/code&gt; trait for the external &lt;code&gt;Vec&amp;lt;i32&amp;gt;&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Here are some more complex examples. You can use the rules above to understand them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Valid?&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;T&amp;gt; for MyType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;T&amp;gt; for MyType&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;MyType&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; ForeignTrait&amp;lt;MyType, T&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&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;impl&amp;lt;T&amp;gt; ForeignTrait for T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;T&amp;gt; for T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt; for T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;MyType&amp;lt;T&amp;gt;&amp;gt; for T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; From&amp;lt;T&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;impl&amp;lt;T&amp;gt; ForeignTrait&amp;lt;T, MyType&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not OK&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Whether a covered implementation is a breaking change depends on the specific situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a new implementation to an existing trait, with at least one new local type that satisfies the conditions above, is a non-breaking change&lt;/li&gt;
&lt;li&gt;Adding an implementation for an existing trait that does not meet the conditions above is a breaking change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;impl&amp;lt;T&amp;gt; ForeignTrait&amp;lt;MyType, T&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt; is valid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;impl&amp;lt;T&amp;gt; ForeignTrait&amp;lt;T, MyType&amp;gt; for Vec&amp;lt;T&amp;gt;&lt;/code&gt; is invalid&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.16. Generic Traits - Generic (Type-Parameter) Traits and Associated-Type Traits</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Sat, 01 Aug 2026 05:11:39 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-116-generic-traits-generic-type-parameter-traits-and-associated-type-traits-4p45</link>
      <guid>https://dev.to/someb1oody/advanced-rust-116-generic-traits-generic-type-parameter-traits-and-associated-type-traits-4p45</guid>
      <description>&lt;h2&gt;
  
  
  1.16.1. Two Ways to Make a Trait Generic
&lt;/h2&gt;

&lt;p&gt;Traits can be generic in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generic type parameters. Example: &lt;code&gt;trait Foo&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Associated types. Example: &lt;code&gt;trait Foo { type Bar; }&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference between the two is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With associated types, a given trait for a specific type has only one implementation&lt;/li&gt;
&lt;li&gt;With generic parameters, there can be multiple implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;A simple suggestion: if possible, prefer associated types.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.16.2. Generic (Type-Parameter) Traits
&lt;/h2&gt;

&lt;p&gt;Generic traits require you to specify all generic type parameters and repeat their &lt;em&gt;bounds&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is somewhat harder to maintain. For example, if you add a generic type parameter to a trait, all implementers of that trait must update their code.&lt;/p&gt;

&lt;p&gt;This form can also lead to the problem that a trait may have multiple implementations for a given type. Then the compiler has a harder time inferring which instance of the trait you actually want. Sometimes you must call an ambiguity-resolving function such as &lt;code&gt;FromIterator::&amp;lt;u32&amp;gt;::from_iter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In some cases this feature is also an advantage, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;impl PartialEq&amp;lt;BookFormat&amp;gt; for Book&lt;/code&gt;, where &lt;code&gt;BookFormat&lt;/code&gt; can be different types&lt;/li&gt;
&lt;li&gt;You can implement both &lt;code&gt;FromIterator&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;FromIterator&amp;lt;&amp;amp;T&amp;gt; where T: Clone&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.16.3. Associated-Type Traits
&lt;/h2&gt;

&lt;p&gt;Let’s use a piece of code as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Contains&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Updates syntax to refer to these new types generically&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With associated types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The compiler only needs to know the type that implements the trait&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;bound&lt;/em&gt; can live entirely on the trait itself and does not need to be repeated&lt;/li&gt;
&lt;li&gt;Adding another associated type in the future does not affect users&lt;/li&gt;
&lt;li&gt;The concrete type determines the associated types inside the trait, so there is no need to use ambiguity-resolving functions. Look at this example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Contains&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Specify what types `A` and `B` are. If the `input` type&lt;/span&gt;
    &lt;span class="c1"&gt;// is `Container(i32, i32)`, the `output` types are determined&lt;/span&gt;
    &lt;span class="c1"&gt;// as `i32` and `i32`.&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// `&amp;amp;Self::A` and `&amp;amp;Self::B` are also valid here.&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;number_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;number_2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Grab the first number.&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Grab the last number.&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This example implements the &lt;code&gt;Contains&lt;/code&gt; trait for the &lt;code&gt;Container&lt;/code&gt; type&lt;/li&gt;
&lt;li&gt;The associated types in &lt;code&gt;Container&lt;/code&gt;’s &lt;code&gt;Contains&lt;/code&gt; implementation are determined by &lt;code&gt;type A = i32;&lt;/code&gt; and &lt;code&gt;type B = i32;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  You Cannot Implement &lt;code&gt;Deref&lt;/code&gt; for Multiple Target Types
&lt;/h2&gt;

&lt;p&gt;Look at the source code of the &lt;code&gt;Deref&lt;/code&gt; trait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Deref&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nb"&gt;Sized&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;deref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Target&lt;/code&gt; in &lt;code&gt;type Target: ?Sized;&lt;/code&gt; is the target type we are talking about&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s write a &lt;code&gt;Deref&lt;/code&gt; implementation to illustrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Deref&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;deref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, &lt;code&gt;Wrapper&lt;/code&gt; can only be dereferenced as &lt;code&gt;String&lt;/code&gt;. But if you want &lt;code&gt;Wrapper&lt;/code&gt; to be dereferenced as both &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;str&lt;/code&gt; &lt;strong&gt;at the same time&lt;/strong&gt;, Rust does &lt;strong&gt;not&lt;/strong&gt; allow you to implement &lt;code&gt;Deref&lt;/code&gt; again, because &lt;code&gt;Target&lt;/code&gt; can only have one concrete type.&lt;/p&gt;

&lt;p&gt;In other words, this is illegal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// First Deref implementation, Target = String&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Deref&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;deref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This is illegal: Rust does not allow a second `Deref` implementation&lt;/span&gt;
&lt;span class="c1"&gt;// for the same `Wrapper` type.&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Deref&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Conflict: Rust cannot infer which `Target` applies&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;deref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  You Cannot Use Multiple &lt;code&gt;Item&lt;/code&gt;s to Implement the &lt;code&gt;Iterator&lt;/code&gt; Trait
&lt;/h2&gt;

&lt;p&gt;The reason is the same as the reason you cannot implement &lt;code&gt;Deref&lt;/code&gt; for multiple target types: it mainly involves the &lt;strong&gt;uniqueness of associated types&lt;/strong&gt; and the &lt;strong&gt;inference rules of the Rust compiler&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.15. Trait Bounds - Compilation and Dispatch</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Thu, 30 Jul 2026 16:14:29 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-115-trait-bounds-compilation-and-dispatch-4hc5</link>
      <guid>https://dev.to/someb1oody/advanced-rust-115-trait-bounds-compilation-and-dispatch-4hc5</guid>
      <description>&lt;h2&gt;
  
  
  1.15.1. Static Dispatch
&lt;/h2&gt;

&lt;p&gt;What happens when we compile &lt;em&gt;generic code&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;The compiler copies part of the type or function for each &lt;code&gt;T&lt;/code&gt; (for each concrete type), so that each type has its own function. This process is called &lt;strong&gt;monomorphization&lt;/strong&gt;. (Calling methods on a &lt;code&gt;dyn Trait&lt;/code&gt; is different: that uses &lt;em&gt;dynamic dispatch&lt;/em&gt;, covered later in this article.)&lt;/p&gt;

&lt;p&gt;When you build &lt;code&gt;Vec&amp;lt;i32&amp;gt;&lt;/code&gt; or &lt;code&gt;HashMap&amp;lt;String, bool&amp;gt;&lt;/code&gt;, the compiler copies the generic type and all of its implementation blocks. For example, &lt;code&gt;Vec&amp;lt;i32&amp;gt;&lt;/code&gt; replaces the &lt;code&gt;T&lt;/code&gt; in &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; with &lt;code&gt;i32&lt;/code&gt;, effectively making a full copy of &lt;code&gt;Vec&lt;/code&gt;, with every &lt;code&gt;T&lt;/code&gt; replaced by &lt;code&gt;i32&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In other words, the compiler replaces the generic parameters of an instance with concrete types. Note that the compiler does not literally duplicate and paste everything; it only copies the code you actually use.&lt;/p&gt;

&lt;p&gt;Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="nf"&gt;.is_contained_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This example implements a &lt;code&gt;contains&lt;/code&gt; method for &lt;code&gt;String&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The second parameter &lt;code&gt;p&lt;/code&gt; of &lt;code&gt;contains&lt;/code&gt; is constrained by &lt;code&gt;Pattern&lt;/code&gt;. &lt;code&gt;p&lt;/code&gt; has no concrete type of its own, only a trait bound, so &lt;code&gt;p&lt;/code&gt; is effectively a generic parameter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When &lt;code&gt;p&lt;/code&gt; is used in practice, it may be different types. The method is copied for each concrete type, because we need to know the address of &lt;code&gt;is_contained_in&lt;/code&gt; so that it can be called. The CPU needs to know where to jump and continue execution.&lt;/p&gt;

&lt;p&gt;For any given &lt;code&gt;p&lt;/code&gt;, the compiler knows that the address belongs to a method implementation for the &lt;code&gt;Pattern&lt;/code&gt; trait. &lt;strong&gt;&lt;em&gt;There is no universal address that works for any type.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: I know you may be thinking of Python’s dynamic typing, but in Python a variable is fundamentally a **reference&lt;/em&gt;* to an object, not a value stored directly.*&lt;/p&gt;

&lt;p&gt;Because of this, the compiler needs to produce one copy of the method body for each type, and each copy has its own address for jumping to. That is called &lt;em&gt;static dispatch&lt;/em&gt;, because for any given copy of the method, the address we “dispatch to” is known statically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Static&lt;/em&gt; in programming usually refers to things known at compile time, or things that can be treated as such&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.15.2. Monomorphization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Monomorphization means the process of turning one generic type into many non-generic types.&lt;/strong&gt; Rust traits have this property.&lt;/p&gt;

&lt;p&gt;After the compiler finishes optimizing the code, it is as if there were no generics at all. Each instance is optimized separately with all known types, so the &lt;code&gt;is_contained_in&lt;/code&gt; call in the example above runs just as efficiently as if the trait did not exist at all — there is no performance loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The compiler fully understands the types involved, and in the appropriate cases, it can even inline them.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fully understands the types involved” means Rust is a &lt;strong&gt;statically typed&lt;/strong&gt; language, so the types of all variables and functions can be determined at compile time, without type inference at run time.&lt;/li&gt;
&lt;li&gt;“Inline them” means expanding the function body directly at the call site to avoid function-call overhead.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[inline(always)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// The compiler may optimize this into `let x = 2 + 3;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1.15.3. The Cost of Monomorphization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Every instance must be compiled separately, which increases compilation time if the compiler cannot optimize it away&lt;/li&gt;
&lt;li&gt;Each monomorphized function has its own machine code, which makes the program larger&lt;/li&gt;
&lt;li&gt;Instructions cannot be shared across different instances of a generic method, so CPU instruction-cache efficiency drops because it must hold multiple copies of the same instruction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.15.4. Dynamic Dispatch
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dynamic dispatch allows code to call trait methods on a generic type without knowing the concrete type.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can make a small change to the code above to achieve dynamic dispatch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="nf"&gt;.is_contained_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, dynamic dispatch requires the caller to provide two pieces of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data pointer for &lt;code&gt;Pattern&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The address of &lt;code&gt;is_contained_in&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does &lt;code&gt;impl Pattern&lt;/code&gt; need &lt;code&gt;&amp;amp;&lt;/code&gt; in front of it?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic dispatch depends on a &lt;strong&gt;trait object&lt;/strong&gt;, and a trait object is essentially a wide pointer (a fat pointer, as discussed in the previous article), so the data must be passed by reference (because Rust cannot know the memory size of the dynamic dispatch type, it can only use a reference)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.15.5. Vtable
&lt;/h2&gt;

&lt;p&gt;In practice, the caller provides a pointer to a block of memory called a &lt;em&gt;virtual method table&lt;/em&gt;, or &lt;em&gt;vtable&lt;/em&gt; for short.&lt;/p&gt;

&lt;p&gt;In the example above, it holds the addresses of all trait-method implementations for that type, including the address of &lt;code&gt;is_contained_in&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When the code wants to call a trait method on the provided type, it looks up the implementation address of &lt;code&gt;is_contained_in&lt;/code&gt; in the vtable and calls it. This lets us use the same function body without caring which type the caller wants to use.&lt;/p&gt;

&lt;p&gt;Each vtable also includes layout and alignment information for the concrete type, which is always needed together with the method information.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.15.6. Object Safety
&lt;/h2&gt;

&lt;p&gt;The combination of a type implementing a trait and its vtable forms a &lt;em&gt;trait object&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Most traits can be turned into trait objects, but not all. For example, &lt;code&gt;Clone&lt;/code&gt; cannot (&lt;code&gt;clone&lt;/code&gt; returns &lt;code&gt;Self&lt;/code&gt;), and &lt;code&gt;Extend&lt;/code&gt; cannot either. These examples are not &lt;em&gt;object-safe&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The specific requirements for object safety are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trait methods must not be generic, and they must use a receiver that can be dispatched through a trait object&lt;/li&gt;
&lt;li&gt;The trait cannot have static methods, because there is no instance on which to call them&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.15.7. &lt;code&gt;self: Sized&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;self: Sized&lt;/code&gt; means &lt;code&gt;self&lt;/code&gt; cannot be used on a trait object, because trait objects are &lt;code&gt;!Sized&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;self: Sized&lt;/code&gt; on a trait means that dynamic dispatch should never be used.&lt;/p&gt;

&lt;p&gt;We can also use &lt;code&gt;self: Sized&lt;/code&gt; on a specific method. In that case, the method becomes unavailable when the trait is accessed through a trait object.&lt;/p&gt;

&lt;p&gt;When checking whether a trait object is safe, methods marked with &lt;code&gt;where Self: Sized&lt;/code&gt; are exempt.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.15.8. Pros and Cons of Dynamic Dispatch
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Advantages&lt;/th&gt;
&lt;th&gt;Disadvantages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shorter compilation time&lt;/td&gt;
&lt;td&gt;The compiler cannot optimize for a specific type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Better CPU instruction-cache efficiency&lt;/td&gt;
&lt;td&gt;Functions can only be called through the vtable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Method calls have extra overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Every method call on a trait object must look up the vtable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  1.15.9. How to Choose Between Static and Dynamic Dispatch
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Static Dispatch&lt;/th&gt;
&lt;th&gt;Dynamic Dispatch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use static dispatch in libraries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Use dynamic dispatch in binaries&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You cannot know the user’s needs&lt;/td&gt;
&lt;td&gt;A binary is the final code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;If dynamic dispatch is used, the user is stuck with it&lt;/td&gt;
&lt;td&gt;Dynamic dispatch keeps the code cleaner by removing generic parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;If static dispatch is used, the user can choose for themselves&lt;/td&gt;
&lt;td&gt;Compiles faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;At the cost of marginal performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.14. Memory Types Pt.2 - Dynamically Sized Types and Wide Pointers, Packed Layouts, Larger Alignment for Speci…</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Thu, 30 Jul 2026 06:16:11 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-114-memory-types-pt2-dynamically-sized-types-and-wide-pointers-packed-1ea2</link>
      <guid>https://dev.to/someb1oody/advanced-rust-114-memory-types-pt2-dynamically-sized-types-and-wide-pointers-packed-1ea2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Full title:&lt;/strong&gt; [Advanced Rust] 1.14. Memory Types Pt.2 - Dynamically Sized Types and Wide Pointers, Packed Layouts, Larger Alignment for Specific Fields or Types, Memory Representation of Complex Types, and Repr Rust&lt;/p&gt;

&lt;h2&gt;
  
  
  1.14.1. &lt;code&gt;repr(Rust)&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Remember the example in the previous article? That example used &lt;code&gt;repr(C)&lt;/code&gt;, and the limitation of the C representation is that all fields must be placed in the same order as they are defined in the original struct.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;repr(Rust)&lt;/code&gt; is the default representation. It intentionally provides fewer layout guarantees than &lt;code&gt;repr(C)&lt;/code&gt;: the compiler may reorder fields, and two types with the same fields in the same order are still not guaranteed to share a layout.&lt;/p&gt;

&lt;p&gt;Because the compiler may reorder fields (for example, placing larger fields first), padding can often be reduced. In the &lt;code&gt;Foo&lt;/code&gt; example from the previous article, one possible optimized layout needs no padding.&lt;/p&gt;

&lt;p&gt;With fewer guarantees about layout, the compiler has room to rearrange things and produce efficient code.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;repr(Rust)&lt;/code&gt; is used, then one possible memory layout of the &lt;code&gt;Foo&lt;/code&gt; struct from above is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Field Type Size&lt;/th&gt;
&lt;th&gt;Default Representation&lt;/th&gt;
&lt;th&gt;Padding&lt;/th&gt;
&lt;th&gt;Final Alignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#[repr(Rust)]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;struct Foo {&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long: u64,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;8-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;normal: u32,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;4-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short: u16,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;2-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;small: u8,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tiny: bool,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total 16 bytes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The compiler first orders the fields by size, putting the largest first so that it can determine what alignment the struct should use. In this example, &lt;code&gt;u64&lt;/code&gt; is the largest and takes 8 bytes, so the struct is aligned to 8 bytes&lt;/li&gt;
&lt;li&gt;The compiler then looks at the remaining fields and sees that their total size is exactly 8 bytes, so it can place them together and avoid padding&lt;/li&gt;
&lt;li&gt;In the end, this struct only needs 16 bytes, which saves half the memory compared with &lt;code&gt;repr(C)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This is more efficient, but compilation time may be a little longer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.14.2. Packed Layouts
&lt;/h2&gt;

&lt;p&gt;You can tell the compiler that no padding is needed between fields, but then you must accept the performance cost of misaligned access.&lt;/p&gt;

&lt;p&gt;When memory is limited or when there are many instances of a type, a packed layout can be useful. It is also useful when sending a memory representation over a low-bandwidth network connection.&lt;/p&gt;

&lt;p&gt;To enable a packed layout, add the &lt;code&gt;#[repr(packed)]&lt;/code&gt; annotation to the type.&lt;/p&gt;

&lt;p&gt;Note that with a packed layout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Code may run more slowly&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In extreme cases, if the CPU supports only aligned access, the program may crash&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.14.3. Giving a Specific Field or Type a Larger Alignment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Using the &lt;code&gt;#[repr(align(n))]&lt;/code&gt; annotation lets you give a specific field or type a larger alignment, where &lt;code&gt;n&lt;/code&gt; is the argument.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, if you want to ensure that different values stored contiguously in memory (like in an array) end up on different CPU cache lines, you can avoid &lt;em&gt;false sharing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Here is a brief explanation of the related terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache is composed of cache lines, and caches operate on cache lines as units. A &lt;em&gt;cache line&lt;/em&gt; is the smallest data unit that can be mapped into the cache&lt;/li&gt;
&lt;li&gt;False sharing happens when two different CPUs access different variables that share the same cache line. In theory they could operate in parallel, but in the end they are both competing to update the same cache entry. This can cause a huge performance drop in concurrent programs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.14.4. Memory Representation of Complex Types
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tuples: Their memory representation is like a struct; the field types and tuple element types are in the same order&lt;/li&gt;
&lt;li&gt;Arrays: A contiguous sequence of the contained type, with no padding between elements&lt;/li&gt;
&lt;li&gt;Unions: For each field, the layout choice is independent; the alignment is the maximum among all fields&lt;/li&gt;
&lt;li&gt;Enums: Like unions, but with an additional hidden shared field used to store the discriminant of the enum variant. The code uses the discriminant value to determine which variant a given value contains. The size of the discriminant depends on the number of variants&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.14.5. Dynamically Sized Types and Wide Pointers
&lt;/h2&gt;

&lt;p&gt;Most types in Rust automatically implement the &lt;code&gt;Sized&lt;/code&gt; trait.&lt;/p&gt;

&lt;p&gt;Rust needs to know some details about its types, such as how much space to allocate for a value of a specific type. That is what makes the concept of &lt;em&gt;dynamically sized types&lt;/em&gt; a little confusing. They are sometimes called &lt;em&gt;DSTs&lt;/em&gt; or &lt;em&gt;unsized types&lt;/em&gt;, and they let us write code that works with values whose size is only known at run time.&lt;/p&gt;

&lt;p&gt;To use dynamically sized types, &lt;strong&gt;Rust provides the &lt;code&gt;Sized&lt;/code&gt; trait to indicate whether the size of a type is known at compile time&lt;/strong&gt;. Everything whose size is known at compile time automatically implements this trait. Rust also implicitly adds the &lt;code&gt;Sized&lt;/code&gt; trait to every generic function. &lt;strong&gt;By default, generic functions apply only to types whose size is known at compile time.&lt;/strong&gt; This restriction can be relaxed with &lt;code&gt;?Sized&lt;/code&gt;. &lt;code&gt;?Sized&lt;/code&gt; means “&lt;code&gt;T&lt;/code&gt; may or may not implement &lt;code&gt;Sized&lt;/code&gt;,” that is, &lt;code&gt;T&lt;/code&gt; may or may not be a dynamically sized type. This notation does not require the default condition that &lt;em&gt;generic types must have a known size at compile time&lt;/em&gt;. The &lt;code&gt;?Trait&lt;/code&gt; syntax with this meaning applies only to the &lt;code&gt;Sized&lt;/code&gt; trait and no other trait.&lt;/p&gt;

&lt;p&gt;What should we do when a function needs to accept a DST — such as a trait object or a slice — as a parameter? We can use a &lt;em&gt;wide pointer&lt;/em&gt; (also called a &lt;em&gt;fat pointer&lt;/em&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  1.14.6. Wide Pointers
&lt;/h2&gt;

&lt;p&gt;By placing a non-&lt;code&gt;Sized&lt;/code&gt; type behind a wide pointer, we bridge the gap between &lt;code&gt;Sized&lt;/code&gt; and non-&lt;code&gt;Sized&lt;/code&gt; types.&lt;/p&gt;

&lt;p&gt;So what exactly is a wide pointer? &lt;strong&gt;A wide pointer is an ordinary pointer with an additional "&lt;em&gt;word-size&lt;/em&gt;" field attached. It provides the compiler with the extra information it needs about the pointer so that it can generate sensible code that uses that pointer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you reference a DST, the compiler automatically constructs a wide pointer for you. For example, the extra information for a &lt;em&gt;slice&lt;/em&gt; is the slice’s length.&lt;/p&gt;

&lt;p&gt;Wide pointers are &lt;code&gt;Sized&lt;/code&gt; because they are pointers at heart, and their size is fixed (twice the size of a “sized” pointer — one field stores the pointer itself, and the other stores the attached metadata used to “complete” the type).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; both support storing wide pointers, so they both support &lt;code&gt;?Sized&lt;/code&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.13. Memory Types Pt.1 - Alignment, Layout, and the Repr Attribute</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Tue, 28 Jul 2026 18:34:11 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-113-memory-types-pt1-alignment-layout-and-the-repr-attribute-32a6</link>
      <guid>https://dev.to/someb1oody/advanced-rust-113-memory-types-pt1-alignment-layout-and-the-repr-attribute-32a6</guid>
      <description>&lt;h2&gt;
  
  
  1.13.1. The Basic Responsibility of Types
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every Rust value has a type, and the responsibility of that type is to tell you how to interpret the bits in memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, the bit pattern &lt;code&gt;0b10111101&lt;/code&gt; has no meaning by itself, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interpreted as &lt;code&gt;u8&lt;/code&gt;, it becomes the number 189&lt;/li&gt;
&lt;li&gt;Interpreted as &lt;code&gt;i8&lt;/code&gt;, it becomes the number -67&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you define a custom type, the compiler decides where each part of that type is placed in memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.2. Alignment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Alignment determines where a type’s bytes may be stored.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once a type’s representation is determined, you might think it can be stored anywhere in memory. In theory that is possible, but in practice computer hardware places constraints on where a given type can live.&lt;/p&gt;

&lt;p&gt;The most typical example is a pointer. A pointer points to bytes, not bits; one byte equals 8 bits. In other words, it does not point to an individual bit. So if a value of some type were placed at bit index 4 in memory, you would not be able to address it, because pointers address bytes rather than specific bits. That is why alignment is done at the byte level — that is, at 8-bit boundaries.&lt;/p&gt;

&lt;p&gt;For this reason, &lt;strong&gt;all values, regardless of type, must begin on a byte boundary&lt;/strong&gt;. All types must be at least byte-aligned. In other words, the storage address must be a multiple of 8 bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.3. Stricter Alignment Rules
&lt;/h2&gt;

&lt;p&gt;Some types have alignment requirements stricter than byte alignment. In CPU and memory systems, memory is often accessed in blocks larger than a single byte.&lt;/p&gt;

&lt;p&gt;For example, on a 64-bit CPU, most values are accessed in 8-byte blocks, and each operation begins at an address that is &lt;em&gt;8-byte aligned&lt;/em&gt;. This is also called the CPU word size.&lt;/p&gt;

&lt;p&gt;Of course, CPUs can also handle reads and writes of smaller values, as well as values that cross block boundaries. But as developers, we should &lt;strong&gt;try our best to ensure that hardware operates at its native alignment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, if the &lt;code&gt;i64&lt;/code&gt; value you want to read begins in the middle of an 8-byte block, then reading it requires at least two reads. Because &lt;code&gt;i64&lt;/code&gt; is 8 bytes wide, beginning in the middle of two 8-byte blocks means it must span both blocks. So when reading it, the engine must read from both blocks: the first block provides the first part of the &lt;code&gt;i64&lt;/code&gt;, the second block provides the remaining part, and then the pieces must be merged.&lt;/p&gt;

&lt;p&gt;That is very inefficient and slows down program execution, so we should try to keep hardware operations aligned to their native boundaries whenever possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.4. Misaligned Access
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When a CPU accesses memory and the data address does not follow the alignment required by the architecture, it is called a "misaligned access".&lt;/strong&gt; This can lead to poor performance and concurrency issues.&lt;/p&gt;

&lt;p&gt;Many CPUs require, or strongly recommend, that their parameters be naturally aligned. A naturally aligned value has alignment that matches its size.&lt;/p&gt;

&lt;p&gt;For example, if you want to load 8 bytes, the provided address should be 8-byte aligned.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.5. The Compiler Tries to Use Alignment as Much as Possible
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Based on the contents a type includes, the compiler computes an alignment for that type (or, in other words, assigns it an alignment scheme):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For primitive values, alignment usually matches their size. For example, &lt;code&gt;u8&lt;/code&gt; is aligned to 1 byte, &lt;code&gt;u16&lt;/code&gt; to 2 bytes, &lt;code&gt;u32&lt;/code&gt; to 4 bytes, and &lt;code&gt;u64&lt;/code&gt; to 8 bytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For compound types (types that contain other types), the alignment is usually the maximum alignment of the contained types. For example, if a type contains fields of &lt;code&gt;u8&lt;/code&gt;, &lt;code&gt;u16&lt;/code&gt;, and &lt;code&gt;u32&lt;/code&gt;, then the type should be 4-byte aligned (&lt;code&gt;u32&lt;/code&gt; has the largest alignment, which is 4 bytes).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.13.6. Layout
&lt;/h2&gt;

&lt;p&gt;The layout of a type is how the compiler decides to represent that type in memory.&lt;/p&gt;

&lt;p&gt;The Rust compiler does not provide many guarantees about how types are laid out.&lt;/p&gt;

&lt;p&gt;Rust provides the &lt;code&gt;repr&lt;/code&gt; attribute: it can be added to a type definition to request a specific representation.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.7. &lt;code&gt;repr(C)&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most common &lt;code&gt;repr&lt;/code&gt; attributes is &lt;code&gt;repr(C)&lt;/code&gt;. The &lt;code&gt;C&lt;/code&gt; in the name indicates that it is related to C.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;repr(C)&lt;/code&gt; layout is compatible with the layout used by C/C++ compilers for the same type. This is useful for Rust code that interacts with other languages through FFI (&lt;em&gt;Foreign Function Interface&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;When using FFI to interact with other languages, Rust generates a layout that matches what the other language’s compiler expects. Because C layout is predictable and unlikely to change, &lt;code&gt;repr(C)&lt;/code&gt; is very useful in &lt;code&gt;unsafe&lt;/code&gt; contexts.&lt;/p&gt;

&lt;p&gt;For example, you can use it when working with raw pointers to that type or when converting between two types with the same fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.8. &lt;code&gt;repr(transparent)&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;transparent&lt;/code&gt; in &lt;code&gt;repr(transparent)&lt;/code&gt; means transparent. &lt;strong&gt;It is used on newtype-style wrappers and guarantees that the outer type has the same layout as its single non-zero-sized field.&lt;/strong&gt; (Other fields are allowed only if they are zero-sized types, such as &lt;code&gt;()&lt;/code&gt; or &lt;code&gt;PhantomData&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;This is very useful when combined with the newtype pattern.&lt;/p&gt;

&lt;p&gt;Let’s briefly revisit the newtype pattern here: you use a tuple struct to create a new local type, which is essentially a thin wrapper.&lt;/p&gt;

&lt;p&gt;For example, if you want to operate on the memory representation of &lt;code&gt;struct A&lt;/code&gt; and &lt;code&gt;struct NewA(A)&lt;/code&gt;, then after using &lt;code&gt;repr(transparent)&lt;/code&gt;, the two memory representations should be the same. Without it, the Rust compiler cannot guarantee that.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.13.9. An Example of Using &lt;code&gt;repr&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s look at an example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Field Type Size&lt;/th&gt;
&lt;th&gt;Default Representation&lt;/th&gt;
&lt;th&gt;Padding&lt;/th&gt;
&lt;th&gt;Final Alignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#[repr(C)]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;struct Foo {&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tiny: bool,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1-byte aligned&lt;/td&gt;
&lt;td&gt;3 bytes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;normal: u32,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;4-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;(&lt;code&gt;tiny&lt;/code&gt; + &lt;code&gt;normal&lt;/code&gt;) 8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;small: u8,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1-byte aligned&lt;/td&gt;
&lt;td&gt;7 bytes&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long: u64,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;8-byte aligned&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short: u16,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;2-byte aligned&lt;/td&gt;
&lt;td&gt;6 bytes&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total 32 bytes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This table shows the memory alignment and padding of a Rust struct under &lt;code&gt;#[repr(C)]&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The code is in the leftmost column and uses the &lt;code&gt;repr(C)&lt;/code&gt; annotation. The struct contains several fields&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Rust compiler first sees that the &lt;code&gt;tiny&lt;/code&gt; field is of type &lt;code&gt;bool&lt;/code&gt;, which occupies 1 byte in memory, so it is aligned to 1 byte&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The compiler then sees that the &lt;code&gt;normal&lt;/code&gt; field is of type &lt;code&gt;u32&lt;/code&gt;, which occupies 4 bytes, so it only needs 4-byte alignment. At this point Rust notices that &lt;code&gt;tiny&lt;/code&gt; is aligned to 1 byte, so the compiler inserts 3 bytes of padding to make &lt;code&gt;tiny&lt;/code&gt; occupy 4 bytes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since this field now occupies exactly 8 bytes, which is a multiple of 4 bytes, it is already aligned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;small&lt;/code&gt; field is of type &lt;code&gt;u8&lt;/code&gt;, which occupies 1 byte and is aligned to 1 byte. Because the previous two fields are already aligned, Rust will decide how much padding to add based on the following bytes. At this point the compiler still has to wait and see&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;long&lt;/code&gt; is of type &lt;code&gt;u64&lt;/code&gt;, which occupies 8 bytes and is naturally 8-byte aligned. Since its field is 8 bytes or larger, we now see that &lt;code&gt;tiny&lt;/code&gt; and &lt;code&gt;normal&lt;/code&gt; together form an 8-byte-aligned region, and &lt;code&gt;long&lt;/code&gt; is also 8-byte aligned. Rust understands that the structure should now be aligned to 8 bytes. Therefore the compiler has to add 7 bytes of padding to &lt;code&gt;small&lt;/code&gt; to make it 8-byte aligned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;short&lt;/code&gt; is of type &lt;code&gt;u16&lt;/code&gt;, which occupies 2 bytes. Since the structure should now be 8-byte aligned, the compiler adds 6 bytes so that it becomes 8-byte aligned&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The process can be represented in a table like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Type Size&lt;/th&gt;
&lt;th&gt;Required Alignment&lt;/th&gt;
&lt;th&gt;Padding&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tiny: bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;3 bytes&lt;/td&gt;
&lt;td&gt;To align the next &lt;code&gt;u32&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;normal: u32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;Aligned as &lt;code&gt;u32&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;small: u8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;7 bytes&lt;/td&gt;
&lt;td&gt;To align the next &lt;code&gt;u64&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long: u64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;8-byte aligned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short: u16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;6 bytes&lt;/td&gt;
&lt;td&gt;Structure aligned to 8 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.12. Lifetimes (Advanced) Pt.2 - Lifetime Variance, Covariance, Invariance, Contravariance</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Tue, 28 Jul 2026 00:30:07 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-112-lifetimes-advanced-pt2-lifetime-variance-covariance-invariance-1lkc</link>
      <guid>https://dev.to/someb1oody/advanced-rust-112-lifetimes-advanced-pt2-lifetime-variance-covariance-invariance-1lkc</guid>
      <description>&lt;h2&gt;
  
  
  1.12.1. Lifetime Variance
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Variance is a concept in Rust’s type system. It describes how generic parameters — especially lifetime parameters — relate to one another in the type hierarchy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can think of it simply as &lt;em&gt;variance describes which types are “subtypes” of other types&lt;/em&gt;, where “subtype” is somewhat similar to the concept used in Java and C#.&lt;/p&gt;

&lt;p&gt;In addition, &lt;em&gt;variance also cares about when a “subtype” can replace a “supertype” and vice versa&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In general, if A is a subtype of B, then A is at least as useful as B. Here is a Rust example: if a function takes &lt;code&gt;&amp;amp;'a str&lt;/code&gt;, then &lt;code&gt;&amp;amp;'static str&lt;/code&gt; can be passed in. &lt;strong&gt;Because &lt;code&gt;'static&lt;/code&gt; is a subtype of &lt;code&gt;'a&lt;/code&gt;, &lt;code&gt;'static&lt;/code&gt; lives at least as long as any &lt;code&gt;'a&lt;/code&gt; (and &lt;code&gt;'static&lt;/code&gt; can remain valid for the entire program).&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.12.2. Three Kinds of Lifetime Variance
&lt;/h2&gt;

&lt;p&gt;All types have variance. The variance associated with each type defines which similar types can be used in that type’s position.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: the following content is fairly difficult. It is recommended that you first recall the ideas of sufficient conditions and necessary conditions from high school math.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Covariant
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Covariant means that a type can be replaced only by a “subtype.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Covariance means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if A &amp;lt;: B (A is a subtype of B), then F&amp;lt;A&amp;gt; &amp;lt;: F&amp;lt;B&amp;gt; (F&amp;lt;A&amp;gt; is also a subtype of F&amp;lt;B&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;transitive inheritance relationship from smaller to larger&lt;/strong&gt;, similar to reasoning from a &lt;strong&gt;sufficient condition&lt;/strong&gt;: &lt;strong&gt;if A holds, then B must also hold&lt;/strong&gt; (A is a sufficient condition for B).&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;&amp;amp;'static T&lt;/code&gt; can replace &lt;code&gt;&amp;amp;'a T&lt;/code&gt;, because &lt;code&gt;&amp;amp;T&lt;/code&gt; is covariant over the lifetime &lt;code&gt;'a&lt;/code&gt;, so &lt;code&gt;'a&lt;/code&gt; can be replaced by one of its subtypes, such as &lt;code&gt;'static&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Invariant
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Invariant means that you must provide the exact specified type.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Invariance means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A &amp;lt;: B cannot imply F&amp;lt;A&amp;gt; &amp;lt;: F&amp;lt;B&amp;gt;, and F&amp;lt;B&amp;gt; &amp;lt;: F&amp;lt;A&amp;gt; also cannot be inferred
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means there is &lt;strong&gt;not enough relationship&lt;/strong&gt; between &lt;code&gt;F&amp;lt;A&amp;gt;&lt;/code&gt; and &lt;code&gt;F&amp;lt;B&amp;gt;&lt;/code&gt; to derive one from the other, so they are &lt;strong&gt;neither sufficient conditions nor necessary conditions&lt;/strong&gt;; they are independent.&lt;/p&gt;

&lt;p&gt;For example, the mutable reference &lt;code&gt;&amp;amp;mut T&lt;/code&gt; is invariant over &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Contravariant
&lt;/h3&gt;

&lt;p&gt;Contravariance means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if A &amp;lt;: B (A is a subtype of B), then F&amp;lt;B&amp;gt; &amp;lt;: F&amp;lt;A&amp;gt; (F&amp;lt;B&amp;gt; is instead a subtype of F&amp;lt;A&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic here is: “To make &lt;code&gt;F&amp;lt;A&amp;gt;&lt;/code&gt; hold, B must satisfy A’s condition,” which is more like a &lt;strong&gt;necessary condition&lt;/strong&gt;: &lt;strong&gt;if B holds, then A must also hold&lt;/strong&gt; (A is a necessary condition for B).&lt;/p&gt;

&lt;p&gt;You can think of contravariance as “the relationship moves in the opposite direction”: the lower a function’s requirements for its parameters, the greater the range of cases it can handle.&lt;/p&gt;

&lt;p&gt;Here are two examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Suppose there are two variables, &lt;code&gt;x1&lt;/code&gt; and &lt;code&gt;x2&lt;/code&gt;, where &lt;code&gt;x1&lt;/code&gt; has the lifetime &lt;code&gt;'static&lt;/code&gt; and &lt;code&gt;x2&lt;/code&gt; has the lifetime &lt;code&gt;'a&lt;/code&gt;. Then clearly &lt;code&gt;x1&lt;/code&gt; is more useful than &lt;code&gt;x2&lt;/code&gt;, because it lives longer.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose there are two functions, &lt;code&gt;take_func1&lt;/code&gt; and &lt;code&gt;take_func2&lt;/code&gt;, where &lt;code&gt;take_func1&lt;/code&gt; accepts &lt;code&gt;&amp;amp;'static str&lt;/code&gt; and &lt;code&gt;take_func2&lt;/code&gt; accepts &lt;code&gt;&amp;amp;'a str&lt;/code&gt;. Clearly, &lt;code&gt;take_func1&lt;/code&gt; places stricter requirements on its argument, which means &lt;code&gt;take_func1&lt;/code&gt; is not as broadly useful as &lt;code&gt;take_func2&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the two examples above, we can see that giving a variable a longer lifetime makes it more useful, but requiring a function parameter to have a longer lifetime makes the function less useful. That is contravariance.&lt;/p&gt;

&lt;p&gt;So what is contravariant with what? It is the &lt;strong&gt;function’s contravariance over the types of its parameters&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.12.3. The Role of Lifetime Variance
&lt;/h2&gt;

&lt;p&gt;Let’s look at an example to see what lifetime variance does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MutStr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'b&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'b&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MutStr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="py"&gt;.s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The confusing part of this code is the &lt;code&gt;MutStr&lt;/code&gt; struct, so let’s break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The struct has only one field, but it has two lifetimes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;'a mut&lt;/code&gt; means &lt;strong&gt;a mutable reference&lt;/strong&gt;, and the lifetime of that mutable reference is &lt;code&gt;'a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;'b str&lt;/code&gt; means &lt;strong&gt;a reference to a string slice&lt;/strong&gt;, and the lifetime of that string slice is &lt;code&gt;'b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In other words, &lt;code&gt;MutStr&lt;/code&gt; lets you store a &lt;strong&gt;mutable reference&lt;/strong&gt; that points to &lt;strong&gt;a reference to a string slice&lt;/strong&gt;. You can modify &lt;code&gt;s&lt;/code&gt; itself, but you cannot modify the string content pointed to by &lt;code&gt;&amp;amp;'b str&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let’s look at the logic in &lt;code&gt;main&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;let mut s = "hello";&lt;/code&gt; declares the variable &lt;code&gt;s&lt;/code&gt;, whose type is &lt;code&gt;&amp;amp;str&lt;/code&gt;, and whose value is &lt;code&gt;"hello"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;*MutStr { s: &amp;amp;mut s }.s = "world";&lt;/code&gt; is actually several steps combined into one line. Let’s separate them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MutStr { s: &amp;amp;mut s }&lt;/code&gt; passes a mutable reference to &lt;code&gt;s&lt;/code&gt; into the &lt;code&gt;MutStr&lt;/code&gt; struct. At this point, the value of the &lt;code&gt;s&lt;/code&gt; field inside &lt;code&gt;MutStr&lt;/code&gt; is &lt;code&gt;"hello"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;*MutStr { s: &amp;amp;mut s }.s = "world";&lt;/code&gt;, the &lt;code&gt;.s&lt;/code&gt; means access the &lt;code&gt;s&lt;/code&gt; field (at this point the field’s value is &lt;code&gt;&amp;amp;mut s&lt;/code&gt;). &lt;code&gt;*&lt;/code&gt; &lt;strong&gt;dereferences&lt;/strong&gt; &lt;code&gt;s&lt;/code&gt;, that is, it obtains the reference itself to the string slice &lt;code&gt;s&lt;/code&gt;. &lt;code&gt;= "world"&lt;/code&gt; changes the pointed-to value — &lt;code&gt;s&lt;/code&gt; used to point to &lt;code&gt;"hello"&lt;/code&gt;, and now it is changed to &lt;code&gt;"world"&lt;/code&gt;, that is, &lt;code&gt;s = "world"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if there were only one lifetime — could this still be written?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MutStr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MutStr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="py"&gt;.s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E0308&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;mismatched&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MutStr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="py"&gt;.s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;-----------------------&lt;/span&gt;   &lt;span class="o"&gt;^^^^^^^&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;|&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;

&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E0277&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;compilation&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MutStr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="py"&gt;.s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt; &lt;span class="n"&gt;doesn&lt;/span&gt;&lt;span class="nv"&gt;'t&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;Sized&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;implemented&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hand&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;assignment&lt;/span&gt; &lt;span class="n"&gt;must&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;statically&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On this one-liner, rustc reports the failure at the assignment (&lt;code&gt;expected str, found &amp;amp;str&lt;/code&gt;, and &lt;code&gt;str&lt;/code&gt; is unsized). The deeper type problem is that &lt;code&gt;&amp;amp;mut s&lt;/code&gt; has type &lt;code&gt;&amp;amp;mut &amp;amp;str&lt;/code&gt;, while the field expects &lt;code&gt;&amp;amp;mut str&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;More specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The variable &lt;code&gt;s&lt;/code&gt; has type &lt;code&gt;&amp;amp;str&lt;/code&gt; (a reference to a string slice).&lt;/li&gt;
&lt;li&gt;When you write &lt;code&gt;&amp;amp;mut s&lt;/code&gt;, its actual type is &lt;code&gt;&amp;amp;mut &amp;amp;str&lt;/code&gt;, that is, a mutable reference to the variable &lt;code&gt;s&lt;/code&gt;. However, the &lt;code&gt;MutStr&lt;/code&gt; definition requires the field &lt;code&gt;s&lt;/code&gt; to have type &lt;code&gt;&amp;amp;mut str&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you isolate the construction as &lt;code&gt;MutStr { s: &amp;amp;mut s }&lt;/code&gt;, rustc instead reports that you cannot borrow the data behind an &lt;code&gt;&amp;amp;&lt;/code&gt; reference as mutable — the same underlying mismatch, surfaced differently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are different referent types, not a lifetime-subtyping question. (Separately, note that &lt;code&gt;&amp;amp;mut T&lt;/code&gt; &lt;em&gt;does&lt;/em&gt; support unsizing coercions such as &lt;code&gt;&amp;amp;mut [T; N]&lt;/code&gt; → &lt;code&gt;&amp;amp;mut [T]&lt;/code&gt;; that mechanism still cannot turn &lt;code&gt;&amp;amp;mut &amp;amp;str&lt;/code&gt; into &lt;code&gt;&amp;amp;mut str&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;What invariance &lt;em&gt;does&lt;/em&gt; matter for is the two-lifetime version: &lt;code&gt;&amp;amp;'a mut &amp;amp;'b str&lt;/code&gt; is invariant in &lt;code&gt;'b&lt;/code&gt;, which prevents unsoundly shortening the inner borrow when you assign through the mutable reference.&lt;/p&gt;

&lt;p&gt;You can also think about it this way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;String literals (&lt;code&gt;"hello"&lt;/code&gt; and &lt;code&gt;"world"&lt;/code&gt; are string literals) have type &lt;code&gt;&amp;amp;str&lt;/code&gt; and an implicit &lt;code&gt;'static&lt;/code&gt; lifetime annotation, which means &lt;code&gt;&amp;amp;str&lt;/code&gt; is actually &lt;code&gt;&amp;amp;'static str&lt;/code&gt;. In the original struct, this corresponds to &lt;code&gt;'b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The struct’s &lt;code&gt;'a&lt;/code&gt; corresponds to the lifetime of the mutable reference, which is the lifetime of the &lt;code&gt;&amp;amp;mut&lt;/code&gt; mutable reference in the line &lt;code&gt;*MutStr { s: &amp;amp;mut s }.s = "world"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After the change, the struct with only one lifetime parameter expects &lt;code&gt;&amp;amp;mut str&lt;/code&gt;, but &lt;code&gt;&amp;amp;mut s&lt;/code&gt; still has type &lt;code&gt;&amp;amp;mut &amp;amp;str&lt;/code&gt;, so the types do not match&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.11. Lifetimes (Advanced) Pt.1 - Review, Borrow Checker, Generic Lifetimes</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Tue, 28 Jul 2026 00:28:57 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-111-lifetimes-advanced-pt1-review-borrow-checker-generic-lifetimes-2o6c</link>
      <guid>https://dev.to/someb1oody/advanced-rust-111-lifetimes-advanced-pt1-review-borrow-checker-generic-lifetimes-2o6c</guid>
      <description>&lt;h2&gt;
  
  
  1.11.1. Review
&lt;/h2&gt;

&lt;p&gt;In the beginner tutorial, we mentioned that every reference in Rust has a lifetime. A lifetime is the scope in which the reference remains valid, and in most cases it is implicit and inferred by the compiler.&lt;/p&gt;

&lt;p&gt;When you take a reference to a variable, the lifetime begins. When the variable is moved or goes out of scope, the lifetime ends. In other words, for a reference, a lifetime is the name of the code region in which it must remain valid.&lt;/p&gt;

&lt;p&gt;Lifetimes usually overlap with scopes, but not always.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.11.2. Borrow Checker
&lt;/h2&gt;

&lt;p&gt;Whenever a reference with some lifetime &lt;code&gt;'a&lt;/code&gt; is used, the borrow checker checks whether &lt;code&gt;'a&lt;/code&gt; is still alive. The process is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trace the path back to where &lt;code&gt;'a&lt;/code&gt; began — that is, where the reference was obtained&lt;/li&gt;
&lt;li&gt;From there, check whether there are conflicts along that path&lt;/li&gt;
&lt;li&gt;Ensure that the reference points to a value that can be accessed safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example uses the &lt;a href="https://crates.io/crates/rand" rel="noopener noreferrer"&gt;&lt;code&gt;rand&lt;/code&gt;&lt;/a&gt; crate. Add the following dependency to &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;rand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.8"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;84&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;x&lt;/code&gt; is of type &lt;code&gt;Box&amp;lt;i32&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Declaring &lt;code&gt;r&lt;/code&gt; as a reference to &lt;code&gt;x&lt;/code&gt; means the reference’s lifetime begins on that line (line 5)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On line 7, the value of &lt;code&gt;x&lt;/code&gt; is modified through dereferencing. That requires a mutable reference to &lt;code&gt;x&lt;/code&gt;. At this point, the borrow checker looks for a mutable reference to &lt;code&gt;x&lt;/code&gt; and checks whether its use conflicts with anything else. In this example there is no conflict, so the code is valid&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You may ask: line 7 is inside the scope of &lt;code&gt;r&lt;/code&gt;. Since &lt;code&gt;*x&lt;/code&gt; needs a mutable reference to &lt;code&gt;x&lt;/code&gt;, shouldn’t having both the immutable reference &lt;code&gt;r&lt;/code&gt; and the mutable reference &lt;code&gt;*x&lt;/code&gt; in the same scope violate the borrowing rules and produce an error?&lt;br&gt;
In fact, Rust is smart enough to know that if the &lt;code&gt;if&lt;/code&gt; branch is taken, the &lt;code&gt;else&lt;/code&gt; branch cannot be taken. &lt;code&gt;r&lt;/code&gt; is never used in the &lt;code&gt;if&lt;/code&gt; branch at all, so using the mutable reference &lt;code&gt;*x&lt;/code&gt; in the &lt;code&gt;if&lt;/code&gt; branch is fine. In other words, the lifetime of &lt;code&gt;r&lt;/code&gt; does not extend into the &lt;code&gt;if&lt;/code&gt; branch. This is an example of how lifetimes do not always exactly match scopes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
        &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; is of type &lt;code&gt;Box&amp;lt;i32&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;z&lt;/code&gt; is a reference to &lt;code&gt;x&lt;/code&gt;, so the lifetime begins on this line (line 4)&lt;/li&gt;
&lt;li&gt;On line 6, &lt;code&gt;z&lt;/code&gt; is printed inside the loop. Using &lt;code&gt;z&lt;/code&gt; naturally triggers a borrow-checker check. There is no problem here, so the borrow checker does not report an error&lt;/li&gt;
&lt;li&gt;On line 7, &lt;code&gt;x&lt;/code&gt; is reassigned&lt;/li&gt;
&lt;li&gt;On line 8, &lt;code&gt;z&lt;/code&gt; is reassigned. Rust treats the newly assigned reference as a different reference, so line 8 effectively starts a new lifetime, and the original lifetime ends at line 7&lt;/li&gt;
&lt;li&gt;Each subsequent loop iteration starts a new lifetime at &lt;code&gt;z = &amp;amp;x;&lt;/code&gt;. Therefore the borrow checker does not report an error&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Features of the Borrow Checker
&lt;/h3&gt;

&lt;p&gt;The borrow checker is conservative: if it is not sure whether a borrow is valid, it rejects that borrow.&lt;/p&gt;

&lt;p&gt;Sometimes the borrow checker needs help understanding why a borrow is valid, which is one of the reasons &lt;code&gt;Unsafe Rust&lt;/code&gt; exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.11.3. Generic Lifetimes
&lt;/h2&gt;

&lt;p&gt;Sometimes we need to store references inside our own types. Then we need to annotate those references with lifetimes so that the borrow checker can verify their validity. One example is returning a reference from a method where the returned reference lives longer than &lt;code&gt;self&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rust lets you make a type generic over one or more lifetimes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two Reminders
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If a type implements the &lt;code&gt;Drop&lt;/code&gt; trait, then dropping the type counts as using the lifetimes or types that the type is generic over. If the type does not implement &lt;code&gt;Drop&lt;/code&gt;, then dropping it does not count as using the lifetime, and the references inside the type can be ignored.&lt;br&gt;
For example, when an instance of some type is about to be dropped, the borrow checker checks whether it is still legal to use the lifetimes that the type is generic over, because the code in your &lt;code&gt;drop&lt;/code&gt; function might use those references.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A type can be generic over multiple lifetimes, but usually there is no need to make the type signature more complex. You should use multiple lifetime parameters only when the type contains multiple references, and the returned reference should be tied only to one of those lifetimes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;longest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="n"&gt;x&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="n"&gt;y&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;'a&lt;/code&gt; denotes a lifetime called &lt;code&gt;a&lt;/code&gt;. &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and the return type all share this lifetime &lt;code&gt;a&lt;/code&gt;, which means that &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and the return value all have the same lifetime.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.10. References and Interior Mutability (Quick Recap) - References, Interior Mutability, Cell Type, and Relate…</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Sat, 25 Jul 2026 20:34:21 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-110-references-and-interior-mutability-quick-recap-references-interior-3mkh</link>
      <guid>https://dev.to/someb1oody/advanced-rust-110-references-and-interior-mutability-quick-recap-references-interior-3mkh</guid>
      <description>&lt;p&gt;&lt;strong&gt;Full title:&lt;/strong&gt; [Advanced Rust] 1.10. References and Interior Mutability (Quick Recap) - References, Interior Mutability, Cell Type, and Related Operations&lt;/p&gt;

&lt;h2&gt;
  
  
  1.10.1. References
&lt;/h2&gt;

&lt;p&gt;Through references, Rust allows values to be borrowed without giving up ownership.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A reference is a pointer with an additional contract attached.&lt;/strong&gt; Rust has two kinds of references.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Shared References
&lt;/h3&gt;

&lt;p&gt;Shared references, also called &lt;em&gt;immutable references&lt;/em&gt;, are written in Rust as &lt;code&gt;&amp;amp;T&lt;/code&gt;, where &lt;code&gt;T&lt;/code&gt; stands for a type.&lt;/p&gt;

&lt;p&gt;Their characteristic is that any number of references can exist at the same time, or within the same scope, pointing to the same value. Every shared reference implements the &lt;code&gt;Copy&lt;/code&gt; trait.&lt;/p&gt;

&lt;p&gt;The value behind a shared reference is immutable. The compiler is allowed to assume that the value pointed to by a shared reference does not change while that reference is alive.&lt;/p&gt;

&lt;p&gt;For example: if the value behind a shared reference is read multiple times inside a function, the compiler is allowed to read it once and then reuse the read value.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Mutable References
&lt;/h3&gt;

&lt;p&gt;The counterpart to immutable references is the &lt;em&gt;mutable reference&lt;/em&gt;, written in Rust as &lt;code&gt;&amp;amp;mut T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A mutable reference is exclusive, which means that within one scope there can be only one mutable reference; there cannot be a second mutable reference or any number of shared references.&lt;/strong&gt; Therefore, mutable references do not implement the &lt;code&gt;Copy&lt;/code&gt; trait (shared references do).&lt;/p&gt;

&lt;p&gt;The compiler assumes that no other thread accesses the type pointed to by a mutable reference, whether through a shared reference or another mutable reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.10.2. Owning a Value vs. Owning a Mutable Reference to a Value
&lt;/h2&gt;

&lt;p&gt;The owner is responsible for deleting the value — or dropping it — and aside from that, the two behave mostly the same.&lt;/p&gt;

&lt;p&gt;Note: if you move the value behind a mutable reference, you must leave another value in its place. If you do not, the owner will think it still needs to drop the value, but there is actually nothing left to drop, which leads to &lt;strong&gt;undefined behavior&lt;/strong&gt; or a &lt;strong&gt;compilation error&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// `r` becomes a dangling reference&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E0507&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;behind&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;^^&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="n"&gt;occurs&lt;/span&gt; &lt;span class="n"&gt;because&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;implement&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;Copy&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;consider&lt;/span&gt; &lt;span class="n"&gt;removing&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;dereference&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;consider&lt;/span&gt; &lt;span class="n"&gt;cloning&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;performance&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;acceptable&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Try to move the value pointed to by `r`&lt;/span&gt;
  &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s walk through the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;r&lt;/code&gt; is a mutable reference to &lt;code&gt;s&lt;/code&gt;, and the &lt;code&gt;*r&lt;/code&gt; operation tries to &lt;strong&gt;move&lt;/strong&gt; the value (&lt;code&gt;String&lt;/code&gt; does not implement &lt;code&gt;Copy&lt;/code&gt;, so &lt;code&gt;s&lt;/code&gt; would lose its data)&lt;/li&gt;
&lt;li&gt;Since &lt;code&gt;s&lt;/code&gt; still exists, Rust expects to be able to drop its memory normally when &lt;code&gt;s&lt;/code&gt; goes out of scope&lt;/li&gt;
&lt;li&gt;But &lt;code&gt;s&lt;/code&gt; has already been moved away, so Rust no longer knows how to drop it correctly, which triggers a &lt;strong&gt;compilation error&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The correct approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Replace the original value with an empty string&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// "Hello"&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// ""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1.10.3. Interior Mutability
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Some types provide interior mutability, which allows them to modify values through shared references.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These types usually rely on extra mechanisms — such as atomic CPU instructions — or on invariants to provide safe mutability without relying on the semantics of exclusive references.&lt;/p&gt;

&lt;p&gt;Interior mutability falls into two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Obtain a mutable reference through a shared reference: &lt;code&gt;Mutex&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;&lt;br&gt;
These types provide a guarantee: if a value is exposed through a mutable reference, then only one mutable reference will exist at the same time, and no shared references will exist alongside it. This capability relies on &lt;code&gt;UnsafeCell&lt;/code&gt;, the only correct way to modify a value through a shared reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace a value through a shared reference: &lt;code&gt;std::sync::atomic&lt;/code&gt;, &lt;code&gt;std::cell::Cell&lt;/code&gt;&lt;br&gt;
These types do not provide a mutable reference to the internal value, but they do provide methods for in-place operations on the value — for example, replacing or reading it. For instance, you cannot get a direct reference to a &lt;code&gt;usize&lt;/code&gt; or &lt;code&gt;i32&lt;/code&gt;, but you can read and replace the value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.10.4. The &lt;code&gt;Cell&lt;/code&gt; Type
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Cell&lt;/code&gt; comes from the standard library and provides interior mutability through invariants.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;Cell&lt;/code&gt; cannot be shared across threads, because its internal value is not meant to be modified concurrently, even when mutation happens through a shared reference&lt;/li&gt;
&lt;li&gt;It does not provide references to the value inside the &lt;code&gt;Cell&lt;/code&gt; (so the value can always be moved)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Methods provided by &lt;code&gt;Cell&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace the value as a whole, which is the so-called in-place operation&lt;/li&gt;
&lt;li&gt;Return a copy of the value, which is reading&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;set(value)&lt;/code&gt;: Replace the Value
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Create a `Cell` that stores 10&lt;/span&gt;

    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Replace the internal value&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Updated value: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Prints 20&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;set(value)&lt;/code&gt; replaces the value inside the &lt;code&gt;Cell&lt;/code&gt; with a &lt;strong&gt;new value&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;get()&lt;/code&gt;: Return a Copy of the Value
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Get a copy of the value inside `x`&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get()&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; return a reference to the internal value; it returns a &lt;strong&gt;copy of the value&lt;/strong&gt; (for types that implement the &lt;code&gt;Copy&lt;/code&gt; trait).&lt;/li&gt;
&lt;li&gt;It works for &lt;code&gt;i32&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, and other &lt;strong&gt;types that implement the &lt;code&gt;Copy&lt;/code&gt; trait&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.9. Ownership (Quick Recap) - Core Ideas of Ownership, How to Implement Copy Trait, Value Drop, and Drop Order</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Sat, 25 Jul 2026 20:33:21 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-19-ownership-quick-recap-core-ideas-of-ownership-how-to-implement-copy-2cpd</link>
      <guid>https://dev.to/someb1oody/advanced-rust-19-ownership-quick-recap-core-ideas-of-ownership-how-to-implement-copy-2cpd</guid>
      <description>&lt;h2&gt;
  
  
  1.9.1. The Core Idea of Ownership
&lt;/h2&gt;

&lt;p&gt;The core idea of Rust’s memory model is that &lt;strong&gt;every value has exactly one owner&lt;/strong&gt;. In other words, only one place — usually a scope — is responsible for freeing each value.&lt;/p&gt;

&lt;p&gt;This behavior is enforced by the borrow checker. If a value is moved — for example by assigning it to a new variable, pushing it into a &lt;code&gt;Vec&lt;/code&gt;, placing it on the heap, and so on — then the owner becomes the new location.&lt;/p&gt;

&lt;p&gt;The owner is really just a location in memory; the place where the data lives is the value’s owner. A move means the data is transferred from one location to another, and the new location becomes the owner.&lt;/p&gt;

&lt;p&gt;However, some types do not follow this rule: &lt;em&gt;if a value’s type implements the &lt;code&gt;Copy&lt;/code&gt; trait, then reassignment performs a copy rather than a move&lt;/em&gt;. That is, a copy of the value is placed in the new location.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.9.2. How to Implement the &lt;code&gt;Copy&lt;/code&gt; Trait
&lt;/h2&gt;

&lt;p&gt;Types that implement &lt;code&gt;Copy&lt;/code&gt; must be able to duplicate their values bit by bit.&lt;/p&gt;

&lt;p&gt;Types that cannot implement &lt;code&gt;Copy&lt;/code&gt; naturally include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types that contain non-&lt;code&gt;Copy&lt;/code&gt; types&lt;/li&gt;
&lt;li&gt;Types that must perform special resource-release work when their values are dropped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Imagine &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; implemented &lt;code&gt;Copy&lt;/code&gt;. If you assigned &lt;code&gt;box1 = box2&lt;/code&gt;, then both variables would believe they owned a heap allocation that belonged exclusively to them. When they went out of scope, both would try to free that memory, causing a &lt;em&gt;double free&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  1.9.3. Dropping Values
&lt;/h2&gt;

&lt;p&gt;When a value is no longer needed, its owner deletes it.&lt;/p&gt;

&lt;p&gt;Dropping — or discarding — a value happens when it goes out of scope. Types recursively drop the values they contain. For example, deleting a complex type can require deleting many values.&lt;/p&gt;

&lt;p&gt;Rust does not drop the same value more than once because of ownership. If a variable contains references to other values that it does not own, then deleting that variable does not delete the other values.&lt;/p&gt;

&lt;p&gt;That may be hard to understand, so let’s look at a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x1&lt;/code&gt; is an &lt;code&gt;i32&lt;/code&gt;, and &lt;code&gt;y1&lt;/code&gt; is a &lt;code&gt;Box&amp;lt;i32&amp;gt;&lt;/code&gt; that owns a heap allocation containing a &lt;em&gt;copy&lt;/em&gt; of &lt;code&gt;x1&lt;/code&gt;’s value (because &lt;code&gt;i32&lt;/code&gt; is &lt;code&gt;Copy&lt;/code&gt;, &lt;code&gt;Box::new(x1)&lt;/code&gt; does not borrow &lt;code&gt;x1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{}&lt;/code&gt; creates a new scope, and &lt;code&gt;z&lt;/code&gt; is created inside that smaller scope&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;z&lt;/code&gt; is a tuple whose value is &lt;code&gt;(x1, y1)&lt;/code&gt;. &lt;code&gt;x1&lt;/code&gt; is an &lt;code&gt;i32&lt;/code&gt; and implements &lt;code&gt;Copy&lt;/code&gt;, so &lt;code&gt;x1&lt;/code&gt; copies its value into &lt;code&gt;z&lt;/code&gt;; &lt;code&gt;y1&lt;/code&gt; is a &lt;code&gt;Box&amp;lt;i32&amp;gt;&lt;/code&gt; and does not implement &lt;code&gt;Copy&lt;/code&gt;, so it cannot be copied and instead transfers ownership to &lt;code&gt;z&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After leaving the inner scope, &lt;code&gt;x1&lt;/code&gt; is used again. &lt;code&gt;x1&lt;/code&gt; is still valid because it copied its value into &lt;code&gt;z&lt;/code&gt; and remains usable itself&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;y1&lt;/code&gt; becomes invalid after being assigned to &lt;code&gt;z&lt;/code&gt; because ownership moved to &lt;code&gt;z&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.9.4. The Order of Dropping Values
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Variables, including function parameters, are dropped in reverse order of declaration.&lt;/li&gt;
&lt;li&gt;Nested values are dropped in source order. In the example above, when the inner scope ends, &lt;code&gt;z&lt;/code&gt; is dropped: it first drops its first element (the copied &lt;code&gt;i32&lt;/code&gt;), then its second element (the &lt;code&gt;Box&lt;/code&gt;). Because &lt;code&gt;y1&lt;/code&gt; was moved into &lt;code&gt;z&lt;/code&gt;, &lt;code&gt;y1&lt;/code&gt; itself is not dropped again afterward.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: Rust does not currently allow self-referential values inside a single value.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.8. Memory Pt.6 - Scanning Address Space Through the Operating System</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Fri, 24 Jul 2026 17:51:58 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-18-memory-pt6-scanning-address-space-through-the-operating-system-nmo</link>
      <guid>https://dev.to/someb1oody/advanced-rust-18-memory-pt6-scanning-address-space-through-the-operating-system-nmo</guid>
      <description>&lt;h2&gt;
  
  
  1.8.1. Scan the Address Space Through the Operating System (Example)
&lt;/h2&gt;

&lt;p&gt;Operating systems provide interfaces that let programs make requests — &lt;em&gt;system calls&lt;/em&gt;. On Windows, &lt;code&gt;KERNEL32.DLL&lt;/code&gt; provides functions for &lt;em&gt;inspecting and manipulating the memory of running processes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This example is performed on Windows. Why use Windows as the example?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The function names are easy to understand&lt;/li&gt;
&lt;li&gt;No knowledge of the POSIX API is required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.8.2. Dependencies
&lt;/h2&gt;

&lt;p&gt;This example uses the &lt;a href="https://crates.io/crates/windows-sys" rel="noopener noreferrer"&gt;windows-sys&lt;/a&gt; crate, which provides low-level bindings to the Windows API. Add the following dependency to &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;windows-sys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.59.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_Foundation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_Memory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_ProcessStatus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_Threading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Here we use &lt;code&gt;windows-sys&lt;/code&gt; to call Windows APIs such as &lt;code&gt;GetCurrentProcess&lt;/code&gt;, &lt;code&gt;K32GetProcessMemoryInfo&lt;/code&gt;, and &lt;code&gt;VirtualQueryEx&lt;/code&gt;. Those modules are feature-gated, so the features above must be enabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.8.3. Main Program
&lt;/h2&gt;

&lt;p&gt;Then bring the required items into scope in &lt;code&gt;main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;VirtualQueryEx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ProcessStatus&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;K32GetProcessMemoryInfo&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Threading&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;GetCurrentProcess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// Windows `PVOID` / `SIZE_T` as used by the Win32 APIs.&lt;/span&gt;
&lt;span class="cd"&gt;/// In `windows-sys` 0.59+, these are expressed as raw Rust types rather than&lt;/span&gt;
&lt;span class="cd"&gt;/// named aliases under `Win32::Foundation`.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PVOID&lt;/code&gt;: Represents a &lt;code&gt;void*&lt;/code&gt; pointer, used to describe an opaque memory address. Here it is a local alias for &lt;code&gt;*mut c_void&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SIZE_T&lt;/code&gt;: Corresponds to an unsigned integer type used to represent the size of a memory region. Here it is a local alias for &lt;code&gt;usize&lt;/code&gt; (matching the &lt;code&gt;windows-sys&lt;/code&gt; 0.59+ signatures).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MEMORY_BASIC_INFORMATION&lt;/code&gt;: A built-in system structure used to describe the basic information of a memory region.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt;: A structure used to record a process’s memory usage.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;K32GetProcessMemoryInfo&lt;/code&gt;: This function retrieves memory information for the current process.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GetCurrentProcess&lt;/code&gt; and &lt;code&gt;GetCurrentProcessId&lt;/code&gt;: Retrieve the current process handle and process ID, respectively.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;For convenient &lt;code&gt;Debug&lt;/code&gt; output, we wrap the &lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt; returned by the Windows API in a custom &lt;code&gt;ProcessInfo&lt;/code&gt; structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ProcessInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;page_fault_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;cb&lt;/code&gt; (&lt;code&gt;u32&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The size of the structure in bytes.&lt;/li&gt;
&lt;li&gt;Purpose: Identifies the size of the structure for compatibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;page_fault_count&lt;/code&gt; (&lt;code&gt;u32&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The total number of page faults since the process started.&lt;/li&gt;
&lt;li&gt;Purpose: A page fault is the handling process triggered when a memory access misses physical memory. It includes soft faults (data obtained from the file cache) and hard faults (data loaded from disk).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;peak_working_set_size&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The peak size of the working set used by the process, meaning the memory currently resident in physical memory.&lt;/li&gt;
&lt;li&gt;Purpose: Used to monitor the process’s peak memory usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;working_set_size&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The current size of the process’s working set.&lt;/li&gt;
&lt;li&gt;Purpose: Shows how much physical memory the process is currently using.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;quota_peak_paged_pool_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The peak size of the process’s paged-pool quota usage.&lt;/li&gt;
&lt;li&gt;Purpose: The paged pool is kernel-mode memory that can be paged out to disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;quota_paged_pool_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The current size of the process’s paged-pool quota usage.&lt;/li&gt;
&lt;li&gt;Purpose: Used to monitor the amount of pageable kernel memory currently in use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;quota_peak_non_paged_pool_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The peak size of the process’s non-paged-pool quota usage.&lt;/li&gt;
&lt;li&gt;Purpose: The non-paged pool is kernel-mode memory that remains permanently resident in physical memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;quota_non_paged_pool_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The current size of the process’s non-paged-pool quota usage.&lt;/li&gt;
&lt;li&gt;Purpose: Used to monitor the amount of non-pageable kernel memory currently in use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;pagefile_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The current amount of space used by the process in the page file.&lt;/li&gt;
&lt;li&gt;Purpose: Indicates how much of the process’s data has been paged to disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;peak_pagefile_usage&lt;/code&gt; (&lt;code&gt;usize&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Description: The peak amount of page-file space used by the process.&lt;/li&gt;
&lt;li&gt;Purpose: Used to monitor the process’s page-file high-water mark.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;MEMORY_BASIC_INFORMATION&lt;/code&gt; from &lt;code&gt;windows-sys&lt;/code&gt; does not implement &lt;code&gt;Debug&lt;/code&gt;, so we also wrap its fields for printing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MemoryBasicInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;base_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allocation_base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allocation_protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Get the current process handle and process ID (these must go inside an &lt;code&gt;unsafe&lt;/code&gt; block):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;this_proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;this_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Retrieve process memory information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;zeroed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mem_counters_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;size_of&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;K32GetProcessMemoryInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_proc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem_counters_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let mut mem_counters: PROCESS_MEMORY_COUNTERS = mem::zeroed();&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;mem::zeroed()&lt;/code&gt; to create and initialize a &lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt; structure so that all of its fields are zero.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt; is a predefined Windows structure used to store process memory statistics.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let mem_counters_size = mem::size_of::&amp;lt;PROCESS_MEMORY_COUNTERS&amp;gt;() as u32;&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;mem::size_of&lt;/code&gt; to compute the size of the &lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt; structure in bytes.
&lt;/li&gt;
&lt;li&gt;Convert that size to &lt;code&gt;u32&lt;/code&gt;, which is then used as a parameter in the API call below.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;K32GetProcessMemoryInfo(this_proc, &amp;amp;mut mem_counters, mem_counters_size);&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parameter explanation:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;this_proc&lt;/code&gt;: The current process handle, indicating which process’s memory data you want to query.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;mut mem_counters&lt;/code&gt;: A mutable reference to the &lt;code&gt;PROCESS_MEMORY_COUNTERS&lt;/code&gt; structure, used to receive the memory statistics returned by the API.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mem_counters_size&lt;/code&gt;: The size of the structure, ensuring the API can correctly read and populate the structure data.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt;
Call &lt;code&gt;K32GetProcessMemoryInfo&lt;/code&gt; to fill &lt;code&gt;mem_counters&lt;/code&gt; with the current process’s memory state, such as the page-fault count, working-set size, and page-file usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Wrap the memory information in our custom &lt;code&gt;ProcessInfo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proc_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProcessInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;page_fault_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PageFaultCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PeakWorkingSetSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.WorkingSetSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPeakPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPeakNonPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaNonPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PagefileUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PeakPagefileUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Define the starting and ending addresses for the scan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Set a typical upper bound for a 64-bit user-mode address space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;max_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x00007FFF_FFFF_FFFF&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Print the process information and the address range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:p} @ {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this_pid&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;this_proc&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proc_info&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"min: {:p}, max: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Initialize the parameters required by &lt;code&gt;VirtualQueryEx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;MEMINFO_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;size_of&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;base_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;zeroed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let MEMINFO_SIZE = mem::size_of::&amp;lt;MEMORY_BASIC_INFORMATION&amp;gt;();&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Compute the size of &lt;code&gt;MEMORY_BASIC_INFORMATION&lt;/code&gt; in bytes and store it in &lt;code&gt;MEMINFO_SIZE&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reason:&lt;/strong&gt; The &lt;code&gt;VirtualQueryEx&lt;/code&gt; function requires the size of this structure buffer so it can write the query result correctly.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let mut base_addr: PVOID = min_addr;&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Initialize the starting address for the virtual-memory scan by setting the first scan address to &lt;code&gt;min_addr&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;base_addr&lt;/code&gt;:&lt;/strong&gt; Represents the starting address of the current query and will be incremented in the loop below to traverse the entire virtual address space.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let mut mem_info: MEMORY_BASIC_INFORMATION = mem::zeroed();&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Use &lt;code&gt;mem::zeroed()&lt;/code&gt; to create and initialize a &lt;code&gt;MEMORY_BASIC_INFORMATION&lt;/code&gt; structure, setting all fields to zero.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  - &lt;strong&gt;Reason:&lt;/strong&gt; This structure will store the result of &lt;code&gt;VirtualQueryEx&lt;/code&gt;, namely the detailed information of the memory region corresponding to the current query address.
&lt;/h2&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Scan the entire address space by calling &lt;code&gt;VirtualQueryEx&lt;/code&gt; in a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;VirtualQueryEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_proc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEMINFO_SIZE&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// `MEMORY_BASIC_INFORMATION` from `windows-sys` does not implement `Debug`,&lt;/span&gt;
    &lt;span class="c1"&gt;// so wrap the fields we care about for printing.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;printable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MemoryBasicInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;base_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.BaseAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;allocation_base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.AllocationBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;allocation_protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.AllocationProtect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;region_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.RegionSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.Protect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;printable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Add the size of the current region to get the next query address&lt;/span&gt;
    &lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.RegionSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1.8.4. Full Code
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;VirtualQueryEx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ProcessStatus&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;K32GetProcessMemoryInfo&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;windows_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Win32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Threading&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;GetCurrentProcess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// Windows `PVOID` / `SIZE_T` as used by the Win32 APIs.&lt;/span&gt;
&lt;span class="cd"&gt;/// In `windows-sys` 0.59+, these are expressed as raw Rust types rather than&lt;/span&gt;
&lt;span class="cd"&gt;/// named aliases under `Win32::Foundation`.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/// To allow Debug-formatted output, we wrap PROCESS_MEMORY_COUNTERS ourselves.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ProcessInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;page_fault_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_peak_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quota_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;peak_pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/// `MEMORY_BASIC_INFORMATION` from `windows-sys` does not implement `Debug`.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MemoryBasicInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;base_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allocation_base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allocation_protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the current process handle and process ID&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;this_proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;this_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Get process memory information&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;zeroed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mem_counters_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;size_of&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PROCESS_MEMORY_COUNTERS&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;K32GetProcessMemoryInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_proc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem_counters_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Wrap the memory information in our custom ProcessInfo&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proc_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProcessInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;page_fault_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PageFaultCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;peak_working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PeakWorkingSetSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;working_set_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.WorkingSetSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;quota_peak_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPeakPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;quota_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;quota_peak_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaPeakNonPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;quota_non_paged_pool_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.QuotaNonPagedPoolUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PagefileUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;peak_pagefile_usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_counters&lt;/span&gt;&lt;span class="py"&gt;.PeakPagefileUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Define the start and end addresses of the scan&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Set a typical upper bound for a 64-bit user-mode address space&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;max_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x00007FFF_FFFF_FFFF&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Print&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:p} @ {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this_pid&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;this_proc&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proc_info&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"min: {:p}, max: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Initialize the parameters required by VirtualQueryEx&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;MEMINFO_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;size_of&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;base_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MEMORY_BASIC_INFORMATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;zeroed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Loop over VirtualQueryEx to scan the entire address space&lt;/span&gt;
        &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="nf"&gt;VirtualQueryEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_proc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEMINFO_SIZE&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SIZE_T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;printable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MemoryBasicInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;base_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.BaseAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;allocation_base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.AllocationBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;allocation_protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.AllocationProtect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;region_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.RegionSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.Protect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;printable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// Add the size of the current region to get the next query address&lt;/span&gt;
            &lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;mem_info&lt;/span&gt;&lt;span class="py"&gt;.RegionSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PVOID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[package]&lt;/span&gt;  
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"RustStudy"&lt;/span&gt;  
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;  
&lt;span class="py"&gt;edition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2021"&lt;/span&gt;  

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
&lt;span class="py"&gt;windows-sys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.59.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_Foundation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_Memory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_ProcessStatus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Win32_System_Threading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1.8.5. Steps for Reading and Writing Process Memory
&lt;/h2&gt;

&lt;p&gt;The logic for reading and writing process memory is fairly simple. Pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_process_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;OpenProcess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;VirtualQueryEx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;reach&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;

    &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;ReadProcessMemory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
    &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;

    &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;WriteProcessMemory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;need&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;let pid = some_process_id;&lt;/code&gt;: Get the current process ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OpenProcess(pid);&lt;/code&gt;: Open this process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linux provides simple APIs: &lt;code&gt;process_vm_readv()&lt;/code&gt; and &lt;code&gt;process_vm_writev()&lt;/code&gt;, which correspond to &lt;code&gt;ReadProcessMemory()&lt;/code&gt; and &lt;code&gt;WriteProcessMemory()&lt;/code&gt; on Windows.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Advanced Rust] 1.7. Memory Part 5 - Heap vs. Stack Memory, Virtual Memory, and Guidelines for Displaying Data in RAM</title>
      <dc:creator>SomeB1oody</dc:creator>
      <pubDate>Fri, 24 Jul 2026 17:49:02 +0000</pubDate>
      <link>https://dev.to/someb1oody/advanced-rust-17-memory-part-5-heap-vs-stack-memory-virtual-memory-and-guidelines-for-10fn</link>
      <guid>https://dev.to/someb1oody/advanced-rust-17-memory-part-5-heap-vs-stack-memory-virtual-memory-and-guidelines-for-10fn</guid>
      <description>&lt;h2&gt;
  
  
  1.7.1. Dynamic Memory Allocation
&lt;/h2&gt;

&lt;p&gt;At any given moment, a running program occupies part of memory. &lt;em&gt;Sometimes the program needs more memory, so it must request it from the operating system; this is called dynamic allocation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The following diagram shows the steps of dynamic memory allocation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywls04h5caytxfhl3dl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywls04h5caytxfhl3dl2.png" alt="steps of dynamic memory allocation" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The program requests memory from the system through the allocator interface. On Unix-like systems this is typically done with &lt;code&gt;malloc()&lt;/code&gt;/&lt;code&gt;free()&lt;/code&gt;, and on Windows with &lt;code&gt;HeapAlloc()&lt;/code&gt;/&lt;code&gt;HeapFree()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The program uses the allocated memory.&lt;/li&gt;
&lt;li&gt;If the memory is no longer needed after use, the program releases it back to the operating system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;PS: there is an **allocator&lt;/em&gt;* between the program and the system when memory is requested. It is a specialized subroutine hidden behind the scenes of the program, and it performs some optimizations to avoid a large amount of work for the CPU and the operating system.*&lt;/p&gt;

&lt;h2&gt;
  
  
  1.7.2. Why Is There a Performance Difference Between Stack Memory and Heap Memory?
&lt;/h2&gt;

&lt;p&gt;First of all, it should be made clear that &lt;em&gt;stack memory and heap memory are only concepts; physically, memory does not contain these two separate regions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The reason stack memory is fast is that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local variables of functions (all allocated on the stack) are adjacent to one another in RAM (&lt;em&gt;contiguous layout&lt;/em&gt;). A contiguous layout is very cache-friendly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason heap memory is slower is that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data allocated on the heap is unlikely to be adjacent to one another.&lt;/li&gt;
&lt;li&gt;Accessing data on the heap requires &lt;em&gt;dereferencing&lt;/em&gt; a pointer (which involves page-table lookups and then accessing main memory).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A Simple Comparison Between Stack and Heap
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;Heap&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe&lt;/td&gt;
&lt;td&gt;Dangerous&lt;/td&gt;
&lt;td&gt;Dangerous here means Unsafe Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rigid&lt;/td&gt;
&lt;td&gt;Flexible&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Data structures on the stack cannot change size during their lifetime.&lt;/li&gt;
&lt;li&gt;Data structures on the heap are more flexible because the pointer can change.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.7.3. Virtual Memory
&lt;/h2&gt;

&lt;p&gt;Virtual memory is the memory view seen by a program. All data that a program can access is provided by the operating system within its address space.&lt;/p&gt;

&lt;p&gt;Intuitively, a program’s memory is a sequence of bytes, from a starting position &lt;code&gt;0&lt;/code&gt; to an ending position &lt;code&gt;n&lt;/code&gt;. For example, if a program reports that it uses 100 KB of RAM, then &lt;code&gt;n&lt;/code&gt; would be around 100000.&lt;/p&gt;

&lt;p&gt;Let’s look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;n_nonzero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;byte_at_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;byte_at_addr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;n_nonzero&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_nonzero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This example scans the memory of the running program byte by byte, starting at position &lt;code&gt;0&lt;/code&gt; and ending at &lt;code&gt;9999&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;let ptr = i as *const u8;&lt;/code&gt; converts &lt;code&gt;i&lt;/code&gt; into an immutable raw pointer of type &lt;code&gt;*const u8&lt;/code&gt; (a &lt;code&gt;u8&lt;/code&gt; occupies one byte) so that the memory address can be checked. Here, we treat each address as one unit. In reality, many values occupy more than one byte and span multiple bytes, but we will ignore that here.&lt;/li&gt;
&lt;li&gt;The next line, &lt;code&gt;let byte_at_addr = unsafe { *ptr };&lt;/code&gt;, dereferences the pointer (operations on raw pointers must be placed inside an &lt;code&gt;unsafe&lt;/code&gt; block) and reads the value into &lt;code&gt;byte_at_addr&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;byte_at_addr&lt;/code&gt; is not &lt;code&gt;0&lt;/code&gt;, then &lt;code&gt;n_nonzero&lt;/code&gt; increases by 1.&lt;/li&gt;
&lt;li&gt;Finally, the value of &lt;code&gt;n_nonzero&lt;/code&gt; is printed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;segmentation fault
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;segmentation fault&lt;/code&gt; means an error that occurs when the CPU or operating system detects that a program is trying to access an illegal (unauthorized) memory address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A segment refers to a block in virtual memory. Virtual memory is divided into blocks to minimize the space needed for translating between virtual and physical addresses.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So which memory access is illegal? Address &lt;code&gt;0&lt;/code&gt;. When &lt;code&gt;i&lt;/code&gt; equals &lt;code&gt;0&lt;/code&gt;, it is effectively a null pointer, and a null pointer cannot be dereferenced. This also partly explains why raw pointer operations must be placed inside an &lt;code&gt;unsafe&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;Let’s start the loop from &lt;code&gt;1&lt;/code&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;n_nonzero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;byte_at_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;byte_at_addr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;n_nonzero&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_nonzero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;segmentation fault
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same error.&lt;/p&gt;

&lt;p&gt;This example does not work, so let’s switch to another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GLOBAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;noop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;noop_local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;noop_local&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;local_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;local_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;boxed_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;boxed_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;789&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fn_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;noop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GLOBAL:    {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GLOBAL&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"local_str: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_str&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"local_int: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;local_int&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"boxed_int: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;into_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxed_int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"boxed_str: {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;into_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxed_str&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fn_int:    {:p}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn_int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We declare variables such as &lt;code&gt;GLOBAL&lt;/code&gt;, &lt;code&gt;local_str&lt;/code&gt;, and &lt;code&gt;local_int&lt;/code&gt; (static variables also count as variables). Some are stored on the heap, and some are stored on the stack.&lt;/li&gt;
&lt;li&gt;We print their memory addresses.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;local_str.as_ptr()&lt;/code&gt; prints the address of the string data. Prefer that over &lt;code&gt;local_str as *const str&lt;/code&gt; with &lt;code&gt;{:p}&lt;/code&gt;: a &lt;code&gt;*const str&lt;/code&gt; is a wide pointer, and current Rust formats it as &lt;code&gt;Pointer { addr: ..., metadata: ... }&lt;/code&gt; rather than a bare hex address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GLOBAL:    0x102572ae4
local_str: 0x102572ae0
local_int: 0x16d8c260c
boxed_int: 0x102d89b10
boxed_str: 0x102d89c10
fn_int:    0x16d8c2620
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although our program is very small, the distribution of variables in virtual memory is quite scattered. Still, there is some pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The addresses of &lt;code&gt;GLOBAL&lt;/code&gt; and &lt;code&gt;local_str&lt;/code&gt; are relatively close.&lt;/li&gt;
&lt;li&gt;The addresses of &lt;code&gt;boxed_int&lt;/code&gt; and &lt;code&gt;boxed_str&lt;/code&gt; are relatively close.&lt;/li&gt;
&lt;li&gt;The addresses of &lt;code&gt;local_int&lt;/code&gt; and &lt;code&gt;fn_int&lt;/code&gt; are relatively close.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The size of virtual memory is roughly &lt;code&gt;2^48&lt;/code&gt;, but physical memory is certainly not that large. In addition, part of the virtual address space is reserved by the system for itself, and those reserved addresses cannot be used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Through the Example
&lt;/h3&gt;

&lt;p&gt;From these examples, we can learn a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some memory addresses are illegal. If you access out-of-bounds memory, the program will be terminated.&lt;/li&gt;
&lt;li&gt;Memory addresses are not random. Although values of different types appear to be widely distributed in memory, there is actually a pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.7.4. Translating Virtual Addresses to Physical Addresses
&lt;/h2&gt;

&lt;p&gt;Accessing data in a program requires virtual addresses (a program can only access virtual addresses). Virtual addresses are translated into physical addresses, which involves the program, the operating system, the CPU, and RAM hardware (and sometimes hard disks and other devices as well):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CPU is responsible for the translation; more specifically, the &lt;em&gt;Memory Management Unit (MMU)&lt;/em&gt; inside the CPU performs this work.&lt;/li&gt;
&lt;li&gt;The operating system is responsible for storing instructions.&lt;/li&gt;
&lt;li&gt;These instructions also exist at predefined addresses in memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the worst case, every memory access triggers two memory lookups: one for the memory being accessed and one for the instructions.&lt;/p&gt;

&lt;p&gt;The CPU maintains a cache of recently translated addresses. It has its own fast memory to accelerate memory access. For historical reasons, this memory is called the &lt;em&gt;Translation Lookaside Buffer (TLB)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To improve performance, programmers need to keep data structures compact and avoid deep nesting.&lt;/strong&gt; This becomes especially important once the TLB capacity is reached (for x86 processors, roughly 100 &lt;em&gt;pages&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Let’s define the terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page: a fixed-size block of bytes in physical memory; on 64-bit systems it is usually 4 KB.&lt;/li&gt;
&lt;li&gt;Word: any value whose size is the size of a pointer, i.e. the width of a CPU register. In Rust, &lt;code&gt;usize&lt;/code&gt; and &lt;code&gt;isize&lt;/code&gt; are &lt;em&gt;word-length types&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Virtual addresses are divided into many blocks called &lt;em&gt;pages&lt;/em&gt;, usually 4 KB each. Dividing memory into blocks helps avoid storing a translation mapping for every variable. In addition, pages have a uniform size, which helps avoid &lt;em&gt;memory fragmentation (empty, unusable spaces appearing in available RAM)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: the above is only a general guideline; situations such as microcontrollers are different.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.7.5. Practical Guidelines for Displaying Data in RAM
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keep the hot part of your program within 4 KB&lt;/strong&gt; so that lookups stay fast and performance remains good. Many programs cannot keep their hot working set within &lt;em&gt;4 KB&lt;/em&gt;, and for such programs the &lt;em&gt;4 KB&lt;/em&gt; target is unrealistic. In that case, &lt;strong&gt;the next target should be 4 KB × 100&lt;/strong&gt;. This means the CPU’s &lt;em&gt;translation cache (TLB)&lt;/em&gt; can still support your program.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Avoid deeply nested data structures.&lt;/strong&gt; If a pointer points to another page, performance will be affected.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;When traversing arrays, the access order affects cache utilization (because the CPU reads small blocks of bytes from RAM, called a cache line), which in turn affects program performance.&lt;/strong&gt; Two-dimensional arrays in C/C++, Rust, Python (NumPy), and similar languages are &lt;strong&gt;stored in row-major order&lt;/strong&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The layout in memory is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1  2  3  |  4  5  6  |  7  8  9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use &lt;strong&gt;row-major traversal&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;matrix[i][j]&lt;/code&gt; is &lt;strong&gt;contiguous&lt;/strong&gt; in memory, which makes good use of &lt;strong&gt;cache lines&lt;/strong&gt;, reduces RAM access, and improves speed.&lt;/p&gt;

&lt;p&gt;If you use &lt;strong&gt;column-major traversal&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;strong&gt;columns are scattered in memory&lt;/strong&gt;, accessing &lt;code&gt;matrix[i][j]&lt;/code&gt; may cross multiple &lt;strong&gt;cache lines&lt;/strong&gt;. The CPU may frequently &lt;strong&gt;load new cache lines from RAM&lt;/strong&gt;, causing &lt;strong&gt;cache misses&lt;/strong&gt; and hurting performance.&lt;/p&gt;

&lt;p&gt;To summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In languages such as C/C++, Rust, and Python (NumPy) that &lt;strong&gt;use row-major order by default&lt;/strong&gt;, try to traverse arrays by row.&lt;/li&gt;
&lt;li&gt;In languages such as MATLAB and Fortran that &lt;strong&gt;use column-major order&lt;/strong&gt;, traversing by column is more efficient.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Note:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Virtualization makes things even worse.&lt;/strong&gt; If you run an application inside a virtual machine, the &lt;em&gt;hypervisor&lt;/em&gt; must also translate addresses for the guest operating system. That is why many CPUs include hardware virtualization support — to reduce overhead by reducing the amount of translation work.&lt;/p&gt;

&lt;p&gt;If you run containers inside a virtual machine, you add yet another layer of indirection, which also increases latency.&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;if you want bare-metal performance, you have to run the program on bare metal&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
