This commit is contained in:
Nilstrieb 2022-07-23 15:26:03 +00:00
parent 3a526b579c
commit 4d6197c1aa
5 changed files with 132 additions and 92 deletions

View file

@ -56,8 +56,9 @@ and at least one of them is <code>noalias</code>, there are some restricti
<li>If one of them writes, they must not point to the same value (alias each other)</li> <li>If one of them writes, they must not point to the same value (alias each other)</li>
<li>If neither of them writes, they can alias just fine. <li>If neither of them writes, they can alias just fine.
Therefore, we also apply <code>noalias</code> to <code>&mut T</code> and <code>&T</code> (if it doesn’t contain interior mutability through Therefore, we also apply <code>noalias</code> to <code>&mut T</code> and <code>&T</code> (if it doesn’t contain interior mutability through
<code>UnsafeCell<T></code>, since they uphold these rules.</li> <code>UnsafeCell<T></code>), since they uphold these rules.</li>
</ul> </ul>
<p>For more info on <code>noalias</code>, see <a href="https://llvm.org/docs/LangRef.html#parameter-attributes">LLVMs LangRef</a>.</p>
<p>This might sound familiar to you if you’re a viewer of <a href="https://twitter.com/jonhoo">Jon Gjengset</a>’s content (which I can highly recommend). Jon has made an entire video about this before, since his crate <code>left-right</code> <p>This might sound familiar to you if you’re a viewer of <a href="https://twitter.com/jonhoo">Jon Gjengset</a>’s content (which I can highly recommend). Jon has made an entire video about this before, since his crate <code>left-right</code>
was affected by this (<a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)</a>.</p> was affected by this (<a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)</a>.</p>
<p>If you’re looking for <em>any</em> hint that using box emits <code>noalias</code>, you have to look no further than the documentation <p>If you’re looking for <em>any</em> hint that using box emits <code>noalias</code>, you have to look no further than the documentation
@ -66,13 +67,13 @@ belong to the arcane circles of the select few who were aware of it. So lots of
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.</p> pointers are concerned.</p>
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1> <h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
<p>TODO: introduce UB by explaining how it allows optimizations like the one above, don’t talk in standardese</p> <p>So, LLVM was completely correct in optimizing our code to make the assert fail. But what exactly gave it permission to do so?
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour. Undefined Behaviour (UB for short). Undefined behaviour is at the root of many modern compiler optimizations. But what is undefined behaviour?
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed, UB represents a contract between the program and the compiler. The compiler assumes that UB will not happen, and can therefore optimize based
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly on these assumptions. Examples of UB also include use-after-free, out of bounds reads or data races. If UB is executed, <em>anything</em> can happen,
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.</p> including segmentation faults, silent memory corruption, leakage of private keys or exactly what you intended to happen.</p>
<p>I cannot recommend Miri highly enough for all unsafe code you’re writing (sadly support for some IO functions <p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour in Rust. I cannot recommend Miri
and FFI is still lacking, and it’s still very slow).</p> highly enough for all unsafe code you’re writing (sadly support for some IO functions and FFI is still lacking, and it’s still very slow).</p>
<p>So, let’s see whether our code contains UB. It has to, since otherwise the optimizer wouldn’t be allowed to change <p>So, let’s see whether our code contains UB. It has to, since otherwise the optimizer wouldn’t be allowed to change
observable behaviour (since the assert doesn’t fail in debug mode). <code>$ cargo miri run</code>…</p> observable behaviour (since the assert doesn’t fail in debug mode). <code>$ cargo miri run</code>…</p>
<pre tabindex="0"><code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using <3314> at alloc1722[0x0], but that tag does not exist in the borrow stack for this location <pre tabindex="0"><code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using <3314> at alloc1722[0x0], but that tag does not exist in the borrow stack for this location
@ -137,29 +138,36 @@ other box-exclusive features it offers. Even worse is <code>string_cache</
<p>Then last but not least, there’s the opinionated fact that <code>Box<T></code> shall be implementable entirely in user code. While we are <p>Then last but not least, there’s the opinionated fact that <code>Box<T></code> shall be implementable entirely in user code. While we are
many missing language features away from this being the case, the <code>noalias</code> case is also magic descended upon box itself, with no many missing language features away from this being the case, the <code>noalias</code> case is also magic descended upon box itself, with no
user code ever having access to it.</p> user code ever having access to it.</p>
<p>There are also several arguments in favour of box being unique and special cased here. To negate the last argument above, it can <p>There are several arguments in favour of box being unique and special cased here. To negate the last argument above, it can
be said that <code>Box<T></code> <em>is</em> a very special type. It’s just like a <code>T</code>, but on the heap. Using this mental model, it’s very easy to be said that <code>Box<T></code> <em>is</em> a very special type. It’s just like a <code>T</code>, but on the heap. Using this mental model, it’s very easy to
justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code, justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code,
and I prefer the mental model of “reference that manages its own lifetime”, which doesn’t imply uniqueness.</p> and I prefer the mental model of “reference that manages its own lifetime”, which doesn’t imply uniqueness.</p>
<p>But there are also crates on <a href="https://crates.io/">crates.io</a> like <a href="https://crates.io/crates/aliasable">aliasable</a> that already
provide an aliasable version of <code>Box<T></code>, which is used by the self-referential type helper crate <a href="https://crates.io/crates/ouroboros">ouroboros</a>.
So if box stayed unique, people could also just pick up that crate as a dependency and use the aliasable box from there instead of
having to write their own. Interestingly, this crate also provides a <code>Vec<T></code>, even though <code>Vec<T></code> can currently be aliased in practice and
in the current version of stacked borrows. just fine, although it’s also not clear whether we want to keep it like this, but I
don’t think this can reasonable be changed.</p>
<h1 id="noalias-noslow">noalias, noslow</h1> <h1 id="noalias-noslow">noalias, noslow</h1>
<p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. <code>noalias</code> doesn’t exist for fun, it’s something <p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. <code>noalias</code> doesn’t exist for fun, it’s something
that can bring clear performance wins (for <code>noalias</code> on <code>&mut T</code>, those were measureable). So the only question remains: that can bring clear performance wins (for <code>noalias</code> on <code>&mut T</code>, those were measureable). So the only question remains:
<strong>How much performance does <code>noalias</code> on <code>Box<T></code> give us now, and how many potential performance improvements could we get in the <strong>How much performance does <code>noalias</code> on <code>Box<T></code> give us now, and how many potential performance improvements could we get in the
future?</strong> For the latter, there is no simple answer. For the former, there is. <code>rustc</code> has <a href="https://github.com/rust-lang/rust/pull/99527"><em>no</em> performance improvements</a> future?</strong> For the latter, there is no simple answer. For the former, there is. <code>rustc</code> has <a href="https://github.com/rust-lang/rust/pull/99527"><em>no</em> performance improvements</a>
from being compiled with <code>noalias</code> on <code>Box<T></code>.</p> from being compiled with <code>noalias</code> on <code>Box<T></code>.</p>
<p>I have not yet benchmarked ecosystem crates without box noalias and don’t have the capacity to do so right now, so I would be very <p>I have also benchmarked a few crates from the ecosystem with and without noalias on box, and the <a href="https://gist.github.com/Nilstrieb/9a0751fb9fd1044a30ab55cef9a7d335">results</a>
grateful if anyone wanted to pick that up and report the results.</p> were inconclusive. (At the time of writing, only regex-syntax, tokio, and syn have been benchmarked.) regex-syntax showed no changes. Tokio showed a few improvements without noalias
<p>There are also crates on <a href="https://crates.io/">crates.io</a> like <a href="https://crates.io/crates/aliasable">aliasable</a> that already which is very weird, so maybe the benchmarks aren’t really good or something else was going on. And syn tended towards minor regressions without noalias, but the benchmarks had high
provide an aliasable version of <code>Box<T></code>, which is used by the self-referential type helper crate <a href="https://crates.io/crates/ouroboros">ouroboros</a>.</p> jitter so no real conclusion can be reached from this either, at least in my eyes, but I don’t have a lot of experience with benchmarks. Therefore, I would love for more people
to benchmark more crates, especially if you have more experience with benchmarks.</p>
<h1 id="a-way-forward">a way forward</h1> <h1 id="a-way-forward">a way forward</h1>
<p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions in ecosystem crates, <p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions, they are not significant enough
the overall tradeoff goes against the current box behaviour. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely to justify boxes uniqueness. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely remove all uniqueness from <code>Box<T></code>, and treat it
remove all uniqueness from <code>Box<T></code>, and treat it just like a <code>*const T</code> for the purposes of aliasing. This will make it more just like a <code>*const T</code> for the purposes of aliasing. This will make it more predictable for unsafe code, and is a step forward towards less magic from <code>Box<T></code>.</p>
predictable for unsafe code, and comes at none or only a minor performance cost.</p> <p>But the performance cost may be real, and especially the future optimization value can’t be certain. The current uniqueness guarantees of box
<p>But this performance cost may be real, and especially the future optimization value can’t be certain. The current uniqueness guarantees of box
are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a
<code>&'static mut T</code> that is unleaked for drop, but the semantics of this are still <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear</a>. <code>&'static mut T</code> that is unleaked for drop, but the semantics of this are still <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear</a>.
If that is not possible, exposing <code>std::ptr::Unique</code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of <code>Unique</code> If that is not possible, exposing <code>std::ptr::Unique</code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of <code>Unique</code>
inside the standard library would have to be removed.</p> inside the standard library would have to be removed. We could also offer a <code>std::boxed::UniqueBox</code> 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.</p>
<p>I guess what I am wishing for are some good and flexible raw pointer types. But that’s still in the stars…</p> <p>I guess what I am wishing for are some good and flexible raw pointer types. But that’s still in the stars…</p>
&lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss> &lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss>

View file

@ -1,6 +1,6 @@
<!doctype html><html lang=en><head><title>Box Is a Unique Type :: nilstriebs blog</title><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="About better aliasing semantics for `Box`"><meta name=keywords content="box,noalias"><meta name=robots content="noodp"><link rel=canonical href=/posts/box-is-a-unique-type/><link rel=stylesheet href=/assets/style.css><link rel=apple-touch-icon href=/img/apple-touch-icon-192x192.png><link rel="shortcut icon" href=/img/favicon/orange.png><meta name=twitter:card content="summary"><meta property="og:locale" content="en"><meta property="og:type" content="article"><meta property="og:title" content="Box Is a Unique Type"><meta property="og:description" content="About better aliasing semantics for `Box`"><meta property="og:url" content="/posts/box-is-a-unique-type/"><meta property="og:site_name" content="nilstriebs blog"><meta property="og:image" content="/"><meta property="og:image:width" content="2048"><meta property="og:image:height" content="1024"><meta property="article:published_time" content="2022-07-22 00:00:00 +0000 UTC"></head><body class=orange><div class="container center headings--one-size"><header class=header><div class=header__inner><div class=header__logo><a href=/><div class=logo>nilstriebs blog</div></a></div></div></header><div class=content><div class=post><h1 class=post-title><a href=/posts/box-is-a-unique-type/>Box Is a Unique Type</a></h1><div class=post-meta><span class=post-date>2022-07-22</span> <!doctype html><html lang=en><head><title>Box Is a Unique Type :: nilstriebs blog</title><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="About better aliasing semantics for `Box`"><meta name=keywords content="box,noalias"><meta name=robots content="noodp"><link rel=canonical href=/posts/box-is-a-unique-type/><link rel=stylesheet href=/assets/style.css><link rel=apple-touch-icon href=/img/apple-touch-icon-192x192.png><link rel="shortcut icon" href=/img/favicon/orange.png><meta name=twitter:card content="summary"><meta property="og:locale" content="en"><meta property="og:type" content="article"><meta property="og:title" content="Box Is a Unique Type"><meta property="og:description" content="About better aliasing semantics for `Box`"><meta property="og:url" content="/posts/box-is-a-unique-type/"><meta property="og:site_name" content="nilstriebs blog"><meta property="og:image" content="/"><meta property="og:image:width" content="2048"><meta property="og:image:height" content="1024"><meta property="article:published_time" content="2022-07-22 00:00:00 +0000 UTC"></head><body class=orange><div class="container center headings--one-size"><header class=header><div class=header__inner><div class=header__logo><a href=/><div class=logo>nilstriebs blog</div></a></div></div></header><div class=content><div class=post><h1 class=post-title><a href=/posts/box-is-a-unique-type/>Box Is a Unique Type</a></h1><div class=post-meta><span class=post-date>2022-07-22</span>
<span class=post-author>:: Nilstrieb</span> <span class=post-author>:: Nilstrieb</span>
<span class=post-reading-time>:: 10 min read (2110 words)</span></div><span class=post-tags>#<a href=/tags/rust/>rust</a>&nbsp; <span class=post-reading-time>:: 12 min read (2351 words)</span></div><span class=post-tags>#<a href=/tags/rust/>rust</a>&nbsp;
#<a href=/tags/unsafe-code/>unsafe code</a>&nbsp;</span><div class=post-content><div><p>We have all used <code>Box&lt;T></code> before in our Rust code. It&rsquo;s a glorious type, with great ergonomics #<a href=/tags/unsafe-code/>unsafe code</a>&nbsp;</span><div class=post-content><div><p>We have all used <code>Box&lt;T></code> before in our Rust code. It&rsquo;s a glorious type, with great ergonomics
and flexibitility. We can use it to put our values on the heap, but it can do even more and flexibitility. We can use it to put our values on the heap, but it can do even more
than that!</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>Fields</span> { than that!</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>Fields</span> {
@ -45,16 +45,17 @@ reveals the solution: (severely shortened to only show the relevant parts)</p><p
<code>noalias</code> is an LLVM attribute on pointers that allows for various optimizations. If there are two pointers, <code>noalias</code> is an LLVM attribute on pointers that allows for various optimizations. If there are two pointers,
and at least one of them is <code>noalias</code>, there are some restrictions around the two. Approximately:</p><ul><li>If one of them writes, they must not point to the same value (alias each other)</li><li>If neither of them writes, they can alias just fine. and at least one of them is <code>noalias</code>, there are some restrictions around the two. Approximately:</p><ul><li>If one of them writes, they must not point to the same value (alias each other)</li><li>If neither of them writes, they can alias just fine.
Therefore, we also apply <code>noalias</code> to <code>&mut T</code> and <code>&T</code> (if it doesn&rsquo;t contain interior mutability through Therefore, we also apply <code>noalias</code> to <code>&mut T</code> and <code>&T</code> (if it doesn&rsquo;t contain interior mutability through
<code>UnsafeCell&lt;T></code>, since they uphold these rules.</li></ul><p>This might sound familiar to you if you&rsquo;re a viewer of <a href=https://twitter.com/jonhoo>Jon Gjengset</a>&rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate <code>left-right</code> <code>UnsafeCell&lt;T></code>), since they uphold these rules.</li></ul><p>For more info on <code>noalias</code>, see <a href=https://llvm.org/docs/LangRef.html#parameter-attributes>LLVMs LangRef</a>.</p><p>This might sound familiar to you if you&rsquo;re a viewer of <a href=https://twitter.com/jonhoo>Jon Gjengset</a>&rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate <code>left-right</code>
was affected by this (<a href=https://youtu.be/EY7Wi9fV5bk)>https://youtu.be/EY7Wi9fV5bk)</a>.</p><p>If you&rsquo;re looking for <em>any</em> hint that using box emits <code>noalias</code>, you have to look no further than the documentation was affected by this (<a href=https://youtu.be/EY7Wi9fV5bk)>https://youtu.be/EY7Wi9fV5bk)</a>.</p><p>If you&rsquo;re looking for <em>any</em> hint that using box emits <code>noalias</code>, you have to look no further than the documentation
for <a href=https://doc.rust-lang.org/nightly/std/boxed/index.html#considerations-for-unsafe-code><code>std::boxed</code></a>. Well, the nightly or beta docs, because I only added this section very recently. For years, this behaviour was not really documented, and you had to for <a href=https://doc.rust-lang.org/nightly/std/boxed/index.html#considerations-for-unsafe-code><code>std::boxed</code></a>. Well, the nightly or beta docs, because I only added this section very recently. For years, this behaviour was not really documented, and you had to
belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was &ldquo;just an belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was &ldquo;just an
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.</p><h1 id=stacked-borrows-and-miri>Stacked Borrows and Miri<a href=#stacked-borrows-and-miri class=hanchor arialabel=Anchor>&#8983;</a></h1><p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&rsquo;t talk in standardese</p><p><a href=https://github.com/rust-lang/miri>Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour. pointers are concerned.</p><h1 id=stacked-borrows-and-miri>Stacked Borrows and Miri<a href=#stacked-borrows-and-miri class=hanchor arialabel=Anchor>&#8983;</a></h1><p>So, LLVM was completely correct in optimizing our code to make the assert fail. But what exactly gave it permission to do so?
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed, Undefined Behaviour (UB for short). Undefined behaviour is at the root of many modern compiler optimizations. But what is undefined behaviour?
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly UB represents a contract between the program and the compiler. The compiler assumes that UB will not happen, and can therefore optimize based
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.</p><p>I cannot recommend Miri highly enough for all unsafe code you&rsquo;re writing (sadly support for some IO functions on these assumptions. Examples of UB also include use-after-free, out of bounds reads or data races. If UB is executed, <em>anything</em> can happen,
and FFI is still lacking, and it&rsquo;s still very slow).</p><p>So, let&rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&rsquo;t be allowed to change including segmentation faults, silent memory corruption, leakage of private keys or exactly what you intended to happen.</p><p><a href=https://github.com/rust-lang/miri>Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour in Rust. I cannot recommend Miri
highly enough for all unsafe code you&rsquo;re writing (sadly support for some IO functions and FFI is still lacking, and it&rsquo;s still very slow).</p><p>So, let&rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&rsquo;t be allowed to change
observable behaviour (since the assert doesn&rsquo;t fail in debug mode). <code>$ cargo miri run</code>&mldr;</p><pre tabindex=0><code class=language-rust,ignore data-lang=rust,ignore>error: Undefined Behavior: attempting a read access using &lt;3314&gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location observable behaviour (since the assert doesn&rsquo;t fail in debug mode). <code>$ cargo miri run</code>&mldr;</p><pre tabindex=0><code class=language-rust,ignore data-lang=rust,ignore>error: Undefined Behavior: attempting a read access using &lt;3314&gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location
--&gt; src/main.rs:2:26 --&gt; src/main.rs:2:26
| |
@ -105,22 +106,29 @@ This is fairly inconvenient, but totally acceptable. There are bigger problems t
that want to expose a generic interface over any type. Users like to choose box, and sometimes <em>have</em> to chose box because of that want to expose a generic interface over any type. Users like to choose box, and sometimes <em>have</em> to chose box because of
other box-exclusive features it offers. Even worse is <code>string_cache</code>, which is extremely hard to fix.</p><p>Then last but not least, there&rsquo;s the opinionated fact that <code>Box&lt;T></code> shall be implementable entirely in user code. While we are other box-exclusive features it offers. Even worse is <code>string_cache</code>, which is extremely hard to fix.</p><p>Then last but not least, there&rsquo;s the opinionated fact that <code>Box&lt;T></code> shall be implementable entirely in user code. While we are
many missing language features away from this being the case, the <code>noalias</code> case is also magic descended upon box itself, with no many missing language features away from this being the case, the <code>noalias</code> case is also magic descended upon box itself, with no
user code ever having access to it.</p><p>There are also several arguments in favour of box being unique and special cased here. To negate the last argument above, it can user code ever having access to it.</p><p>There are several arguments in favour of box being unique and special cased here. To negate the last argument above, it can
be said that <code>Box&lt;T></code> <em>is</em> a very special type. It&rsquo;s just like a <code>T</code>, but on the heap. Using this mental model, it&rsquo;s very easy to be said that <code>Box&lt;T></code> <em>is</em> a very special type. It&rsquo;s just like a <code>T</code>, but on the heap. Using this mental model, it&rsquo;s very easy to
justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code, justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code,
and I prefer the mental model of &ldquo;reference that manages its own lifetime&rdquo;, which doesn&rsquo;t imply uniqueness.</p><h1 id=noalias-noslow>noalias, noslow<a href=#noalias-noslow class=hanchor arialabel=Anchor>&#8983;</a></h1><p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. <code>noalias</code> doesn&rsquo;t exist for fun, it&rsquo;s something and I prefer the mental model of &ldquo;reference that manages its own lifetime&rdquo;, which doesn&rsquo;t imply uniqueness.</p><p>But there are also crates on <a href=https://crates.io/>crates.io</a> like <a href=https://crates.io/crates/aliasable>aliasable</a> that already
provide an aliasable version of <code>Box&lt;T></code>, which is used by the self-referential type helper crate <a href=https://crates.io/crates/ouroboros>ouroboros</a>.
So if box stayed unique, people could also just pick up that crate as a dependency and use the aliasable box from there instead of
having to write their own. Interestingly, this crate also provides a <code>Vec&lt;T></code>, even though <code>Vec&lt;T></code> can currently be aliased in practice and
in the current version of stacked borrows. just fine, although it&rsquo;s also not clear whether we want to keep it like this, but I
don&rsquo;t think this can reasonable be changed.</p><h1 id=noalias-noslow>noalias, noslow<a href=#noalias-noslow class=hanchor arialabel=Anchor>&#8983;</a></h1><p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. <code>noalias</code> doesn&rsquo;t exist for fun, it&rsquo;s something
that can bring clear performance wins (for <code>noalias</code> on <code>&mut T</code>, those were measureable). So the only question remains: that can bring clear performance wins (for <code>noalias</code> on <code>&mut T</code>, those were measureable). So the only question remains:
<strong>How much performance does <code>noalias</code> on <code>Box&lt;T></code> give us now, and how many potential performance improvements could we get in the <strong>How much performance does <code>noalias</code> on <code>Box&lt;T></code> give us now, and how many potential performance improvements could we get in the
future?</strong> For the latter, there is no simple answer. For the former, there is. <code>rustc</code> has <a href=https://github.com/rust-lang/rust/pull/99527><em>no</em> performance improvements</a> future?</strong> For the latter, there is no simple answer. For the former, there is. <code>rustc</code> has <a href=https://github.com/rust-lang/rust/pull/99527><em>no</em> performance improvements</a>
from being compiled with <code>noalias</code> on <code>Box&lt;T></code>.</p><p>I have not yet benchmarked ecosystem crates without box noalias and don&rsquo;t have the capacity to do so right now, so I would be very from being compiled with <code>noalias</code> on <code>Box&lt;T></code>.</p><p>I have also benchmarked a few crates from the ecosystem with and without noalias on box, and the <a href=https://gist.github.com/Nilstrieb/9a0751fb9fd1044a30ab55cef9a7d335>results</a>
grateful if anyone wanted to pick that up and report the results.</p><p>There are also crates on <a href=https://crates.io/>crates.io</a> like <a href=https://crates.io/crates/aliasable>aliasable</a> that already were inconclusive. (At the time of writing, only regex-syntax, tokio, and syn have been benchmarked.) regex-syntax showed no changes. Tokio showed a few improvements without noalias
provide an aliasable version of <code>Box&lt;T></code>, which is used by the self-referential type helper crate <a href=https://crates.io/crates/ouroboros>ouroboros</a>.</p><h1 id=a-way-forward>a way forward<a href=#a-way-forward class=hanchor arialabel=Anchor>&#8983;</a></h1><p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions in ecosystem crates, which is very weird, so maybe the benchmarks aren&rsquo;t really good or something else was going on. And syn tended towards minor regressions without noalias, but the benchmarks had high
the overall tradeoff goes against the current box behaviour. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely jitter so no real conclusion can be reached from this either, at least in my eyes, but I don&rsquo;t have a lot of experience with benchmarks. Therefore, I would love for more people
remove all uniqueness from <code>Box&lt;T></code>, and treat it just like a <code>*const T</code> for the purposes of aliasing. This will make it more to benchmark more crates, especially if you have more experience with benchmarks.</p><h1 id=a-way-forward>a way forward<a href=#a-way-forward class=hanchor arialabel=Anchor>&#8983;</a></h1><p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions, they are not significant enough
predictable for unsafe code, and comes at none or only a minor performance cost.</p><p>But this performance cost may be real, and especially the future optimization value can&rsquo;t be certain. The current uniqueness guarantees of box to justify boxes uniqueness. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely remove all uniqueness from <code>Box&lt;T></code>, and treat it
just like a <code>*const T</code> for the purposes of aliasing. This will make it more predictable for unsafe code, and is a step forward towards less magic from <code>Box&lt;T></code>.</p><p>But the performance cost may be real, and especially the future optimization value can&rsquo;t be certain. The current uniqueness guarantees of box
are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a
<code>&'static mut T</code> that is unleaked for drop, but the semantics of this are still <a href=https://github.com/rust-lang/unsafe-code-guidelines/issues/316>unclear</a>. <code>&'static mut T</code> that is unleaked for drop, but the semantics of this are still <a href=https://github.com/rust-lang/unsafe-code-guidelines/issues/316>unclear</a>.
If that is not possible, exposing <code>std::ptr::Unique</code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of <code>Unique</code> If that is not possible, exposing <code>std::ptr::Unique</code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of <code>Unique</code>
inside the standard library would have to be removed.</p><p>I guess what I am wishing for are some good and flexible raw pointer types. But that&rsquo;s still in the stars&mldr;</p><p>For more information about this topic, see <a href=https://github.com/rust-lang/unsafe-code-guidelines/issues/326>https://github.com/rust-lang/unsafe-code-guidelines/issues/326</a></p></div></div></div></div><footer class=footer><div class=footer__inner><div class=copyright><span>© 2022 Powered by <a href=http://gohugo.io>Hugo</a></span> inside the standard library would have to be removed. We could also offer a <code>std::boxed::UniqueBox</code> 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.</p><p>I guess what I am wishing for are some good and flexible raw pointer types. But that&rsquo;s still in the stars&mldr;</p><p>For more information about this topic, see <a href=https://github.com/rust-lang/unsafe-code-guidelines/issues/326>https://github.com/rust-lang/unsafe-code-guidelines/issues/326</a></p></div></div></div></div><footer class=footer><div class=footer__inner><div class=copyright><span>© 2022 Powered by <a href=http://gohugo.io>Hugo</a></span>
<span>:: Theme made by <a href=https://twitter.com/panr>panr</a></span></div></div></footer><script src=/assets/main.js></script> <span>:: Theme made by <a href=https://twitter.com/panr>panr</a></span></div></div></footer><script src=/assets/main.js></script>
<script src=/assets/prism.js></script></div></body></html> <script src=/assets/prism.js></script></div></body></html>

View file

@ -56,8 +56,9 @@ and at least one of them is &lt;code>noalias&lt;/code>, there are some restricti
&lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li> &lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li>
&lt;li>If neither of them writes, they can alias just fine. &lt;li>If neither of them writes, they can alias just fine.
Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through
&lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>, since they uphold these rules.&lt;/li> &lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>), since they uphold these rules.&lt;/li>
&lt;/ul> &lt;/ul>
&lt;p>For more info on &lt;code>noalias&lt;/code>, see &lt;a href="https://llvm.org/docs/LangRef.html#parameter-attributes">LLVMs LangRef&lt;/a>.&lt;/p>
&lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code> &lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code>
was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p> was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p>
&lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation &lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation
@ -66,13 +67,13 @@ belong to the arcane circles of the select few who were aware of it. So lots of
RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.&lt;/p> pointers are concerned.&lt;/p>
&lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1> &lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1>
&lt;p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&amp;rsquo;t talk in standardese&lt;/p> &lt;p>So, LLVM was completely correct in optimizing our code to make the assert fail. But what exactly gave it permission to do so?
&lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour. Undefined Behaviour (UB for short). Undefined behaviour is at the root of many modern compiler optimizations. But what is undefined behaviour?
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed, UB represents a contract between the program and the compiler. The compiler assumes that UB will not happen, and can therefore optimize based
&lt;em>anything&lt;/em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly on these assumptions. Examples of UB also include use-after-free, out of bounds reads or data races. If UB is executed, &lt;em>anything&lt;/em> can happen,
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.&lt;/p> including segmentation faults, silent memory corruption, leakage of private keys or exactly what you intended to happen.&lt;/p>
&lt;p>I cannot recommend Miri highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions &lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour in Rust. I cannot recommend Miri
and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p> highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p>
&lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change &lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change
observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p> observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location &lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location
@ -137,29 +138,36 @@ other box-exclusive features it offers. Even worse is &lt;code>string_cache&lt;/
&lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are &lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are
many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no
user code ever having access to it.&lt;/p> user code ever having access to it.&lt;/p>
&lt;p>There are also several arguments in favour of box being unique and special cased here. To negate the last argument above, it can &lt;p>There are several arguments in favour of box being unique and special cased here. To negate the last argument above, it can
be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to
justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code, justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code,
and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p> and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p>
&lt;p>But there are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.
So if box stayed unique, people could also just pick up that crate as a dependency and use the aliasable box from there instead of
having to write their own. Interestingly, this crate also provides a &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code>, even though &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code> can currently be aliased in practice and
in the current version of stacked borrows. just fine, although it&amp;rsquo;s also not clear whether we want to keep it like this, but I
don&amp;rsquo;t think this can reasonable be changed.&lt;/p>
&lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1> &lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1>
&lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something &lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something
that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains: that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains:
&lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the &lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the
future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a> future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a>
from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p> from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
&lt;p>I have not yet benchmarked ecosystem crates without box noalias and don&amp;rsquo;t have the capacity to do so right now, so I would be very &lt;p>I have also benchmarked a few crates from the ecosystem with and without noalias on box, and the &lt;a href="https://gist.github.com/Nilstrieb/9a0751fb9fd1044a30ab55cef9a7d335">results&lt;/a>
grateful if anyone wanted to pick that up and report the results.&lt;/p> were inconclusive. (At the time of writing, only regex-syntax, tokio, and syn have been benchmarked.) regex-syntax showed no changes. Tokio showed a few improvements without noalias
&lt;p>There are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already which is very weird, so maybe the benchmarks aren&amp;rsquo;t really good or something else was going on. And syn tended towards minor regressions without noalias, but the benchmarks had high
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.&lt;/p> jitter so no real conclusion can be reached from this either, at least in my eyes, but I don&amp;rsquo;t have a lot of experience with benchmarks. Therefore, I would love for more people
to benchmark more crates, especially if you have more experience with benchmarks.&lt;/p>
&lt;h1 id="a-way-forward">a way forward&lt;/h1> &lt;h1 id="a-way-forward">a way forward&lt;/h1>
&lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions in ecosystem crates, &lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions, they are not significant enough
the overall tradeoff goes against the current box behaviour. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely to justify boxes uniqueness. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it
remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more predictable for unsafe code, and is a step forward towards less magic from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
predictable for unsafe code, and comes at none or only a minor performance cost.&lt;/p> &lt;p>But the performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
&lt;p>But this performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a
&lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>. &lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>.
If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code> If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code>
inside the standard library would have to be removed.&lt;/p> inside the standard library would have to be removed. We could also offer a &lt;code>std::boxed::UniqueBox&lt;/code> 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.&lt;/p>
&lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p> &lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p>
&lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss> &lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss>

View file

@ -56,8 +56,9 @@ and at least one of them is &lt;code>noalias&lt;/code>, there are some restricti
&lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li> &lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li>
&lt;li>If neither of them writes, they can alias just fine. &lt;li>If neither of them writes, they can alias just fine.
Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through
&lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>, since they uphold these rules.&lt;/li> &lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>), since they uphold these rules.&lt;/li>
&lt;/ul> &lt;/ul>
&lt;p>For more info on &lt;code>noalias&lt;/code>, see &lt;a href="https://llvm.org/docs/LangRef.html#parameter-attributes">LLVMs LangRef&lt;/a>.&lt;/p>
&lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code> &lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code>
was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p> was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p>
&lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation &lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation
@ -66,13 +67,13 @@ belong to the arcane circles of the select few who were aware of it. So lots of
RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.&lt;/p> pointers are concerned.&lt;/p>
&lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1> &lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1>
&lt;p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&amp;rsquo;t talk in standardese&lt;/p> &lt;p>So, LLVM was completely correct in optimizing our code to make the assert fail. But what exactly gave it permission to do so?
&lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour. Undefined Behaviour (UB for short). Undefined behaviour is at the root of many modern compiler optimizations. But what is undefined behaviour?
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed, UB represents a contract between the program and the compiler. The compiler assumes that UB will not happen, and can therefore optimize based
&lt;em>anything&lt;/em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly on these assumptions. Examples of UB also include use-after-free, out of bounds reads or data races. If UB is executed, &lt;em>anything&lt;/em> can happen,
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.&lt;/p> including segmentation faults, silent memory corruption, leakage of private keys or exactly what you intended to happen.&lt;/p>
&lt;p>I cannot recommend Miri highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions &lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour in Rust. I cannot recommend Miri
and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p> highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p>
&lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change &lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change
observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p> observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location &lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location
@ -137,29 +138,36 @@ other box-exclusive features it offers. Even worse is &lt;code>string_cache&lt;/
&lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are &lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are
many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no
user code ever having access to it.&lt;/p> user code ever having access to it.&lt;/p>
&lt;p>There are also several arguments in favour of box being unique and special cased here. To negate the last argument above, it can &lt;p>There are several arguments in favour of box being unique and special cased here. To negate the last argument above, it can
be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to
justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code, justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code,
and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p> and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p>
&lt;p>But there are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.
So if box stayed unique, people could also just pick up that crate as a dependency and use the aliasable box from there instead of
having to write their own. Interestingly, this crate also provides a &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code>, even though &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code> can currently be aliased in practice and
in the current version of stacked borrows. just fine, although it&amp;rsquo;s also not clear whether we want to keep it like this, but I
don&amp;rsquo;t think this can reasonable be changed.&lt;/p>
&lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1> &lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1>
&lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something &lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something
that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains: that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains:
&lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the &lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the
future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a> future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a>
from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p> from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
&lt;p>I have not yet benchmarked ecosystem crates without box noalias and don&amp;rsquo;t have the capacity to do so right now, so I would be very &lt;p>I have also benchmarked a few crates from the ecosystem with and without noalias on box, and the &lt;a href="https://gist.github.com/Nilstrieb/9a0751fb9fd1044a30ab55cef9a7d335">results&lt;/a>
grateful if anyone wanted to pick that up and report the results.&lt;/p> were inconclusive. (At the time of writing, only regex-syntax, tokio, and syn have been benchmarked.) regex-syntax showed no changes. Tokio showed a few improvements without noalias
&lt;p>There are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already which is very weird, so maybe the benchmarks aren&amp;rsquo;t really good or something else was going on. And syn tended towards minor regressions without noalias, but the benchmarks had high
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.&lt;/p> jitter so no real conclusion can be reached from this either, at least in my eyes, but I don&amp;rsquo;t have a lot of experience with benchmarks. Therefore, I would love for more people
to benchmark more crates, especially if you have more experience with benchmarks.&lt;/p>
&lt;h1 id="a-way-forward">a way forward&lt;/h1> &lt;h1 id="a-way-forward">a way forward&lt;/h1>
&lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions in ecosystem crates, &lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions, they are not significant enough
the overall tradeoff goes against the current box behaviour. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely to justify boxes uniqueness. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it
remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more predictable for unsafe code, and is a step forward towards less magic from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
predictable for unsafe code, and comes at none or only a minor performance cost.&lt;/p> &lt;p>But the performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
&lt;p>But this performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a
&lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>. &lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>.
If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code> If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code>
inside the standard library would have to be removed.&lt;/p> inside the standard library would have to be removed. We could also offer a &lt;code>std::boxed::UniqueBox&lt;/code> 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.&lt;/p>
&lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p> &lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p>
&lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss> &lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss>

View file

@ -56,8 +56,9 @@ and at least one of them is &lt;code>noalias&lt;/code>, there are some restricti
&lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li> &lt;li>If one of them writes, they must not point to the same value (alias each other)&lt;/li>
&lt;li>If neither of them writes, they can alias just fine. &lt;li>If neither of them writes, they can alias just fine.
Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through Therefore, we also apply &lt;code>noalias&lt;/code> to &lt;code>&amp;amp;mut T&lt;/code> and &lt;code>&amp;amp;T&lt;/code> (if it doesn&amp;rsquo;t contain interior mutability through
&lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>, since they uphold these rules.&lt;/li> &lt;code>UnsafeCell&amp;lt;T&amp;gt;&lt;/code>), since they uphold these rules.&lt;/li>
&lt;/ul> &lt;/ul>
&lt;p>For more info on &lt;code>noalias&lt;/code>, see &lt;a href="https://llvm.org/docs/LangRef.html#parameter-attributes">LLVMs LangRef&lt;/a>.&lt;/p>
&lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code> &lt;p>This might sound familiar to you if you&amp;rsquo;re a viewer of &lt;a href="https://twitter.com/jonhoo">Jon Gjengset&lt;/a>&amp;rsquo;s content (which I can highly recommend). Jon has made an entire video about this before, since his crate &lt;code>left-right&lt;/code>
was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p> was affected by this (&lt;a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)&lt;/a>.&lt;/p>
&lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation &lt;p>If you&amp;rsquo;re looking for &lt;em>any&lt;/em> hint that using box emits &lt;code>noalias&lt;/code>, you have to look no further than the documentation
@ -66,13 +67,13 @@ belong to the arcane circles of the select few who were aware of it. So lots of
RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all RAII pointer&amp;rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.&lt;/p> pointers are concerned.&lt;/p>
&lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1> &lt;h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri&lt;/h1>
&lt;p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&amp;rsquo;t talk in standardese&lt;/p> &lt;p>So, LLVM was completely correct in optimizing our code to make the assert fail. But what exactly gave it permission to do so?
&lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour. Undefined Behaviour (UB for short). Undefined behaviour is at the root of many modern compiler optimizations. But what is undefined behaviour?
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed, UB represents a contract between the program and the compiler. The compiler assumes that UB will not happen, and can therefore optimize based
&lt;em>anything&lt;/em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly on these assumptions. Examples of UB also include use-after-free, out of bounds reads or data races. If UB is executed, &lt;em>anything&lt;/em> can happen,
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.&lt;/p> including segmentation faults, silent memory corruption, leakage of private keys or exactly what you intended to happen.&lt;/p>
&lt;p>I cannot recommend Miri highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions &lt;p>&lt;a href="https://github.com/rust-lang/miri">Miri&lt;/a> is an interpreter for Rust code with the goal of finding undefined behaviour in Rust. I cannot recommend Miri
and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p> highly enough for all unsafe code you&amp;rsquo;re writing (sadly support for some IO functions and FFI is still lacking, and it&amp;rsquo;s still very slow).&lt;/p>
&lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change &lt;p>So, let&amp;rsquo;s see whether our code contains UB. It has to, since otherwise the optimizer wouldn&amp;rsquo;t be allowed to change
observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p> observable behaviour (since the assert doesn&amp;rsquo;t fail in debug mode). &lt;code>$ cargo miri run&lt;/code>&amp;hellip;&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location &lt;pre tabindex="0">&lt;code class="language-rust,ignore" data-lang="rust,ignore">error: Undefined Behavior: attempting a read access using &amp;lt;3314&amp;gt; at alloc1722[0x0], but that tag does not exist in the borrow stack for this location
@ -137,29 +138,36 @@ other box-exclusive features it offers. Even worse is &lt;code>string_cache&lt;/
&lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are &lt;p>Then last but not least, there&amp;rsquo;s the opinionated fact that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> shall be implementable entirely in user code. While we are
many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no many missing language features away from this being the case, the &lt;code>noalias&lt;/code> case is also magic descended upon box itself, with no
user code ever having access to it.&lt;/p> user code ever having access to it.&lt;/p>
&lt;p>There are also several arguments in favour of box being unique and special cased here. To negate the last argument above, it can &lt;p>There are several arguments in favour of box being unique and special cased here. To negate the last argument above, it can
be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to be said that &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> &lt;em>is&lt;/em> a very special type. It&amp;rsquo;s just like a &lt;code>T&lt;/code>, but on the heap. Using this mental model, it&amp;rsquo;s very easy to
justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code, justify all the box magic and its unique behaviour. But in my opinion, this is not a useful mental model regarding unsafe code,
and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p> and I prefer the mental model of &amp;ldquo;reference that manages its own lifetime&amp;rdquo;, which doesn&amp;rsquo;t imply uniqueness.&lt;/p>
&lt;p>But there are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.
So if box stayed unique, people could also just pick up that crate as a dependency and use the aliasable box from there instead of
having to write their own. Interestingly, this crate also provides a &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code>, even though &lt;code>Vec&amp;lt;T&amp;gt;&lt;/code> can currently be aliased in practice and
in the current version of stacked borrows. just fine, although it&amp;rsquo;s also not clear whether we want to keep it like this, but I
don&amp;rsquo;t think this can reasonable be changed.&lt;/p>
&lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1> &lt;h1 id="noalias-noslow">noalias, noslow&lt;/h1>
&lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something &lt;p>There is one clear potential benefit from this box behaviour: ✨Optimizations✨. &lt;code>noalias&lt;/code> doesn&amp;rsquo;t exist for fun, it&amp;rsquo;s something
that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains: that can bring clear performance wins (for &lt;code>noalias&lt;/code> on &lt;code>&amp;amp;mut T&lt;/code>, those were measureable). So the only question remains:
&lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the &lt;strong>How much performance does &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code> give us now, and how many potential performance improvements could we get in the
future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a> future?&lt;/strong> For the latter, there is no simple answer. For the former, there is. &lt;code>rustc&lt;/code> has &lt;a href="https://github.com/rust-lang/rust/pull/99527">&lt;em>no&lt;/em> performance improvements&lt;/a>
from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p> from being compiled with &lt;code>noalias&lt;/code> on &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
&lt;p>I have not yet benchmarked ecosystem crates without box noalias and don&amp;rsquo;t have the capacity to do so right now, so I would be very &lt;p>I have also benchmarked a few crates from the ecosystem with and without noalias on box, and the &lt;a href="https://gist.github.com/Nilstrieb/9a0751fb9fd1044a30ab55cef9a7d335">results&lt;/a>
grateful if anyone wanted to pick that up and report the results.&lt;/p> were inconclusive. (At the time of writing, only regex-syntax, tokio, and syn have been benchmarked.) regex-syntax showed no changes. Tokio showed a few improvements without noalias
&lt;p>There are also crates on &lt;a href="https://crates.io/">crates.io&lt;/a> like &lt;a href="https://crates.io/crates/aliasable">aliasable&lt;/a> that already which is very weird, so maybe the benchmarks aren&amp;rsquo;t really good or something else was going on. And syn tended towards minor regressions without noalias, but the benchmarks had high
provide an aliasable version of &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, which is used by the self-referential type helper crate &lt;a href="https://crates.io/crates/ouroboros">ouroboros&lt;/a>.&lt;/p> jitter so no real conclusion can be reached from this either, at least in my eyes, but I don&amp;rsquo;t have a lot of experience with benchmarks. Therefore, I would love for more people
to benchmark more crates, especially if you have more experience with benchmarks.&lt;/p>
&lt;h1 id="a-way-forward">a way forward&lt;/h1> &lt;h1 id="a-way-forward">a way forward&lt;/h1>
&lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions in ecosystem crates, &lt;p>Based on all of this, I do have a few solutions. First of all, I think that even if there might be some small performance regressions, they are not significant enough
the overall tradeoff goes against the current box behaviour. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely to justify boxes uniqueness. Unsafe code wants to use box, and it is reasonable to do so. Therefore I propose to completely remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it
remove all uniqueness from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>, and treat it just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more just like a &lt;code>*const T&lt;/code> for the purposes of aliasing. This will make it more predictable for unsafe code, and is a step forward towards less magic from &lt;code>Box&amp;lt;T&amp;gt;&lt;/code>.&lt;/p>
predictable for unsafe code, and comes at none or only a minor performance cost.&lt;/p> &lt;p>But the performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
&lt;p>But this performance cost may be real, and especially the future optimization value can&amp;rsquo;t be certain. The current uniqueness guarantees of box
are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a are very strong, and still giving code an option to obtain these seems useful. One possibility would be for code to use a
&lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>. &lt;code>&amp;amp;'static mut T&lt;/code> that is unleaked for drop, but the semantics of this are still &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/316">unclear&lt;/a>.
If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code> If that is not possible, exposing &lt;code>std::ptr::Unique&lt;/code> (with it getting boxes aliasing semantics) could be desirable. For this, all existing usages of &lt;code>Unique&lt;/code>
inside the standard library would have to be removed.&lt;/p> inside the standard library would have to be removed. We could also offer a &lt;code>std::boxed::UniqueBox&lt;/code> 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.&lt;/p>
&lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p> &lt;p>I guess what I am wishing for are some good and flexible raw pointer types. But that&amp;rsquo;s still in the stars&amp;hellip;&lt;/p>
&lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss> &lt;p>For more information about this topic, see &lt;a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/326">https://github.com/rust-lang/unsafe-code-guidelines/issues/326&lt;/a>&lt;/p></content></item></channel></rss>