Box Is a Unique Type
2022-07-23
+nilstriebs blog
diff --git a/index.xml b/index.xml
index ee81ea0..bdd451f 100644
--- a/index.xml
+++ b/index.xml
@@ -1,4 +1,167 @@
-nilstriebs blog /Recent content on nilstriebs blog Hugo -- gohugo.io en-us Sat, 23 Jul 2022 00:00:00 +0000 Box Is a Unique Type /posts/box-is-a-unique-type/Sat, 23 Jul 2022 00:00:00 +0000 /posts/box-is-a-unique-type/ We have all used Box<T> before in our Rust code. It’s a glorious type, with great ergonomics and flexibility. We can use it to put our values on the heap, but it can do even more than that!
+nilstriebs blog /Recent content on nilstriebs blog Hugo -- gohugo.io en-us Fri, 17 Mar 2023 00:00:00 +0000 Item Patterns And Struct Else /posts/item-patterns-and-struct-else/Fri, 17 Mar 2023 00:00:00 +0000 /posts/item-patterns-and-struct-else/ Pattern matching One of my favourite features of Rust is pattern matching. It’s a simple and elegant way to deal with not just structs, but also enums!
+enum ItemKind { Struct(String, Vec<Field>), Function(String, Body), } impl ItemKind { fn name(&self) -> &str { match self { Self::Struct(name, _) => name, Self::Function(name, _) => name, } } } Here, we have an enum and a function to get the name out of this. <h1 id="pattern-matching">Pattern matching</h1>
+<p>One of my favourite features of Rust is pattern matching. It’s a simple and elegant way to deal with not just structs, but also enums!</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">enum</span> <span style="color:#a6e22e">ItemKind</span> {
+</span></span><span style="display:flex;"><span> Struct(String, Vec<span style="color:#f92672"><</span>Field<span style="color:#f92672">></span>),
+</span></span><span style="display:flex;"><span> Function(String, Body),
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> ItemKind {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">name</span>(<span style="color:#f92672">&</span>self) -> <span style="color:#66d9ef">&</span><span style="color:#66d9ef">str</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">match</span> self {
+</span></span><span style="display:flex;"><span> Self::Struct(name, _) <span style="color:#f92672">=></span> name,
+</span></span><span style="display:flex;"><span> Self::Function(name, _) <span style="color:#f92672">=></span> name,
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>Here, we have an enum and a function to get the name out of this. In C, this would be very unsafe, as we cannot be guaranteed that our union has the right tag.
+But in Rust, the compiler nicely checks it all for us. It’s safe and expressive (just like many other features of Rust).</p>
+<p>But that isn’t the only way to use pattern matching. While branching is one of its core features (in that sense, pattern matching is just like git),
+it doesn’t always have to be used. Another major advantage of pattern matching lies in the ability to <em>exhaustively</em> (not be be confused with exhausting, like writing down brilliant ideas like this) match over inputs.</p>
+<p>Let’s look at the following example. Here, we have a struct representing a struct in a programming language. It has a name and fields.
+We then manually implement a custom hash trait for it because we are important and need a custom hash trait. We could have written a derive macro, but didn’t because
+we don’t understand how proc macros work.</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Struct</span> {
+</span></span><span style="display:flex;"><span> name: String,
+</span></span><span style="display:flex;"><span> fields: Vec<span style="color:#f92672"><</span>Field<span style="color:#f92672">></span>,
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> HandRolledHash <span style="color:#66d9ef">for</span> Struct {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">hash</span>(<span style="color:#f92672">&</span>self, hasher: <span style="color:#66d9ef">&</span><span style="color:#a6e22e">mut</span> HandRolledHasher) {
+</span></span><span style="display:flex;"><span> hasher.hash(<span style="color:#f92672">&</span>self.name);
+</span></span><span style="display:flex;"><span> hasher.hash(<span style="color:#f92672">&</span>self.fields);
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>This works perfectly. But then later, <a href="https://github.com/rust-lang/rustup/pull/1642">we add privacy to the language</a>. Now, all types have a visibility.</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span>struct Struct {
+</span></span><span style="display:flex;"><span><span style="color:#a6e22e">+ visibility: Vis,
+</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e"></span> name: String,
+</span></span><span style="display:flex;"><span> fields: Vec<Field>,
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>Pretty cool. Now no one can access the implementation details and make everything a mess. But wait - we have just made a mess! We didn’t hash the visibility!
+Hashing something incorrectly <a href="https://github.com/rust-lang/rust/issues/84970">doesn’t sound too bad</a>, but it would be nice if this was prevented.</p>
+<p>Thanks to exhaustive pattern matching, it would have been easy to prevent. We just change our hash implementation:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> HandRolledHash <span style="color:#66d9ef">for</span> Struct {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">hash</span>(<span style="color:#f92672">&</span>self, hasher: <span style="color:#66d9ef">&</span><span style="color:#a6e22e">mut</span> HandRolledHasher) {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> Self { name, fields } <span style="color:#f92672">=</span> self;
+</span></span><span style="display:flex;"><span> hasher.hash(name);
+</span></span><span style="display:flex;"><span> hasher.hash(fields);
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>And with this, adding the visibility will cause a compiler error and alert us that we need to handle it in hashing.
+(The decision whether we actually do want to handle it is still up to us. We could also just turn off the computer and make new friends outside.)</p>
+<p>We can conclude that pattern matching is a great feature.</p>
+<h1 id="limitations-of-pattern-matching">Limitations of pattern matching</h1>
+<p>But there is one big limitation of pattern matching - all of its occurrences (<code>match</code>, <code>if let</code>, <code>if let</code> chains, <code>while let</code>, <code>while let</code> chains, <code>for</code>, <code>let</code>, <code>let else</code>, and function parameters
+(we do have a lot of pattern matching)) are inside of bodies, mostly as part of expressions or statements.</p>
+<p>This doesn’t sound too bad. This is where the executed code resides. But it comes at a cost of consistency. We often add many syntactical niceties to expressions and statements, but forget about items.</p>
+<h1 id="items-and-sadness">Items and sadness</h1>
+<p>Items have a hard life. They are the parents of everything important. <code>struct</code>, <code>enum</code>, <code>const</code>, <code>mod</code>, <code>fn</code>, <code>union</code>, <code>global_asm</code> are all things we use daily, yet their grammar is very limited. (“free the items” was an alternative blog post title, although “freeing” generally remains a concern of <a href="https://nilstrieb.github.io/nilstrieb-c-style-guide-edition-2/">my C style guide</a>).</p>
+<p>For example, see the following code where we declare a few constants.</p>
+<pre tabindex="0"><code>const ONE: u8 = 1;
+const TWO: u8 = 1;
+const THREE: u8 = 3;
+</code></pre><p>There is nothing obviously wrong with this code. You understand it, I understand it, an ALGOL 68 developer from 1970 would probably understand it
+and even an ancient greek philosopher might have a clue (which is impressive, given that they are all not alive anymore). But this is the kind of code that pages you at 4 AM.</p>
+<p>You’ve read the last paragraph in confusion. Of course there’s something wrong with this code! <code>TWO</code> is <code>1</code>, yet the name strongly suggests that it should be <code>2</code>. And you’d
+be right, this was just a check to make sure you’re still here. You are very clever and deserve this post. If you didn’t notice it, go to sleep. It’s good for your health.</p>
+<p>But even if it was <code>2</code>, this code is still not good. There is way too much duplication! <code>const</code> is mentioned three times. This is a major distraction to the reader.</p>
+<p>Let’s have a harder example:</p>
+<pre tabindex="0"><code>const ONE: u8 = 0; const
+NAME: &
+str = "nils";
+const X: &str
+= "const";const A: () = ();
+</code></pre><p>Here, the <code>const</code> being noise is a lot more obvious. Did you see that <code>X</code> contains <code>"const"</code>? Maybe you did, maybe you didn’t. When I tested it, 0/0 people could see it.</p>
+<p>Now imagine if it looked like this:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (<span style="color:#66d9ef">ONE</span>, <span style="color:#66d9ef">NAME</span>, X, A): (<span style="color:#66d9ef">u8</span>, <span style="color:#f92672">&</span><span style="color:#66d9ef">str</span>, <span style="color:#f92672">&</span><span style="color:#66d9ef">str</span>, ()) <span style="color:#f92672">=</span> (<span style="color:#ae81ff">0</span>, <span style="color:#e6db74">"nils"</span>, <span style="color:#e6db74">"const"</span>, ());
+</span></span></code></pre></div><p>Everything is way shorter and more readable.</p>
+<p>What you’ve just seen is a limited form of pattern matching!</p>
+<h1 id="lets-go-further">Let’s go further</h1>
+<p>The idea of generalizing pattern matching is very powerful. We can apply this to more than just consts.</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> (Person, Car) <span style="color:#f92672">=</span> ({ name: String }, { wheels: <span style="color:#66d9ef">u8</span> });
+</span></span></code></pre></div><p>Here, we create two structs with just a single <code>struct</code> keyword. This makes it way simpler and easier to read when related structs are declared.
+So far we’ve just used tuples. But we can go even further. Structs of structs!</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Household</span><span style="color:#f92672"><</span>T, U<span style="color:#f92672">></span> {
+</span></span><span style="display:flex;"><span> parent: <span style="color:#a6e22e">T</span>,
+</span></span><span style="display:flex;"><span> child: <span style="color:#a6e22e">U</span>,
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Household</span> { parent: <span style="color:#a6e22e">Ferris</span>, child: <span style="color:#a6e22e">Corro</span> } <span style="color:#f92672">=</span> Household {
+</span></span><span style="display:flex;"><span> parent: { name: String },
+</span></span><span style="display:flex;"><span> child: { name: String, unsafety: <span style="color:#66d9ef">bool</span> },
+</span></span><span style="display:flex;"><span>};
+</span></span></code></pre></div><p>Now we can nicely match on the <code>Household</code> struct containing the definition of the <code>Ferris</code> and <code>Corro</code> structs. This is equivalent to the following code:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Feris</span> {
+</span></span><span style="display:flex;"><span> name: String,
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Corro</span> {
+</span></span><span style="display:flex;"><span> name: String,
+</span></span><span style="display:flex;"><span> unsafety: <span style="color:#66d9ef">bool</span>,
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>This is already really neat, but there’s more. We also have to consider the falliblity of patterns.</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> Some(A) <span style="color:#f92672">=</span> None;
+</span></span></code></pre></div><p>This pattern doesn’t match. Inside bodies, we could use an <code>if let</code>:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">let</span> Some(a) <span style="color:#f92672">=</span> None {} <span style="color:#66d9ef">else</span> {}
+</span></span></code></pre></div><p>We can also apply this to items.</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#66d9ef">struct</span> Some(A) <span style="color:#f92672">=</span> None {
+</span></span><span style="display:flex;"><span> <span style="color:#75715e">/* other items where A exists */</span>
+</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">else</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#75715e">/* other items where A doesn't exist */</span>
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>This doesn’t sound too useful, but it allows for extreme flexibility!</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span>macro_rules<span style="color:#f92672">!</span> are_same_type {
+</span></span><span style="display:flex;"><span> (<span style="color:#75715e">$a</span>:<span style="color:#a6e22e">ty</span>, <span style="color:#75715e">$b</span>:<span style="color:#a6e22e">ty</span>) <span style="color:#f92672">=></span> {{
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">mut</span> <span style="color:#66d9ef">ARE_SAME</span>: <span style="color:#66d9ef">bool</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">struct</span> <span style="color:#75715e">$a</span> <span style="color:#f92672">=</span> <span style="color:#75715e">$b</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> _: () <span style="color:#f92672">=</span> <span style="color:#66d9ef">unsafe</span> { <span style="color:#66d9ef">ARE_SAME</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>; };
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">unsafe</span> { <span style="color:#66d9ef">ARE_SAME</span> }
+</span></span><span style="display:flex;"><span> }};
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> are_same_type!(Vec<span style="color:#f92672"><</span>String<span style="color:#f92672">></span>, String) {
+</span></span><span style="display:flex;"><span> println!(<span style="color:#e6db74">"impossible to reach!"</span>);
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>}
+</span></span></code></pre></div><p>Ignoring this suspicious assignment to a <code>static mut</code>, this is lovely!</p>
+<p>We can go further.</p>
+<p>Today, items are just there with no ordering. What if we imposed an ordering? (and just like this, the C11 atomic model was born.) What if “Rust items” was a meta scripting language?</p>
+<p>We can write a simple guessing game!</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">fn</span> input() -> <span style="color:#66d9ef">u8</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">INPUT</span>: <span style="color:#66d9ef">&</span><span style="color:#66d9ef">str</span> <span style="color:#f92672">=</span> prompt!();
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> Ok(<span style="color:#66d9ef">INPUT</span>): Result<span style="color:#f92672"><</span><span style="color:#66d9ef">u8</span>, ParseIntErr<span style="color:#f92672">></span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">INPUT</span>.parse() <span style="color:#66d9ef">else</span> {
+</span></span><span style="display:flex;"><span> compile_error!(<span style="color:#e6db74">"Invalid input"</span>);
+</span></span><span style="display:flex;"><span> };
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">INPUT</span>
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">RANDOM</span>: <span style="color:#66d9ef">u8</span> <span style="color:#f92672">=</span> env!(<span style="color:#e6db74">"RANDOM"</span>);
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">loop</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">INPUT</span> <span style="color:#f92672">=</span> input();
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">INPUT</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">RANDOM</span> {
+</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">break</span>; <span style="color:#75715e">// continue compilation
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">INPUT</span> <span style="color:#f92672"><</span> <span style="color:#66d9ef">RANDOM</span> {
+</span></span><span style="display:flex;"><span> compile_warn!(<span style="color:#e6db74">"input is smaller"</span>);
+</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> {
+</span></span><span style="display:flex;"><span> compile_warn!(<span style="color:#e6db74">"input is bigger"</span>);
+</span></span><span style="display:flex;"><span> }
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
+</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Empty. I am useless. I strike!
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
+</span></span></code></pre></div><p>If it weren’t for <code>fn main</code> starting a strike and stopping compilation, this would have worked! Quite bold of <code>fn main</code> to just start a strike, even though there’s no <code>union</code> in the entire program. But we really need it, it’s not a disposable worker.</p>
+<p>And then, last and least I want to highlight one of my favourite consequences of this: <code>struct else</code></p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> Some(Test) <span style="color:#f92672">=</span> None <span style="color:#66d9ef">else</span> {
+</span></span><span style="display:flex;"><span> compile_error!(<span style="color:#e6db74">"didn't match pattern"</span>);
+</span></span><span style="display:flex;"><span>};
+</span></span></code></pre></div><p><!-- raw HTML omitted -->you’re asking yourself what you just read. meanwhile, i am asking myself what i just wrote. we are very similar.<!-- raw HTML omitted --></p> Box Is a Unique Type /posts/box-is-a-unique-type/Sat, 23 Jul 2022 00:00:00 +0000 /posts/box-is-a-unique-type/ We have all used Box<T> before in our Rust code. It’s a glorious type, with great ergonomics and flexibility. We can use it to put our values on the heap, but it can do even more than that!
struct Fields { a: String, b: String, } let fields = Box::new(Fields { a: "a".to_string(), b: "b".to_string() }); let a = fields.a; let b = fields.b; This kind of partial deref move is just one of the spectacular magic tricks box has up its sleeve, and they exist for good reason: They are very useful. <p>We have all used <code>Box<T></code> before in our Rust code. It’s a glorious type, with great ergonomics
and flexibility. We can use it to put our values on the heap, but it can do even more
than that!</p>
diff --git a/posts/box-is-a-unique-type/index.html b/posts/box-is-a-unique-type/index.html
index 3cf62de..a8cf790 100644
--- a/posts/box-is-a-unique-type/index.html
+++ b/posts/box-is-a-unique-type/index.html
@@ -131,6 +131,7 @@ are very strong, and still giving code an option to obtain these seems useful. O
Item Patterns And Struct Else
2023-03-17
+:: Nilstrieb
#rust
+#language-design Bringing more expressiveness to our items
Box Is a Unique Type
2022-07-23
:: Nilstrieb
#rust
#unsafe code About better aliasing semantics for
Box<T>&'static mut T that is unleaked for drop, but the semantics of this are still unclear.
If that is not possible, exposing std::ptr::Unique (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of Unique
inside the standard library would have to be removed. We could also offer a std::boxed::UniqueBox that keeps the current semantics, but this would also bring direct aliasing
-decisions more towards safe code, which I am not a huge fan of. Ownership is enough already.I guess what I am wishing for are some good and flexible raw pointer types. But that’s still in the stars…
For more information about this topic, see https://github.com/rust-lang/unsafe-code-guidelines/issues/326
Thanks to the nice people on the Rust Community Discord for their feedback on the draft of this post!