<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Lukas Wirth</title>
      <link>https://www.lukaswirth.dev</link>
      <description>it&#x27;s some kind of blog, I think?</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.lukaswirth.dev/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sun, 19 Jun 2022 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Unsafe code highlighting with rust-analyzer</title>
          <pubDate>Sun, 19 Jun 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.lukaswirth.dev/posts/semantic-unsafe/</link>
          <guid>https://www.lukaswirth.dev/posts/semantic-unsafe/</guid>
          <description xml:base="https://www.lukaswirth.dev/posts/semantic-unsafe/">&lt;blockquote&gt;
&lt;p&gt;This is basically a small appreciation post for semantic highlighting ;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;As Rust devs new and seasoned alike should know, unsafe code is a fickle thing and should be avoided whenever possible.
But when the unavoidable need arises, Rust at least requires the explicit use of an &lt;code&gt;unsafe { ... }&lt;&#x2F;code&gt; block expression.
This is a nice way of designing this unsafe access, not just because it requires the developer to make a conscious decision about reaching out to this superset of Rust, but also because it allows a reader to quickly skim code for potentially problematic regions when something goes very much wrong.&lt;&#x2F;p&gt;
&lt;p&gt;The thing with that last point though is that an unsafe block only marks a region of code.
It doesn&#x27;t really show the exact operations that are being done in there that are in fact unsafe!
This wouldn&#x27;t necessarily be relevant if unsafe operations in Rust were special in the way they look, but that is not the case at all.
Every unsafe operation that exists in Rust is actually one that looks just like a safe one: dereferencing (a raw pointer), reading a (union) field, calling a(n unsafe) function or accessing a (mutable) static.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; class=&quot;language-rs z-code&quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;unsafe&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-rust&quot;&gt;*&lt;&#x2F;span&gt;totally_not_a_raw_ptr&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-function z-rust&quot;&gt;very_safe_function&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-rust&quot;&gt;A_STATIC_BUT_NOT_MUTABLE_I_SWEAR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; this&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;is_not_a_union&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;annotated&quot;&gt;
    &lt;p&gt;
        Wouldn&#x27;t it be nice to make these possibly totally not safe operations stand out?
    &lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;All of these operations are generally safe, except for when they occur on certain constructs, so knowing whether they are safe or not in an unsafe block requires looking at the target of the operation (or requiring the unsafe blocks to always only surround the unsafe operation itself).&lt;&#x2F;p&gt;
&lt;p&gt;This is where an IDE like &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; can come into play to help out visually!
Most people should be acquainted with the concept of syntax highlighting, so what if we could make use of that and highlight unsafe operations differently?
This idea sounds great, but in practice the classic approaches to syntax highlighting can&#x27;t help us here (they&#x27;re usually defined via a bunch of &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regular_expression&quot;&gt;regular expressions&lt;&#x2F;a&gt;).
After all, we just established that these unsafe operations don&#x27;t look any different from safe ones.
Fortunately an IDE knows a lot more about code than just the syntax, it knows its &lt;em&gt;semantics&lt;&#x2F;em&gt; and can therefore do the highlighting part on a semantic level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enabling-unsafe-highlighting&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#enabling-unsafe-highlighting&quot; aria-label=&quot;Anchor link for: enabling-unsafe-highlighting&quot;&gt;Enabling unsafe highlighting&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;With that long and boring introduction out of the way let me show you how to visualize this separation of safe and unsafe operations with &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt;!
Of note is that this requires support from your editor.
After all, the editor is still the responsible entity for rendering the text, as long your editor supports the &lt;code&gt;textDocument&#x2F;semanticTokens&lt;&#x2F;code&gt; request of the &lt;a href=&quot;https:&#x2F;&#x2F;microsoft.github.io&#x2F;language-server-protocol&#x2F;overviews&#x2F;lsp&#x2F;overview&#x2F;&quot;&gt;Language Server Protocol&lt;&#x2F;a&gt; you should be good to go.&lt;&#x2F;p&gt;
&lt;p&gt;The exact procedure for enabling this will differ based on your editor of choice, but in VSCode this would be the addition of the following lines to your &lt;code&gt;settings.json&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json z-code&quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;editor.semanticTokenColorCustomizations&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;: &lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-json&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;rules&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-json&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;*.unsafe:rust&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;#eb5046&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;span class=&quot;z-punctuation z-section z-mapping z-end z-json&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-end z-json&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;annotated&quot;&gt;
    &lt;p&gt;
        That&#x27;s it! The curious may want to read the &lt;a href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;api&#x2F;language-extensions&#x2F;semantic-highlight-guide#theming&quot;&gt;VSCode theming section&lt;&#x2F;a&gt;.
    &lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;With that set, &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; will now reveal to us the dark truth of the snippet from earlier!&lt;&#x2F;p&gt;
&lt;!-- Oh dear, zola doesn&#x27;t add classes to all spans so we need to copy and manually construct the code blocks for overwriting...--&gt;
&lt;pre data-lang=&quot;rs&quot; class=&quot;language-rs z-code&quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;unsafe&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;*&lt;&#x2F;span&gt;totally_not_a_raw_ptr&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-function z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;very_safe_function&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;A_STATIC_BUT_NOT_MUTABLE_I_SWEAR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; value &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; this&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-other z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;is_not_a_union&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;annotated&quot;&gt;
    &lt;p&gt;
        Who would&#x27;ve thought, all of it is unsafe!
    &lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Would you look at that!
We can now clearly see which parts of our unsafe block are actually performing unsafe operations.
As a bonus, this also marks the &lt;code&gt;unsafe&lt;&#x2F;code&gt; token itself and the names of unsafe declarations, such as unsafe functions and unsafe traits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unsafe-macros&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#unsafe-macros&quot; aria-label=&quot;Anchor link for: unsafe-macros&quot;&gt;&amp;quot;Unsafe&amp;quot; macros&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;But there is something we forgot about, something that allows one to easily hide things from the naked eye ... macros!
Pesky macros, they can just expand to unsafe operations as they please in a varying kind of ways.
Worry not though, as &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; can see right through their tricks!&lt;&#x2F;p&gt;
&lt;!-- Oh dear, zola doesn&#x27;t add classes to all spans so we need to copy and manually construct the code blocks for overwriting...--&gt;
&lt;pre data-lang=&quot;rs&quot; class=&quot;language-rs z-code&quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;macro_rules!&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-macro z-rust&quot;&gt;i_am_potentially_unsafe&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
    &lt;span class=&quot;z-meta z-group z-macro-matcher z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;$expr&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-macro-body z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
        &lt;span class=&quot;z-keyword z-operator z-arithmetic z-rust&quot;&gt;*&lt;&#x2F;span&gt;$expr
    &lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; reference &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-bitwise z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;span class=&quot;z-storage z-modifier z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;unsafe&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-support z-macro z-rust&quot;&gt;i_am_potentially_unsafe!&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt; reference &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
    &lt;span class=&quot;z-support z-macro z-rust&quot; style=&quot;color:rgb(235, 80, 70);&quot;&gt;i_am_potentially_unsafe&lt;&#x2F;span&gt;! &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt; reference &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;as&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;*const&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;u32&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;annotated&quot;&gt;
    &lt;p&gt;
        Look at that, the language does have unsafe macros! Well, kind of ...
    &lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; actually inspects macro invocations for whether they emit unsafe operations and marks the identifier of the macro-call appropriately.
So while Rust itself doesn&#x27;t really have the concept of an unsafe macro, &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; kind of imagines it.
There is one case where &lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; deliberately marks a macro expanding to unsafe operations not as unsafe though:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; class=&quot;language-rs z-code&quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;macro_rules!&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-macro z-rust&quot;&gt;teardown&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-group z-macro-matcher z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-macro-body z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-macro-body z-rust&quot;&gt;        &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;unsafe&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-rust&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;std&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;ptr&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;null&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-macro-body z-rust&quot;&gt;    &lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;teardown!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;annotated&quot;&gt;
    &lt;p&gt;
        This is clearly doing bad things, but yet it is not marked as unsafe?
    &lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Why is that?
Well, while a macro like the one shown here technically does unsafe things under the hood (even worse, it straight up invokes undefined behavior), invoking the macro does not require an unsafe block, so for consistency we aren&#x27;t marking it as unsafe.
The reasoning here is that usually a macro that wraps its unsafety in an unsafe block does so because it keeps the required invariants up itself, making it safe overall.
If it does not, I&#x27;d like to argue that the macro is incorrectly written as one could invoke undefined behavior by invoking the macro without actually noticeably writing unsafe code.&lt;&#x2F;p&gt;
&lt;p&gt;Note, semantic highlighting doesn&#x27;t stop here!
&lt;code&gt;rust-analyzer&lt;&#x2F;code&gt; has a lot more tags to offer, one of which most of you should be familiar with: the &lt;span style=&quot;text-decoration: underline&quot;&gt;underlining&lt;&#x2F;span&gt; of mutable variables and function calls!
You can see a full list of all the current tags in the &lt;a href=&quot;https:&#x2F;&#x2F;rust-analyzer.github.io&#x2F;manual.html#semantic-syntax-highlighting&quot;&gt;manual&lt;&#x2F;a&gt;, but exploring those is for another day.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>IDEs and proc-macros</title>
          <pubDate>Fri, 25 Feb 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.lukaswirth.dev/posts/ide-proc-macros/</link>
          <guid>https://www.lukaswirth.dev/posts/ide-proc-macros/</guid>
          <description xml:base="https://www.lukaswirth.dev/posts/ide-proc-macros/">&lt;blockquote&gt;
&lt;p&gt;Note that this is written with rust-analyzer in mind, as that is where I come from, nevertheless it should apply to IDEs in general.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-analyzer&#x2F;rust-analyzer&#x2F;&quot;&gt;&lt;code&gt;rust-analyzer&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; enabled &lt;code&gt;#[attribute]&lt;&#x2F;code&gt; expansion by default on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-analyzer&#x2F;rust-analyzer&#x2F;pull&#x2F;10366&quot;&gt;Sep 27, 2021&lt;&#x2F;a&gt;, and since then we&#x27;ve seen several issues pop up about user experience degrading when it comes to completions inside of attributed items.
This is a pretty big issue for most users, especially those who write async or webserver code, as attributes are prominently used there.
Yet we haven&#x27;t really started addressing the issue properly &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-analyzer&#x2F;rust-analyzer&#x2F;pull&#x2F;11444&quot;&gt;until recently&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We briefly talked about it in the &lt;a href=&quot;https:&#x2F;&#x2F;rust-analyzer.github.io&#x2F;blog&#x2F;2021&#x2F;12&#x2F;30&#x2F;2021-recap.html#proc-macros-and-attributes&quot;&gt;2021 rust-analyzer recap&lt;&#x2F;a&gt;, but I figured a separate post about the more general problem as well as possible solutions might be of interest to some people.&lt;&#x2F;p&gt;
&lt;p&gt;This post will expand on the issue by talking about not just attributes, but also about function-like proc-macros.
I will however not touch on derive attributes specifically, as they do not really suffer from the problem as they do not replace their annotated item.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
