<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>kivo&#x27;s blog</title>
    <link rel="self" type="application/atom+xml" href="https://kivooeo.github.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://kivooeo.github.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-15T00:00:00+00:00</updated>
    <id>https://kivooeo.github.io/atom.xml</id>
    <entry xml:lang="en">
        <title>Part 2: Tackling an `A-diagnostics` issue</title>
        <published>2026-06-15T00:00:00+00:00</published>
        <updated>2026-06-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/blog/p2-a-diagnostics/"/>
        <id>https://kivooeo.github.io/blog/p2-a-diagnostics/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/blog/p2-a-diagnostics/">&lt;p&gt;So it&#x27;s been like a couple months since i wrote the last post about how i tackled an &lt;code&gt;e-needs-test&lt;&#x2F;code&gt; issue&lt;&#x2F;p&gt;
&lt;p&gt;This time, like i promised, i wanna go through something a bit more user-facing together with you - diagnostics&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-note&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Note&lt;&#x2F;div&gt;
&lt;p&gt;A diagnostic is that nice, colored explanation the compiler shows you when something goes wrong. Instead of just shouting &quot;error&quot; and walking away, the compiler calmly points at what&#x27;s off and usually nudges you toward a fix&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;For example&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0596]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: cannot borrow `*some_string` as mutable, as it is behind a `&amp;amp;` reference&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;main.rs:8:5
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 |&lt;&#x2F;span&gt;     some_string.push_str(&quot;, world&quot;);
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;     &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^^^^ `some_string` is a `&amp;amp;` reference, so it cannot be borrowed as mutable&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: consider changing this to be a mutable reference
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;7 |&lt;&#x2F;span&gt; fn change(some_string: &amp;amp;&lt;span class=&quot;af-green&quot;&gt;mut&lt;&#x2F;span&gt; String) {
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                         &lt;span class=&quot;af-green&quot;&gt;+++&lt;&#x2F;span&gt;

For more information about this error, try `rustc --explain E0596`.
&lt;span class=&quot;ansi-bold af-red&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: could not compile `f` (bin &quot;f&quot;) due to 1 previous error&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Beautiful, isn&#x27;t it? Well, the thing is they&#x27;re not as perfect as they look at first glance. If we open the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20label%3AA-diagnostics%20no%3Aassignee&quot;&gt;issues&lt;&#x2F;a&gt; we&#x27;ll see a huge pile of issues on this topic, and even though the rust team puts a lot of effort into making them as user-friendly as possible (you know, those stories where you get 20kb of unreadable output from gcc), teachable and simple - i don&#x27;t think it&#x27;ll ever be possible to make them 100% perfect. But that doesn&#x27;t mean we shouldn&#x27;t improve them at all&lt;&#x2F;p&gt;
&lt;h2 id=&quot;picking-an-issue&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#picking-an-issue&quot; aria-label=&quot;Anchor link for: picking-an-issue&quot;&gt;Picking an Issue&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So let&#x27;s grab an issue and try to solve one&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-warning&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Fair warning&lt;&#x2F;div&gt;
&lt;p&gt;I&#x27;ll say right away, the difficulty in this area ranges from &quot;change one word&quot; to &quot;rewrite half of the borrow checker&quot;. But on average it&#x27;s pretty gentle and somewhere in between, so solving them is interesting and fun (mostly)&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;div class=&quot;admonition admonition-warning&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Another fair warning&lt;&#x2F;div&gt;
&lt;p&gt;Bear in mind that your experience may differ significantly from mine, because diagnostics permeate the entire compiler, from the lexer right through to MIR; there&#x27;s so much going on that it&#x27;s impossible to take everything into account: parser recovery, name resolution, type checking, trait resolution, borrow checking; and that&#x27;s just a small part of it &amp;gt;&amp;lt;&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;But you gotta pick the issue wisely, for the same reason as both warnings above&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;151602&quot;&gt;one&lt;&#x2F;a&gt; caught my eye&lt;&#x2F;p&gt;
&lt;p&gt;Shortly, right now for this code&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;fn take(_: impl Iterator&amp;lt;0&amp;gt;) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The compiler gives this error&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;lib.rs:1:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt; 1 |&lt;&#x2F;span&gt; fn take(_: impl Iterator&amp;lt;0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^ expected 0 generic arguments&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;playground&#x2F;.rustup&#x2F;toolchains&#x2F;nightly-x86_64-unknown-linux-gnu&#x2F;lib&#x2F;rustlib&#x2F;src&#x2F;rust&#x2F;library&#x2F;core&#x2F;src&#x2F;iter&#x2F;traits&#x2F;iterator.rs:40:11
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;40 |&lt;&#x2F;span&gt; pub trait Iterator {
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;           &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^^^^&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt; 1 |&lt;&#x2F;span&gt; fn take(_: impl Iterator&amp;lt;&lt;span class=&quot;af-green&quot;&gt;Item =&lt;&#x2F;span&gt; 0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                          &lt;span class=&quot;af-green&quot;&gt;++++++&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is wrong and doesn&#x27;t make any sense&lt;&#x2F;p&gt;
&lt;p&gt;And this code (it&#x27;s a bit outdated)&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-important&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Important&lt;&#x2F;div&gt;
&lt;p&gt;MGCA (&lt;code&gt;min_generic_const_args&lt;&#x2F;code&gt;) is a nightly feature that lets you use const values directly as generic arguments - &lt;code&gt;Trait&amp;lt;0&amp;gt;&lt;&#x2F;code&gt; instead of &lt;code&gt;Trait&amp;lt;K = 0&amp;gt;&lt;&#x2F;code&gt;. That&#x27;s what this whole second example lives in&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;#![feature(min_generic_const_args)]
trait Trait { #[type_const] const K: i32; }
fn take(_: impl Trait&amp;lt;0&amp;gt;) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Spits out this error&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;lib.rs:3:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;3 |&lt;&#x2F;span&gt; fn take(_: impl Trait&amp;lt;0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^--- help: remove the unnecessary generics&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;|&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                 expected 0 generic arguments
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;lib.rs:2:7
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;2 |&lt;&#x2F;span&gt; trait Trait { #[type_const] const K: i32; }
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;       &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Even though it should suggest something like&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;impl Trait&amp;lt;K = 0&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;starting-to-dig&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#starting-to-dig&quot; aria-label=&quot;Anchor link for: starting-to-dig&quot;&gt;Starting to Dig&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;First thing i make a clean branch&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;$ git checkout -b fix-mgca-assoc-sugg
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And right away i kick off a compiler build&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;$ .&amp;#x2F;x b
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So i don&#x27;t have to do it later, plus I&#x27;ll need to run the code above with the &lt;code&gt;-Ztrack-diagnostics&lt;&#x2F;code&gt; flag to find at least the rough place where the diagnostic gets created&lt;&#x2F;p&gt;
&lt;p&gt;While the compiler is building, one interesting detail about this issue - @fmease originally wanted to work on this problem but dropped his assignment&lt;&#x2F;p&gt;
&lt;p&gt;Ideally it&#x27;s worth messaging him to ask what went wrong and why he decided not to fix it further - as one of the people who knows this area well, he&#x27;d give the right hints and help out&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-tip&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;For newcomers&lt;&#x2F;div&gt;
&lt;p&gt;Reaching out to whoever was originally on an issue (or anyone who knows the area) is one of the best moves you can make. In the overwhelming majority of cases people respond super positively - maybe not right away, but positively&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;And so, 5 minutes later&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Build completed successfully in 0:04:57
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My compiler built (yeah I&#x27;m doing everything in real time, on one screen i have a text editor and on the other a code editor)&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s run it on the file right away and see what&#x27;s going on&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;gh-Kivooeo@dev-desktop-eu-1 ~&#x2F;r&#x2F;rust (fix-mgca-assoc-sugg) &amp;gt; .&#x2F;build&#x2F;aarch64-unknown-linux-gnu&#x2F;stage1&#x2F;bin&#x2F;rustc -Ztrack-diagnostics &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs --edition 2024
&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:1:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt; 1 |&lt;&#x2F;span&gt; fn take(_: impl Iterator&amp;lt;0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^ expected 0 generic arguments&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
   = note: -Ztrack-diagnostics: created at compiler&#x2F;rustc_hir_analysis&#x2F;src&#x2F;hir_ty_lowering&#x2F;generics.rs:575:18
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; library&#x2F;core&#x2F;src&#x2F;iter&#x2F;traits&#x2F;iterator.rs:42:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;42 |&lt;&#x2F;span&gt; pub const trait Iterator {
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^^^^&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt; 1 |&lt;&#x2F;span&gt; fn take(_: impl Iterator&amp;lt;&lt;span class=&quot;af-green&quot;&gt;Item =&lt;&#x2F;span&gt; 0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                          &lt;span class=&quot;af-green&quot;&gt;++++++&lt;&#x2F;span&gt;

&lt;span class=&quot;ansi-bold af-red&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: aborting due to 1 previous error&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s look into &lt;code&gt;compiler&#x2F;rustc_hir_analysis&#x2F;src&#x2F;hir_ty_lowering&#x2F;generics.rs:575:18&lt;&#x2F;code&gt;, hmm, at first glance this looks like exactly the function we need&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F;&amp;#x2F; Checks that the correct number of generic arguments have been provided.
&amp;#x2F;&amp;#x2F;&amp;#x2F; This is used both for datatypes and function calls.
#[instrument(skip(cx, gen_pos), level = &amp;quot;debug&amp;quot;)]
pub(crate) fn check_generic_arg_count(
    cx: &amp;amp;dyn HirTyLowerer&amp;lt;&amp;#x27;_&amp;gt;,
    def_id: DefId,
    seg: &amp;amp;hir::PathSegment&amp;lt;&amp;#x27;_&amp;gt;,
    gen_params: &amp;amp;ty::Generics,
    gen_pos: GenericArgPosition,
    has_self: bool,
) -&amp;gt; GenericArgCountResult
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But looking at the logic, i don&#x27;t see anything that could produce a suggestion like &quot;add &lt;code&gt;Item = 0&lt;&#x2F;code&gt;&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-where-the-suggestion-is-born&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#finding-where-the-suggestion-is-born&quot; aria-label=&quot;Anchor link for: finding-where-the-suggestion-is-born&quot;&gt;Finding Where the Suggestion Is Born&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So let&#x27;s grep for the error text &quot;replace the generic bound with the associated type&quot;. This grep found nothing except output in tests, so let&#x27;s shorten it down to &quot;replace the generic&quot; and we immediately found what we need!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;fn suggest_removing_args_or_generics(&amp;amp;self, err: &amp;amp;mut Diag&amp;lt;&amp;#x27;_, impl EmissionGuarantee&amp;gt;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the specific check inside this function&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;if !self.is_in_trait_impl() {
    let unused_generics = &amp;amp;self.gen_args.args[self.num_expected_type_or_const_args()..];
    let suggestions = iter::zip(unused_generics, &amp;amp;unbound_types)
        .map(|(potential, name)| {
            (potential.span().shrink_to_lo(), format!(&amp;quot;{name} = &amp;quot;))
        })
        .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();

    if !suggestions.is_empty() {
        err.multipart_suggestion(
            format!(
                &amp;quot;replace the generic bound{s} with the associated type{s}&amp;quot;,
                s = pluralize!(unbound_types.len())
            ),
            suggestions,
            Applicability::MaybeIncorrect,
        );
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here you can clearly see it by the &lt;code&gt;suggestions&lt;&#x2F;code&gt; variable. Now we gotta think where to move next&lt;&#x2F;p&gt;
&lt;p&gt;We have an interesting call chain through &lt;code&gt;num_expected_type_or_const_args&lt;&#x2F;code&gt; which is used here, but it can&#x27;t really help us much&lt;&#x2F;p&gt;
&lt;p&gt;I didn&#x27;t give you the full context above. Here&#x27;s what the whole check looks like&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;        &amp;#x2F;&amp;#x2F; If there is a single unbound associated type and a single excess generic param
        &amp;#x2F;&amp;#x2F; suggest replacing the generic param with the associated type bound
        if provided_args_matches_unbound_traits &amp;amp;&amp;amp; !unbound_types.is_empty() {
            &amp;#x2F;&amp;#x2F; Don&amp;#x27;t suggest if we&amp;#x27;re in a trait impl as
            &amp;#x2F;&amp;#x2F; that would result in invalid syntax (fixes #116464)
            if !self.is_in_trait_impl() {
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Why did i do that? I didn&#x27;t look at the outer checks right away myself, and the comments give pretty nice hints&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at how &lt;code&gt;unbound_types&lt;&#x2F;code&gt; is defined&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let unbound_types = self.get_unbound_associated_types();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let&#x27;s look at this method&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    fn get_unbound_associated_types(&amp;amp;self) -&amp;gt; Vec&amp;lt;String&amp;gt; {
        if self.tcx.is_trait(self.def_id) { &amp;#x2F;&amp;#x2F; ok that&amp;#x27;s true
            let items: &amp;amp;AssocItems = self.tcx.associated_items(self.def_id); &amp;#x2F;&amp;#x2F; get assoc item, nice
            items
                .in_definition_order() &amp;#x2F;&amp;#x2F; fetch it in def. order
                .filter(|item| {   &amp;#x2F;&amp;#x2F; filter by:
                    item.is_type() &amp;#x2F;&amp;#x2F; only assoc types
                        &amp;amp;&amp;amp; !item.is_impl_trait_in_trait() &amp;#x2F;&amp;#x2F; not trait
                        &amp;amp;&amp;amp; !self
                            .gen_args
                            .constraints
                            .iter()
                            .any(|constraint| constraint.ident.name == item.name())
                            &amp;#x2F;&amp;#x2F;^ exclude associated types that are already bound in the generic args
                })
                .map(|item| self.tcx.item_ident(item.def_id).to_string()) &amp;#x2F;&amp;#x2F; map it to string
                .collect() &amp;#x2F;&amp;#x2F; and collect
        } else {
            Vec::default() &amp;#x2F;&amp;#x2F; otherwise just empty vec
        }
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anyway it&#x27;s all clear. Surprisingly this code is pretty readable on its own, so let&#x27;s make a simple change and see what happens?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;- item.is_type()
+ (item.is_type() || item.is_type_const())
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that i run this interesting command&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;$ .&amp;#x2F;x b --keep-stage 1 &amp;amp;&amp;amp; .&amp;#x2F;build&amp;#x2F;aarch64-unknown-linux-gnu&amp;#x2F;stage1&amp;#x2F;bin&amp;#x2F;rustc -Ztrack-diagnostics &amp;#x2F;home&amp;#x2F;gh-Kivooeo&amp;#x2F;test_&amp;#x2F;src&amp;#x2F;main.rs --edition 2024
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;admonition admonition-tip&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Tip&lt;&#x2F;div&gt;
&lt;p&gt;Use &lt;code&gt;--keep-stage 1&lt;&#x2F;code&gt; if you don&#x27;t wanna recompile std and core, despite the flags name it works exactly like that&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;So... and for some reason it doesn&#x27;t work&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: cannot find attribute `type_const` in this scope&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:2:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;2 |&lt;&#x2F;span&gt; trait Trait { #[type_const] const K: i32; }
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^^^&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
  = note: -Ztrack-diagnostics: created at compiler&#x2F;rustc_resolve&#x2F;src&#x2F;macros.rs:1071:46&lt;&#x2F;pre&gt;
&lt;p&gt;Ah right, i forgot to mention the code examples are a bit outdated. Now you have to write &lt;code&gt;type const&lt;&#x2F;code&gt;, so the example becomes that&lt;&#x2F;p&gt;
&lt;p&gt;And voila ✨&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:3:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;3 |&lt;&#x2F;span&gt; fn take(_: impl Trait&amp;lt;0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^ expected 0 generic arguments&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
  = note: -Ztrack-diagnostics: created at compiler&#x2F;rustc_hir_analysis&#x2F;src&#x2F;hir_ty_lowering&#x2F;generics.rs:575:18
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:2:7
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;2 |&lt;&#x2F;span&gt; trait Trait { type const K: i32; }
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;       &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;3 |&lt;&#x2F;span&gt; fn take(_: impl Trait&amp;lt;&lt;span class=&quot;af-green&quot;&gt;K =&lt;&#x2F;span&gt; 0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                       &lt;span class=&quot;af-green&quot;&gt;+++&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;the-actual-fix&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-actual-fix&quot; aria-label=&quot;Anchor link for: the-actual-fix&quot;&gt;The Actual Fix&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now the only thing left is to deal with the first case, where we get a really not-great diagnostic&lt;&#x2F;p&gt;
&lt;p&gt;For that i think we can go back to the zip logic, because it&#x27;s the thing that adds this suggestion. We need to filter it somehow&lt;&#x2F;p&gt;
&lt;p&gt;Good news, this function is used only in this one specific place, so we can ruthlessly change its signature. I suggest this one&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;fn get_unbound_associated_types(&amp;amp;self) -&amp;gt; Vec&amp;lt;&amp;amp;AssocItem&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not a string but the actual &lt;code&gt;AssocItem&lt;&#x2F;code&gt;, so we don&#x27;t have to do &lt;code&gt;(String, bool)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And we add a filter after the zip call, that checks the following - if we wanna suggest a const (like &lt;code&gt;0&lt;&#x2F;code&gt; for example) then we should check it&#x27;s a &lt;code&gt;type const&lt;&#x2F;code&gt;, and if we wanna suggest a type then we should check it&#x27;s a type&lt;&#x2F;p&gt;
&lt;p&gt;Literally just like this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    .filter(|(potential, item)| match potential {
        hir::GenericArg::Const(_) =&amp;gt; item.is_type_const(),
        hir::GenericArg::Type(_) =&amp;gt; item.is_type(),
        _ =&amp;gt; false,
    })
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Annd... yeah, it works!&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:1:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt; 1 |&lt;&#x2F;span&gt; fn take(_: impl Iterator&amp;lt;0&amp;gt;) {}
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^ expected 0 generic arguments&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
   = note: -Ztrack-diagnostics: created at compiler&#x2F;rustc_hir_analysis&#x2F;src&#x2F;hir_ty_lowering&#x2F;generics.rs:575:18
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; library&#x2F;core&#x2F;src&#x2F;iter&#x2F;traits&#x2F;iterator.rs:42:17
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;42 |&lt;&#x2F;span&gt; pub const trait Iterator {
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                 &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^^^^&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No more nonsense suggestion, just the error, exactly what we wanted&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-the-test-suite&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-the-test-suite&quot; aria-label=&quot;Anchor link for: running-the-test-suite&quot;&gt;Running the Test Suite&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Great, now let&#x27;s run &lt;code&gt;.&#x2F;x test ui&lt;&#x2F;code&gt; - I&#x27;m expecting a big number of regressions in our test suite&lt;&#x2F;p&gt;
&lt;p&gt;To my surprise only two tests. Let&#x27;s look at their contents&lt;&#x2F;p&gt;
&lt;p&gt;First test: &lt;code&gt;tests&#x2F;ui&#x2F;const-generics&#x2F;issues&#x2F;issue-87493.rs&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looks like this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;pub trait MyTrait {
    type Assoc;
}

pub fn foo&amp;lt;S, T&amp;gt;(_s: S, _t: T)
where
    S: MyTrait,
    T: MyTrait&amp;lt;Assoc == S::Assoc&amp;gt;,
    &amp;#x2F;&amp;#x2F;~^ ERROR: expected one of `,` or `&amp;gt;`, found `==`
    &amp;#x2F;&amp;#x2F;~| ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
{
}

fn main() {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The original error was this&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0107]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: trait takes 0 generic arguments but 1 generic argument was supplied&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;main.rs:8:8
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 |&lt;&#x2F;span&gt;     T: MyTrait&amp;lt;Assoc == S::Assoc&amp;gt;,
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;        &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^ expected 0 generic arguments&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-green&quot;&gt;note&lt;&#x2F;span&gt;: trait defined here, with 0 generic parameters
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;main.rs:1:11
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;1 |&lt;&#x2F;span&gt; pub trait MyTrait {
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;           &lt;span class=&quot;ansi-bold af-green&quot;&gt;^^^^^^^&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 |&lt;&#x2F;span&gt;     T: MyTrait&amp;lt;&lt;span class=&quot;af-green&quot;&gt;Assoc =&lt;&#x2F;span&gt; Assoc == S::Assoc&amp;gt;,
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                &lt;span class=&quot;af-green&quot;&gt;+++++++&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You know, just for fun i decided to try writing what the compiler suggests here, and you know what i got? You&#x27;ll never guess...&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 |&lt;&#x2F;span&gt;     T: MyTrait&amp;lt;&lt;span class=&quot;af-green&quot;&gt;Assoc =&lt;&#x2F;span&gt; Assoc = Assoc == S::Assoc&amp;gt;,
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                &lt;span class=&quot;af-green&quot;&gt;+++++++&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tried it. The compiler responded with an even more broken version of the same suggestion - &lt;code&gt;Assoc = Assoc = Assoc == S::Assoc&lt;&#x2F;code&gt;. A beginner could sit there applying this forever... After our fix this problem got fixed and now it (kinda) correctly suggests the fix&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: expected one of `,` or `&amp;gt;`, found `==`&lt;&#x2F;span&gt;
 &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; &#x2F;home&#x2F;gh-Kivooeo&#x2F;test_&#x2F;src&#x2F;main.rs:8:22
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 |&lt;&#x2F;span&gt;     T: MyTrait&amp;lt;Assoc == S::Assoc&amp;gt;,
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;                      &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^ expected one of `,` or `&amp;gt;`&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
  = note: -Ztrack-diagnostics: created at compiler&#x2F;rustc_parse&#x2F;src&#x2F;parser&#x2F;diagnostics.rs:2528:34
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: if you meant to use an associated type binding, replace `==` with `=`
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 &lt;&#x2F;span&gt;&lt;span class=&quot;af-red&quot;&gt;-     T: MyTrait&amp;lt;Assoc == S::Assoc&amp;gt;,&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;8 &lt;&#x2F;span&gt;&lt;span class=&quot;af-green&quot;&gt;+     T: MyTrait&amp;lt;Assoc = S::Assoc&amp;gt;,&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;  |&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At least it compiles if you do what the compiler asks :)&lt;&#x2F;p&gt;
&lt;p&gt;Now let&#x27;s look at the second test&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F;! This test used to ICE: #121134
&amp;#x2F;&amp;#x2F;! The issue is that we&amp;#x27;re trying to prove a projection, but there&amp;#x27;s
&amp;#x2F;&amp;#x2F;! no bound for the projection&amp;#x27;s trait, and the projection has the wrong
&amp;#x2F;&amp;#x2F;! kind of generic parameter (lifetime vs type).
&amp;#x2F;&amp;#x2F;! When actually calling the function with those broken bounds, trying to
&amp;#x2F;&amp;#x2F;! instantiate the bounds with inference vars would ICE.
#![feature(unboxed_closures)]

trait Output&amp;lt;&amp;#x27;a&amp;gt; {
    type Type;
}

struct Wrapper;

impl Wrapper {
    fn do_something_wrapper&amp;lt;O, F&amp;gt;(&amp;amp;mut self, _: F)
    where
        F: for&amp;lt;&amp;#x27;a&amp;gt; FnOnce(&amp;lt;F as Output&amp;lt;i32&amp;gt;&amp;gt;::Type),
        &amp;#x2F;&amp;#x2F;~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
    {
    }
}

fn main() {
    let mut wrapper = Wrapper;
    wrapper.do_something_wrapper(|value| ());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anyway, some complicated code, but what&#x27;s interesting, right now the compiler suggests the following - add &lt;code&gt;Type = &lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: replace the generic bound with the associated type
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;18 |&lt;&#x2F;span&gt;         F: for&amp;lt;&#x27;a&amp;gt; FnOnce(&amp;lt;F as Output&amp;lt;&lt;span class=&quot;af-green&quot;&gt;Type =&lt;&#x2F;span&gt; i32&amp;gt;&amp;gt;::Type),
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                                        &lt;span class=&quot;af-green&quot;&gt;++++++&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And after we add &lt;code&gt;Type = i32&lt;&#x2F;code&gt;, it suggests this&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0229]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: associated item constraints are not allowed here&lt;&#x2F;span&gt;
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; src&#x2F;main.rs:18:40
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;18 |&lt;&#x2F;span&gt;         F: for&amp;lt;&#x27;a&amp;gt; FnOnce(&amp;lt;F as Output&amp;lt;Type = i32&amp;gt;&amp;gt;::Type),
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;                                        &lt;span class=&quot;ansi-bold af-red&quot;&gt;^^^^^^^^^^ associated item constraint not allowed here&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-cyan&quot;&gt;help&lt;&#x2F;span&gt;: consider removing this associated item binding
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;18 &lt;&#x2F;span&gt;&lt;span class=&quot;af-red&quot;&gt;-         F: for&amp;lt;&#x27;a&amp;gt; FnOnce(&amp;lt;F as Output&amp;lt;Type = i32&amp;gt;&amp;gt;::Type),&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;18 &lt;&#x2F;span&gt;&lt;span class=&quot;af-green&quot;&gt;+         F: for&amp;lt;&#x27;a&amp;gt; FnOnce(&amp;lt;F as Output&amp;lt;&amp;gt;&amp;gt;::Type),&lt;&#x2F;span&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What...? Yeah, this was kinda to the point about diagnostics not being perfect in the compiler. Anyway i ran around in circles for a pretty long time trying to do what the compiler suggests, and in the end it just didn&#x27;t compile&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, i think this isn&#x27;t our problem anymore :)&lt;&#x2F;p&gt;
&lt;p&gt;The very fact that the compiler no longer suggests adding &lt;code&gt;Type =&lt;&#x2F;code&gt; here is already a win, and the other diagnostics fall out of scope of this fix&lt;&#x2F;p&gt;
&lt;p&gt;So with a calm soul we update the tests so they run with the new expected output. For the first one we just run with &lt;code&gt;--bless&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;$ .&amp;#x2F;x test tests&amp;#x2F;ui&amp;#x2F;const-generics&amp;#x2F;issues&amp;#x2F;issue-87493.rs tests&amp;#x2F;ui&amp;#x2F;traits&amp;#x2F;generic_param_mismatch_in_unsatisfied_projection.rs --bless
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now we look&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;running 2 tests
..

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 21417 filtered out; finished in 51.58ms
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Perfect!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#wrapping-up&quot; aria-label=&quot;Anchor link for: wrapping-up&quot;&gt;Wrapping Up&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now, the last thing left to do is write a new test and add @fmease&#x27;s suggestion to change the wording of this error&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;format!(
-    &amp;quot;replace the generic bound{s} with the associated type{s}&amp;quot;,
+    &amp;quot;turn the generic argument{s} into an associated item binding{s}&amp;quot;,
    s = pluralize!(unbound_types.len())
)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let&#x27;s add a new test, if you don&#x27;t know how to do that i suggest you read the &lt;a href=&quot;&#x2F;blog&#x2F;e-needs-test&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt; about adding tests!&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what our test will look like&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F;! Regression test for &amp;lt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;rust-lang&amp;#x2F;rust&amp;#x2F;issues&amp;#x2F;151602&amp;gt;.

#![feature(min_generic_const_args)]

trait Trait {
    type const K: i32;
}
fn take(_: impl Trait&amp;lt;0&amp;gt;) {}
&amp;#x2F;&amp;#x2F;~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied [E0107]

fn main() {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since we changed the error wording, we&#x27;ll need to run all the tests again and update the &lt;code&gt;.stderr&lt;&#x2F;code&gt; files for all of them&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;$ .&amp;#x2F;x test ui --bless
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I think after that the only thing left is to open the pull request and assign @fmease to it (using &lt;code&gt;r?&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happens-next&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-happens-next&quot; aria-label=&quot;Anchor link for: what-happens-next&quot;&gt;What Happens Next?&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;While the tests are running, let&#x27;s talk about this for a sec. I actually admit there might be some edge cases in this fix or the test, I&#x27;m not super familiar with the MGCA feature, even though i wrote the Ctor support and a couple other things for it. That was more thanks to the great mentorship and review from @BoxyUwU&lt;&#x2F;p&gt;
&lt;p&gt;Also a lot of useful info on this matter was said &lt;a href=&quot;&#x2F;blog&#x2F;e-needs-test&#x2F;#what-to-expect-during-review&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Well, it seems tests are compiled fine, except one test which requiers me to update the error:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;fn trait_bound_generic&amp;lt;I: T&amp;lt;u8, u16&amp;gt;&amp;gt;(_i: I) {
    &amp;#x2F;&amp;#x2F;~^ ERROR trait takes 0 generic arguments
-    &amp;#x2F;&amp;#x2F;~| HELP replace the generic bounds with the associated types
+    &amp;#x2F;&amp;#x2F;~| HELP turn the generic arguments into an associated item bindings
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So it felt to me that fix is very ready for being published, let&#x27;s run &lt;code&gt;.&#x2F;x test tidy&lt;&#x2F;code&gt; to make very sure before opening a PR. Good, &lt;code&gt;tidy&lt;&#x2F;code&gt; seems fine about it&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Build completed successfully in 0:00:41
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next step is to open a PR (done &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;157908&quot;&gt;here&lt;&#x2F;a&gt;), assign @fmease with &lt;code&gt;r?&lt;&#x2F;code&gt; and... well, that&#x27;s basically it - now we wait :)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-review-comes-back&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-review-comes-back&quot; aria-label=&quot;Anchor link for: the-review-comes-back&quot;&gt;The Review Comes Back&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So the wait wasn&#x27;t that long actually, and @fmease left a few comments. And honestly this is the part i enjoy the most - when someone who knows the area way better than you looks at your code and points at the spots you were too eager to skim past&lt;&#x2F;p&gt;
&lt;p&gt;The first and the most important one was about my filter. Remember this part?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;.filter(|(potential, item)| match potential {
    hir::GenericArg::Const(_) =&amp;gt; item.is_type_const(),
    hir::GenericArg::Type(_) =&amp;gt; item.is_type(),
    _ =&amp;gt; false,
})
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looks fine right? Well, the thing is i was zipping &lt;code&gt;unused_generics&lt;&#x2F;code&gt; with &lt;code&gt;unbound_types&lt;&#x2F;code&gt; &lt;strong&gt;by position&lt;&#x2F;strong&gt;, and only then filtering by kind. But the assoc items come in definition order, and the generic args come in the order the user wrote them - there&#x27;s no reason these two line up. @fmease gave a really clean example&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;trait Trait { type A; type const B: usize; }
fn f&amp;lt;T: Trait&amp;lt;(), 0&amp;gt;&amp;gt;(); &amp;#x2F;&amp;#x2F; my PR emits a suggestion
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;trait Trait { type const A: usize; type B; }
fn f&amp;lt;T: Trait&amp;lt;(), 0&amp;gt;&amp;gt;(); &amp;#x2F;&amp;#x2F; my PR does *not* emit one
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the second case the zip produces pairs like &lt;code&gt;[(TyAssocConst, Ty), (AssocTy, Const)]&lt;&#x2F;code&gt; and neither pair survives the filter, so we just silently drop a perfectly good suggestion. Oops&lt;&#x2F;p&gt;
&lt;p&gt;The fix is to stop pairing by position entirely. Instead i split the unbound items into two lazy iterators by kind, and let each generic arg pull the next item of its &lt;strong&gt;own&lt;&#x2F;strong&gt; kind&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let mut unbound_assoc_consts = unbound_assoc_items.iter().filter(|item| item.is_type_const());
let mut unbound_assoc_types = unbound_assoc_items.iter().filter(|item| item.is_type());
let suggestions = unused_generics
    .iter()
    .filter_map(|potential| {
        let item = match potential {
            hir::GenericArg::Const(_) =&amp;gt; unbound_assoc_consts.next(),
            hir::GenericArg::Type(_) =&amp;gt; unbound_assoc_types.next(),
            _ =&amp;gt; None,
        }?;
        Some((
            potential.span().shrink_to_lo(),
            &amp;#x2F;&amp;#x2F; FIXME: This doesn&amp;#x27;t account for generic associated items
            format!(&amp;quot;{} = &amp;quot;, self.tcx.item_ident(item.def_id)),
        ))
    })
    .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each &lt;code&gt;.next()&lt;&#x2F;code&gt; advances its own cursor, so a type arg always grabs the next assoc type and a const the next assoc const, no matter how they&#x27;re interleaved - and &lt;code&gt;?&lt;&#x2F;code&gt; just bails (emitting nothing) if a queue runs dry instead of mispairing&lt;&#x2F;p&gt;
&lt;p&gt;The second comment was a tiny but nice one. The wording&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;quot;turn the generic argument{s} into an associated item binding{s}&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;reads totally fine in singular, but the moment you have more than one it becomes &quot;turn the generic arguments into &lt;strong&gt;an&lt;&#x2F;strong&gt; associated item bindings&quot; which is, well, not english. So the &lt;code&gt;an&lt;&#x2F;code&gt; should only show up when there&#x27;s exactly one. Quick fix&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let s = pluralize!(suggestions.len());
let article = if suggestions.len() == 1 { &amp;quot;an &amp;quot; } else { &amp;quot;&amp;quot; };
err.multipart_suggestion(
    format!(&amp;quot;turn the generic argument{s} into {article}associated item binding{s}&amp;quot;),
    suggestions,
    Applicability::MaybeIncorrect,
);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also notice i switched the pluralization from &lt;code&gt;unbound_types.len()&lt;&#x2F;code&gt; to &lt;code&gt;suggestions.len()&lt;&#x2F;code&gt; - now that not every excess arg necessarily produces a binding, the count should reflect what we actually suggest&lt;&#x2F;p&gt;
&lt;p&gt;Then there was the comment above the whole block, which was honestly just a bit outdated. It still said&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F; If there is a single unbound associated type and a single excess generic param
&amp;#x2F;&amp;#x2F; suggest replacing the generic param with the associated type bound
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but the code handles multiple of them now, and assoc consts too, not only types. @fmease suggested generalizing it&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F; If there is an identical amount of unbound associated items and excess generic args
&amp;#x2F;&amp;#x2F; suggest turning the generic args into associated item bindings.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;with a funny little caveat that even &quot;identical amount&quot; isn&#x27;t strictly true anymore after my kind-matching change (equal counts no longer guarantee a full set of bindings, since a type only pairs with a type and a const with a const). But it&#x27;s still way better than the old wording, so in it goes&lt;&#x2F;p&gt;
&lt;p&gt;And the last one - @fmease asked me to drop a &lt;code&gt;&#x2F;&#x2F; FIXME: This doesn&#x27;t account for generic associated items&lt;&#x2F;code&gt; right above the &lt;code&gt;format!(&quot;{} = &quot;, …)&lt;&#x2F;code&gt;, since that&#x27;s the bit that can&#x27;t express a generic assoc item like &lt;code&gt;type Assoc&amp;lt;T&amp;gt;;&lt;&#x2F;code&gt; (we&#x27;d produce &lt;code&gt;Assoc =&lt;&#x2F;code&gt; with nowhere to put its generics). A separate (preexisting) bug, but a &lt;code&gt;FIXME&lt;&#x2F;code&gt; is the honest thing to leave behind&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-tip&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Tip&lt;&#x2F;div&gt;
&lt;p&gt;Don&#x27;t be shy to leave &lt;code&gt;FIXME&lt;&#x2F;code&gt;s. A &lt;code&gt;FIXME&lt;&#x2F;code&gt; that names a real limitation is much more useful than pretending the code is perfect - it&#x27;s basically a little note to the next person (or future you)&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;h2 id=&quot;round-two-of-nits&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#round-two-of-nits&quot; aria-label=&quot;Anchor link for: round-two-of-nits&quot;&gt;Round Two of Nits&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I pinged &lt;code&gt;@rustbot ready&lt;&#x2F;code&gt; and, like clockwork, a second smaller round came back. This one was the comfy kind - all naming and wording, nothing scary&lt;&#x2F;p&gt;
&lt;p&gt;The running theme was &quot;make names tell the truth&quot;: a variable still called &lt;code&gt;unbound_types&lt;&#x2F;code&gt; was actually holding assoc consts too by now, so it got an honest rename, a one-off helper with a misleading name got inlined away, and a comment that said generic &lt;em&gt;param&lt;&#x2F;em&gt; where it meant generic &lt;em&gt;arg&lt;&#x2F;em&gt; got fixed (this corner of the compiler mixes those two up constantly)&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-important&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Important&lt;&#x2F;div&gt;
&lt;p&gt;A big chunk of review comments are exactly this - a name, a word, a stale comment. It&#x27;s not &quot;you did it wrong&quot;, it&#x27;s just how code stays readable for whoever touches it next, and it&#x27;s the easiest kind of feedback to address&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;He also asked for one more test: that we &lt;em&gt;don&#x27;t&lt;&#x2F;em&gt; suggest nonsense for a plain &lt;code&gt;Iterator&amp;lt;0&amp;gt;&lt;&#x2F;code&gt;. So i extended some test under &lt;code&gt;tests&#x2F;ui&#x2F;suggestions&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;pub trait T&amp;lt;X, Y&amp;gt; {
    type A;
    type B;
    type C;
}
pub struct Foo {
    i: Box&amp;lt;dyn T&amp;lt;usize, usize, usize, usize, B = usize&amp;gt;&amp;gt;,
    &amp;#x2F;&amp;#x2F;~^ ERROR trait takes 2 generic arguments but 4 generic arguments were supplied
}

fn take(_: impl Iterator&amp;lt;0&amp;gt;) {} &amp;#x2F;&amp;#x2F; &amp;lt;- here is what i&amp;#x27;ve actually added !!!
&amp;#x2F;&amp;#x2F;~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied

fn main() {}

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The whole point is the &lt;code&gt;.stderr&lt;&#x2F;code&gt; has &lt;em&gt;no&lt;&#x2F;em&gt; &quot;turn the generic argument&quot; help - &lt;code&gt;Iterator&lt;&#x2F;code&gt; has an assoc type but no assoc const, so the const queue is empty and we suggest nothing, exactly as intended&lt;&#x2F;p&gt;
&lt;p&gt;After all that the suggestion finally does the right thing even in the weird ordering cases, the grammar is correct in both singular and plural, the names say what they mean, and the comment doesn&#x27;t lie anymore&lt;&#x2F;p&gt;
&lt;p&gt;And now this is ready for merge 🎉 🎉 🎉&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-i-hope-you-take-from-this&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-i-hope-you-take-from-this&quot; aria-label=&quot;Anchor link for: what-i-hope-you-take-from-this&quot;&gt;What I Hope You Take From This&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;If there&#x27;s one thing i want you to leave with, it&#x27;s that you really don&#x27;t need to understand the whole compiler to make a diagnostic better. We took something that suggested complete nonsense, followed &lt;code&gt;-Ztrack-diagnostics&lt;&#x2F;code&gt; to the rough spot, found the exact code with a lazy grep, and made the suggestion only show up when it actually makes sense&lt;&#x2F;p&gt;
&lt;p&gt;A-diagnostics issues are great for this - a lot of them sit comfortably in the easy-to-medium range, they&#x27;re user-facing so your work is immediately visible, and the people you&#x27;ll meet along the way are genuinely kind&lt;&#x2F;p&gt;
&lt;p&gt;So if any of this looked fun - go pick one, grep around, ask questions, and don&#x27;t be afraid to be wrong. That&#x27;s literally how all of us started&lt;&#x2F;p&gt;
&lt;p&gt;And honestly, if you wanna try one but feel a little lost - you can just assign me as your reviewer with &lt;code&gt;r? @Kivooeo&lt;&#x2F;code&gt; (or ping me anywhere), i&#x27;m always happy to mentor newcomers on any kind of issues&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;On a side note, if you want to support future blog posts, my work on the compiler and mentoring newcomers, i&#x27;d be really grateful if you took a look at my &lt;a href=&quot;&#x2F;sponsor&quot;&gt;sponsor page&lt;&#x2F;a&gt; &amp;lt;3&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Part 1: Tackling an `E-needs-test` issue</title>
        <published>2026-02-14T00:00:00+00:00</published>
        <updated>2026-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/blog/e-needs-test/"/>
        <id>https://kivooeo.github.io/blog/e-needs-test/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/blog/e-needs-test/">&lt;p&gt;In this part, I want to cover how I would tackle an issue labeled &lt;code&gt;E-needs-test&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll also be mentoring a Google Summer of Code project this year, and it&#x27;s test-suite related - so if you&#x27;re interested, you can read more about it &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;google-summer-of-code?tab=readme-ov-file#reorganisation-of-testsuiissues&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given that this isn&#x27;t a very time-consuming task, I expect this post won&#x27;t be very long. I&#x27;ll document everything as I go - you&#x27;ll see my actual thought process and decisions in real-time&lt;&#x2F;p&gt;
&lt;h2 id=&quot;selecting-and-studying-an-issue&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#selecting-and-studying-an-issue&quot; aria-label=&quot;Anchor link for: selecting-and-studying-an-issue&quot;&gt;Selecting and Studying an Issue&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s head over to &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20no%3Aassignee%20label%3AE-needs-test&quot;&gt;GitHub&lt;&#x2F;a&gt; to search for issues. Looking at the list, I&#x27;ll pick the first available issue. I don&#x27;t think it will make a big difference, and to be honest, picking one at random for content isn&#x27;t a bad idea either&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;ve selected an &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;147958&quot;&gt;issue&lt;&#x2F;a&gt;, now let&#x27;s see what&#x27;s going on. According to the issue description, this code used to cause the compiler to panic when trying to compile it. However, according to the last comment, the problem was fixed in one of the pull requests, even though the issue itself is still open. Therefore, we want to add a test using this code example that used to panic, to lock in the new correct behavior and ensure that it now works as expected&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tackling-the-problem&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tackling-the-problem&quot; aria-label=&quot;Anchor link for: tackling-the-problem&quot;&gt;Tackling the Problem&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So, now that we&#x27;ve looked into the issue&#x27;s context, let&#x27;s start taking action. Let&#x27;s open a code editor, and navigate to forked repository, and create a new branch for pull request. I&#x27;m just going to do what I normally do (to be honest, I still don&#x27;t feel very confident using Git, so I might do something a bit odd or not the usual way):&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-tip&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Tip&lt;&#x2F;div&gt;
&lt;p&gt;If you&#x27;re also not confident with Git, that&#x27;s totally fine - the commands I show here work reliably, and the worst case is that reviewers will help you fix any Git issues&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ git checkout -b add-regression-test-1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And also, to ensure I&#x27;ve a clean and up-to-date branch, I run:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ git fetch upstream
$ git reset --hard upstream&amp;#x2F;main
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;admonition admonition-warning&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Fair warning&lt;&#x2F;div&gt;
&lt;p&gt;&lt;code&gt;reset --hard&lt;&#x2F;code&gt; will discard all your uncommitted local changes. Make sure you don&#x27;t have any unsaved work before running this command. I always verify this first, which is why I use it safely&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;div class=&quot;admonition admonition-note&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Note&lt;&#x2F;div&gt;
&lt;p&gt;This fetches the latest changes from the main Rust repository and resets branch to match it exactly&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;Now let&#x27;s figure out where to add a new test. Since it&#x27;ll be a UI test, I should find the appropriate subdirectory to place it. Since the issue was titled &quot;resolve: &lt;code&gt;no entry found for key&lt;&#x2F;code&gt;&quot;, it&#x27;s clear this is a name resolution problem, which means the test should go in the resolve directory&lt;&#x2F;p&gt;
&lt;p&gt;Also a very small tip on how can you determine the directory, because in your case it might not be specified in the issue&#x27;s title, in that case feel free to look at labels on that issue, it&#x27;s very likely do have labels like &lt;code&gt;A-resolve&lt;&#x2F;code&gt; or &lt;code&gt;A-macros&lt;&#x2F;code&gt; like in my case, and you can search for this words in &lt;code&gt;tests&#x2F;ui&#x2F;README.md&lt;&#x2F;code&gt;, also, try to use your own intuition to understand what is tested in that test (sometimes it&#x27;s not very obvious, I completely relate that part)&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s open &lt;code&gt;tests&#x2F;ui&#x2F;README.md&lt;&#x2F;code&gt; and search for &quot;resolve&quot;, to see what&#x27;s available:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ code tests&amp;#x2F;ui&amp;#x2F;README.md
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I use Ctrl+F to search for &#x27;resolve&#x27;. Aha, there it is: there&#x27;s a directory with the exact name I need:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;h2 id=&quot;tests-ui-resolve-name-resolution&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tests-ui-resolve-name-resolution&quot; aria-label=&quot;Anchor link for: tests-ui-resolve-name-resolution&quot;&gt;&lt;code&gt;tests&#x2F;ui&#x2F;resolve&#x2F;&lt;&#x2F;code&gt;: Name resolution&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;rustc-dev-guide.rust-lang.org&#x2F;name-resolution.html&quot;&gt;Name resolution | rustc-dev-guide&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That&#x27;s exactly what I need! Now let&#x27;s think of a name for the test. It should be short and reflect what&#x27;s being tested. To help with this, let&#x27;s look at the code for the future test, which is taken from the example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;#![feature(decl_macro)]

macro_rules! exported {
    () =&amp;gt; {
        #[macro_export]
        macro_rules! exported {
            () =&amp;gt; {};
        }
    };
}
use inner1::*;
exported!();
mod inner1 {
    pub macro exported() {}
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is some really convoluted nested macro code! Honestly, I have no clue what could have gone wrong here. I tried reading yaahc&#x27;s comments on the issue, but they didn&#x27;t give me much insight, and I must admit I&#x27;m hearing about the &lt;code&gt;decl_macro&lt;&#x2F;code&gt; feature almost for the first time&lt;&#x2F;p&gt;
&lt;p&gt;I honestly don&#x27;t fully understand what this code does, but for adding a regression test, I don&#x27;t need to - the bug was already fixed, I just need to make sure this code compiles now&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll make a relatively generic test name and adding the issue number at the end. Something like &lt;code&gt;exported-macro-in-mod-147958&lt;&#x2F;code&gt; - honestly, I just wrote down what I see in the test itself&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ touch tests&amp;#x2F;ui&amp;#x2F;resolve&amp;#x2F;exported-macro-in-mod-147958.rs
$ code tests&amp;#x2F;ui&amp;#x2F;resolve&amp;#x2F;exported-macro-in-mod-147958.rs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So I just paste the code above into this file. The only difference is that I&#x27;ll add a directive at the very top of the test:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F;@ check-pass
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In UI tests, if you don&#x27;t specify a directive like &lt;code&gt;&#x2F;&#x2F;@ check-pass&lt;&#x2F;code&gt;, the harness assumes the test should produce errors and compares against a .stderr file&lt;&#x2F;p&gt;
&lt;p&gt;I won&#x27;t go into detail about test directives here, because there&#x27;s already good material on this topic. My focus is a bit different, but I highly recommend checking out the &lt;a href=&quot;https:&#x2F;&#x2F;rustc-dev-guide.rust-lang.org&#x2F;tests&#x2F;directives.html&quot;&gt;Rustc dev guide on directives&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Okay, now that the test is ready, let&#x27;s try running it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ .&amp;#x2F;x test tests&amp;#x2F;ui&amp;#x2F;resolve&amp;#x2F;exported-macro-in-mod-147958.rs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will start building the compiler and any necessary tools. By the way, since I expect no errors to occur, a &lt;code&gt;.stderr&lt;&#x2F;code&gt; file shouldn&#x27;t be generated, so I didn&#x27;t use the &lt;code&gt;--bless&lt;&#x2F;code&gt; flag (the one that generates the error output file)&lt;&#x2F;p&gt;
&lt;p&gt;The test didn&#x27;t pass...&lt;&#x2F;p&gt;
&lt;pre class=&quot;term&quot;&gt;running 1 tests

[ui] tests&#x2F;ui&#x2F;resolve&#x2F;exported-macro-in-mod-147958.rs ... F


failures:

---- [ui] tests&#x2F;ui&#x2F;resolve&#x2F;exported-macro-in-mod-147958.rs stdout ----
Saved the actual stderr to `&#x2F;home&#x2F;gh-Kivooeo&#x2F;r&#x2F;rust&#x2F;build&#x2F;aarch64-unknown-linux-gnu&#x2F;test&#x2F;ui&#x2F;resolve&#x2F;exported-macro-in-mod-147958&#x2F;exported-macro-in-mod-147958.stderr`
normalized stderr:
&lt;span class=&quot;ansi-bold af-red&quot;&gt;error[E0601]&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: `main` function not found in crate `exported_macro_in_mod_147958`&lt;&#x2F;span&gt;
  &lt;span class=&quot;ansi-bold af-blue&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt; $DIR&#x2F;exported-macro-in-mod-147958.rs:15:2
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;LL |&lt;&#x2F;span&gt; }
&lt;span class=&quot;ansi-bold af-blue&quot;&gt;   |&lt;&#x2F;span&gt;  &lt;span class=&quot;ansi-bold af-red&quot;&gt;^ consider adding a `main` function to `$DIR&#x2F;exported-macro-in-mod-147958.rs`&lt;&#x2F;span&gt;

&lt;span class=&quot;ansi-bold af-red&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;ansi-bold&quot;&gt;: aborting due to 1 previous error&lt;&#x2F;span&gt;

For more information about this error, try `rustc --explain E0601`.&lt;&#x2F;pre&gt;
&lt;p&gt;Ah, I forgot to add a &lt;code&gt;main&lt;&#x2F;code&gt; function. Of course, I could have added a directive like &lt;code&gt;&#x2F;&#x2F;@ compile-flags: --crate-type lib&lt;&#x2F;code&gt; to indicate this is a library, but I&#x27;m more used to just adding an empty &lt;code&gt;main&lt;&#x2F;code&gt; function&lt;&#x2F;p&gt;
&lt;p&gt;Alright, that&#x27;s it. I can also run &lt;code&gt;.&#x2F;x test tidy&lt;&#x2F;code&gt; just to make sure there&#x27;s no trailing whitespace and that I didn&#x27;t forget a newline at the end of the file&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition admonition-note&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Note&lt;&#x2F;div&gt;
&lt;p&gt;tidy checks formatting, whitespace, file placement, and other repository conventions&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;Now I can prepare the pull request. To do that I ran the following commands:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;user@machine ~&amp;#x2F;r&amp;#x2F;rust (add-regression-test-1)&amp;gt; git add .
user@machine ~&amp;#x2F;r&amp;#x2F;rust (add-regression-test-1)&amp;gt; git commit -m &amp;quot;add regression test&amp;quot;
user@machine ~&amp;#x2F;r&amp;#x2F;rust (add-regression-test-1)&amp;gt; git push --force-with-lease origin add-regression-test-1 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;admonition admonition-note&quot; role=&quot;note&quot;&gt;
&lt;div class=&quot;admonition-title&quot;&gt;Note&lt;&#x2F;div&gt;
&lt;p&gt;&lt;code&gt;--force-with-lease&lt;&#x2F;code&gt; isn&#x27;t needed for a new branch, but I use it out of habit&lt;&#x2F;p&gt;

&lt;&#x2F;div&gt;
&lt;p&gt;I think everything is ready, so let&#x27;s go to GitHub. I&#x27;ll open my fork, switch to the branch I created for this pull request, and click the big &quot;Contribute -&amp;gt; Open pull request&quot; button&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll keep the description minimal, since there is not much to tell about this PR. I titled it &quot;add regression test for 147958&quot; and I just left the description as &quot;fixes #147958&quot;, so that the issue will be closed after merging the pull request&lt;&#x2F;p&gt;
&lt;p&gt;Since I don&#x27;t know who should do the review, I left it like that. Usually, you can write something like &lt;code&gt;r? team&lt;&#x2F;code&gt; (e.g. &lt;code&gt;r? compiler&lt;&#x2F;code&gt;) or a specific member like &lt;code&gt;r? Kivooeo&lt;&#x2F;code&gt;. If you don&#x27;t specify anyone, rustbot will pick the most appropriate free reviewer in rotation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;And that&#x27;s it. Pull request was created &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;152732&quot;&gt;here&lt;&#x2F;a&gt;. Rustbot assigned TaKO8Ki as the reviewer, so now I wait for review. I&#x27;m not 100% sure about this test since I&#x27;m not familiar with this feature, but I fully expect it to be approved. You can also check the reviewer&#x27;s GitHub profile to see their recent activity - I often do this myself, although I don&#x27;t really have any specific expectations. Reviews can take up to two weeks before you can re-request a review if needed&lt;&#x2F;p&gt;
&lt;p&gt;Given the size and simplicity of this PR, I&#x27;m expecting a pretty quick approval. The most likely outcome is that another contributor will approve it or suggest corrections&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-oversight&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#an-oversight&quot; aria-label=&quot;Anchor link for: an-oversight&quot;&gt;An Oversight&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;About 30 minutes after I created the pull request, I remembered that I forgot to add a most important comment&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2F;&amp;#x2F;! Regression test for &amp;lt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;rust-lang&amp;#x2F;rust&amp;#x2F;issues&amp;#x2F;147958&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On top of the test, so in future it would be easier to navigate for original issue, let&#x27;s quickly fix it!&lt;&#x2F;p&gt;
&lt;p&gt;So all I do is just add this comment, final test looks this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&amp;#x2F;&amp;#x2F;! Regression test for &amp;lt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;rust-lang&amp;#x2F;rust&amp;#x2F;issues&amp;#x2F;147958&amp;gt;

&amp;#x2F;&amp;#x2F;@ check-pass

#![feature(decl_macro)]

macro_rules! exported {
    () =&amp;gt; {
        #[macro_export]
        macro_rules! exported {
            () =&amp;gt; {};
        }
    };
}
use inner1::*;
exported!();
mod inner1 {
    pub macro exported() {}
}

fn main() {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here I have an empty &lt;code&gt;main&lt;&#x2F;code&gt; function, and a comment with link to the issue, btw, worth noting that while many regression tests don&#x27;t include this comment (and that&#x27;s totally okay), I personally find it really helpful to have the direct link. I also pretty often see comment like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2F;&amp;#x2F;! Test for #31233
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which makes it pretty hard to follow an actual issue, ctrl + click by link is way faster and easier&lt;&#x2F;p&gt;
&lt;p&gt;Next what I do is some &lt;code&gt;git&lt;&#x2F;code&gt; magic, at least this is how I see this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;$ git add .
$ git commit --amend --no-edit
$ git push --force-with-lease origin add-regression-test-1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that&#x27;s 100% ready :)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-to-expect-during-review&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-to-expect-during-review&quot; aria-label=&quot;Anchor link for: what-to-expect-during-review&quot;&gt;What to expect during review&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now let&#x27;s talk a bit about what you can expect from the review process itself. I won&#x27;t be able to show this part directly in the blog post, but readers can check out the pull request I created above to see if there&#x27;s any review activity. I fully expect there might be some requested changes to my pull request, but let me describe the most common scenarios that might happen after you create your PR:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;CI fails due to tidy issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There might be trailing whitespaces&lt;&#x2F;li&gt;
&lt;li&gt;You forgot to add a newline at the end of the file&lt;&#x2F;li&gt;
&lt;li&gt;You created a test in the root of &lt;code&gt;tests&#x2F;ui&lt;&#x2F;code&gt; - which has been recently prohibited, tests must now be in subdirectories&lt;&#x2F;li&gt;
&lt;li&gt;You used an unclear test name - we now discourage names like &lt;code&gt;issue-123.rs&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You&#x27;ll be asked to rename the test, and the reviewer will likely suggest a more appropriate name&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You&#x27;ll be asked to move the test to a more suitable directory&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You&#x27;ll be asked to modify the test in some way:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Add a comment&lt;&#x2F;li&gt;
&lt;li&gt;Change or add directives&lt;&#x2F;li&gt;
&lt;li&gt;Adjust the test code itself&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;These are all completely normal situations that just need small fixes. Think of review feedback as collaborative teamwork and suggestions for improvement, not as criticism of your work. Every contributor goes through this!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;Conclusion&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s it! We went from finding an issue to submitting a PR in about 15-20 minutes. &lt;code&gt;E-needs-test&lt;&#x2F;code&gt; issues are perfect first contributions because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;They&#x27;re low-risk (just adding a test, not changing compiler logic)&lt;&#x2F;li&gt;
&lt;li&gt;The solution is usually straightforward (the bug is already fixed)&lt;&#x2F;li&gt;
&lt;li&gt;You get familiar with the test suite structure&lt;&#x2F;li&gt;
&lt;li&gt;You learn the PR workflow without much pressure&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;It is important to add at the end that, depending on the issue itself, the process may differ slightly, for example, a different directory for the test or the test will expect an error output (i.e., the creation of a &lt;code&gt;.stderr&lt;&#x2F;code&gt; file), so you may have questions. If you want to try adding a test or solving an issue labeled &lt;code&gt;E-needs-test&lt;&#x2F;code&gt;, but are stuck or feel like you don&#x27;t know something, you can &lt;a href=&quot;https:&#x2F;&#x2F;rust-lang.zulipchat.com&#x2F;#narrow&#x2F;dm&#x2F;675515-Kivooeo&quot;&gt;write to me in private messages&lt;&#x2F;a&gt; on Zulip and&#x2F;or assign me as a reviewer using &lt;code&gt;r? Kivooeo&lt;&#x2F;code&gt; in the description. Thank you to everyone who works on Rust and everyone who will work on it in the future!&lt;&#x2F;p&gt;
&lt;p&gt;In the next part I&#x27;m planning to take some A-diagnostics issue, to actually fix some error messages, yay!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;On a side note, if you want to support the release of future blog posts, my work on the compiler, mentoring newcomers and GSoC students, I&#x27;d be very grateful if you could take a look at my &lt;a href=&quot;&#x2F;sponsor&quot;&gt;sponsor page&lt;&#x2F;a&gt; &amp;lt;3&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>So You Want to Contribute to Rust</title>
        <published>2026-01-28T00:00:00+00:00</published>
        <updated>2026-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/blog/first-part-of-contibuting/"/>
        <id>https://kivooeo.github.io/blog/first-part-of-contibuting/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/blog/first-part-of-contibuting/">&lt;p&gt;&lt;em&gt;Before we start:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This post is long and detailed on purpose. It&#x27;s not meant to be read linearly or &quot;from start to finish&quot;. If you&#x27;re just getting started, it&#x27;s perfectly fine to read only the parts that feel useful right now and ignore the rest until later&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;Have you ever opened the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&quot;&gt;rust-lang&#x2F;rust&lt;&#x2F;a&gt; repo and felt overwhelmed by the sheer number of files, tests, and issues? Like you&#x27;re stuck in &quot;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Analysis_paralysis&quot;&gt;analysis paralysis&lt;&#x2F;a&gt;&quot; - so many options and so much complexity that you freeze and don&#x27;t know where to start. If you feel ambitious and&#x2F;or have time and energy to help people around the world and support your favorite programming language? Please, pull up a chair - this story is for you!&lt;&#x2F;p&gt;
&lt;p&gt;To be honest, I personally didn&#x27;t have that stuck feeling at start, but most people who ask me how to get started do&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-something-to-work-on&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#finding-something-to-work-on&quot; aria-label=&quot;Anchor link for: finding-something-to-work-on&quot;&gt;Finding Something to Work On&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;First, let&#x27;s go to the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&quot;&gt;rust-lang&#x2F;rust&lt;&#x2F;a&gt; repo. (Important note: this applies to other Rust repos like &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust-clippy&quot;&gt;clippy&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rustfmt&quot;&gt;rustfmt&lt;&#x2F;a&gt; too - they also need contributors) Now stop for a moment and ask yourself: do you know what you want to work on?&lt;&#x2F;p&gt;
&lt;p&gt;If your answer is &quot;no&quot;, that&#x27;s totally fine! A good first step is to start looking for an interesting task in this huge space of issues. There are tons of things to do - some exciting and some more routine. Here are a few beginner-friendly areas you might start with:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20no%3Aassignee%20label%3AA-diagnostics&quot;&gt;Diagnostics&lt;&#x2F;a&gt;: This is the part of the compiler that handles our error messages. You can help make these messages clearer or fix cases where the current message is confusing or misleading&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20no%3Aassignee%20label%3AE-needs-test&quot;&gt;E-needs-test label&lt;&#x2F;a&gt;: Rust&#x27;s test suite is enormous but still incomplete. An issue with this label has a bug fixed in the code but no test was added. You can add a test case to capture that fix so it doesn&#x27;t accidentally break in the future. These tasks usually involve small changes and are very valuable&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20no%3Aassignee%20label%3AE-mentor&quot;&gt;E-mentor label&lt;&#x2F;a&gt;: This label means a mentor has offered to help with the issue. It&#x27;s perfect for newcomers because you&#x27;ll have someone experienced ready to answer your questions as you work on it&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;E-easy: I don&#x27;t really want to recommend it because this particular label often attracts a lot of attention and a kind of battle for the issue begins&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues?q=is%3Aissue%20state%3Aopen%20label%3AC-enhancement%20no%3Aassignee&quot;&gt;C-enhancement&lt;&#x2F;a&gt;: could be useful, it&#x27;s not always about the code and might be less stressfull&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;my-first-contribution-story&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#my-first-contribution-story&quot; aria-label=&quot;Anchor link for: my-first-contribution-story&quot;&gt;My First Contribution Story&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let me digress a bit and share how I made my first contribution to the Rust compiler. One evening I was relaxing with no plans and watching a &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=5MIsMbFjvkw&quot;&gt;video&lt;&#x2F;a&gt; by Tsoding about Rust. In it, he tried to access a struct field through a raw pointer using the &lt;code&gt;-&amp;gt;&lt;&#x2F;code&gt; operator. In Rust, you can&#x27;t do that, that&#x27;s a C&#x2F;++ thing, but the compiler still knows what you meant to do. In this example, the error message was actually pretty misleading&lt;&#x2F;p&gt;
&lt;p&gt;So here is what roughly Tsoding was trying to do&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let s = Point { x: 0, y: 2 };

    let p = &amp;amp;s as *const Point;

    p-&amp;gt;x;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before my fix, the diagnostic was looks like this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;help: `xs` is a raw pointer; try dereferencing it
   |
LL |         (*p)-&amp;gt;x;
   |         ++  +
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see here, it correctly asks you to dereference it, but keep a &lt;code&gt;-&amp;gt;&lt;&#x2F;code&gt; which still isn&#x27;t a valid Rust code&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Suddenly something clicked in my head: &quot;What&#x27;s stopping me from start right now and fix that error message?&quot;, and I got excited by this idea. At that moment I had literally no open-source experience and didn&#x27;t even know git well, so I went online to learn what a pull request is and how to make one :)&lt;&#x2F;p&gt;
&lt;p&gt;After some effort, I managed to fork the repository and dive into the code. Then I instantly hit the next roadblock: &quot;There are millions of lines here - how do I find where this error message is generated?&quot; Luckily, luck was on my side. I searched the repository for a unique part of the error text and found a &lt;code&gt;.ftl&lt;&#x2F;code&gt; file - that&#x27;s a Fluent template for error messages. From there I tracked down the diagnostic struct in the code and finally found where it was being created&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I scribbled together a more-or-less working fix and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;139921&quot;&gt;submitted a PR&lt;&#x2F;a&gt;. I still didn&#x27;t understand a lot of the basics - for example, I didn&#x27;t know how to re-run the tests with the &lt;code&gt;--bless&lt;&#x2F;code&gt; flag to update expected output. Despite my inexperience, the reviewers (who are amazing people) did most of the heavy lifting, but I loved the experience. It was completely new to me. While that first PR was under review, I already started on a second one: I found another small issue and fixed it. The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;140094&quot;&gt;second PR&lt;&#x2F;a&gt; turned out to be much simpler and got merged even faster than the first&lt;&#x2F;p&gt;
&lt;p&gt;And that&#x27;s how I stayed involved in the project. I kept finding and fixing interesting problems, all while chatting and collaborating with many really cool people&lt;&#x2F;p&gt;
&lt;p&gt;Here is how that error message looks now after my and reviewers efforts:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;help: `p` is a raw pointer; try dereferencing it
   |
11 -     p-&amp;gt;x;
11 +     (*p).x;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;I&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for sticking with me through that story! Now, back to the main topic: I want to emphasize something important. Many new contributors (and this is often a mistake) focus on counting merges or commits - chasing those numbers. I believe that&#x27;s fundamentally the wrong approach and often leads to burnout. I know it sounds weird coming from someone who did 100 merges in the first 6 months just for fun ^^, but honestly, I was just enjoying learning and helping. It was only later that I realized how many that was! Trust me, don&#x27;t worry about the count - concentrate on the learning and the enjoyment&lt;&#x2F;p&gt;
&lt;p&gt;btw, there&#x27;s plenty of work you can do without writing a line of code. For example, we already talked about adding tests for &lt;code&gt;E-needs-test&lt;&#x2F;code&gt; issues. Other contributions include triaging issues, improving documentation, or helping to reproduce bugs (&lt;code&gt;E-needs-mvce&lt;&#x2F;code&gt;). These non-code contributions are also very valuable&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-practical-step-about-assigning-to-issues&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#small-practical-step-about-assigning-to-issues&quot; aria-label=&quot;Anchor link for: small-practical-step-about-assigning-to-issues&quot;&gt;Small practical step about assigning to issues&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s say you&#x27;ve found an issue you like and want to work on it. That&#x27;s great! To show others that you&#x27;re already working on it, you can use our bot (actually, there&#x27;s a real person sitting there assigning labels, who knows). - &lt;code&gt;rustbot&lt;&#x2F;code&gt;, or more specifically &lt;code&gt;@rustbot claim&lt;&#x2F;code&gt; to assign yourself and &lt;code&gt;@rustbot release&lt;&#x2F;code&gt; to remove the assignment from yourself (which is totally fine!).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;big-practical-steps&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#big-practical-steps&quot; aria-label=&quot;Anchor link for: big-practical-steps&quot;&gt;Big practical steps&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Once you&#x27;ve claimed an issue, it&#x27;s time to set up your environment. The first major step is to build the compiler (good &lt;a href=&quot;https:&#x2F;&#x2F;rustc-dev-guide.rust-lang.org&#x2F;building&#x2F;quickstart.html&quot;&gt;page&lt;&#x2F;a&gt; about it). This in average takes 10-15 minutes, usually 5-8 minutes and rarely it&#x27;s more than 30 minutes, recompiles after small changes is usually faster, so don&#x27;t worry (also using tip 2 from the end could help you with recompiling time)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you already have an idea of what you want to work on (maybe you found a bug that interests you or a feature you want to add), it&#x27;s hard to give one-size-fits-all advice - it really depends on your chosen task&lt;&#x2F;p&gt;
&lt;p&gt;One thing I will strongly encourage is: don&#x27;t be afraid to ask questions. When maintainers see someone who is genuinely interested and trying to understand, we jump in to help and explain as much as we can&lt;&#x2F;p&gt;
&lt;p&gt;Of course, asking questions out loud can be scary, and it&#x27;s totally normal to feel shy. Even if you&#x27;re hesitant, I still recommend live communication: for example, the &lt;a href=&quot;https:&#x2F;&#x2F;rust-lang.zulipchat.com&#x2F;&quot;&gt;Rust Zulip chat&lt;&#x2F;a&gt; is great for quick back-and-forth, or you can comment directly on the GitHub issue. If the person who filed the issue is a core team member, they often respond to questions there. Otherwise, someone on the team or the community will likely see your question and help out&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Here&#x27;s a somewhat surprising tip for those who are really stuck: try asking LLM for help. I know, I know - the community is skeptical about language models and no one likes spammy answers&#x2F;contributions&#x2F;PRs. I&#x27;m a reviewer too, and I know it very well. The key is &lt;em&gt;how&lt;&#x2F;em&gt; you use it&lt;&#x2F;p&gt;
&lt;p&gt;Please don&#x27;t ask the language model to write a code for you if you don&#x27;t understand it. Instead, ask specific and concrete questions about your task&lt;&#x2F;p&gt;
&lt;p&gt;For example, &quot;How do I find where this function is defined in the compiler?&quot; or &quot;What does this part of the code do?&quot;, language models are pretty good at that. Their suggestions aren&#x27;t perfect (they usually won&#x27;t know the quirks of codebase), but they can give you a starting point or point you at the right file. For some people, that little hint is enough to move forward :3&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I recently reviewed a pull request that fixed an error message with the &lt;code&gt;assert!&lt;&#x2F;code&gt; and the returned value. In that case, we needed to detect whether the &lt;code&gt;if&lt;&#x2F;code&gt; came from the &lt;code&gt;assert!&lt;&#x2F;code&gt; or not. The author&#x27;s method wasn&#x27;t perfect&lt;&#x2F;p&gt;
&lt;p&gt;I decided to conduct my own investigation to suggest a better approach, and I realised that I knew what I was looking for, but I couldn&#x27;t search for it due to my limited knowledge of regex and grep. So, I described what I was looking for to the LLM, which provided me with some &lt;code&gt;rg&lt;&#x2F;code&gt; commands. I simply copied and pasted them into the terminal and started searching with them&lt;&#x2F;p&gt;
&lt;p&gt;I found what I was looking for! I could also suggest a better, more idiomatic way for the author to rewrite it&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-you-get-stuck&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#when-you-get-stuck&quot; aria-label=&quot;Anchor link for: when-you-get-stuck&quot;&gt;When You Get Stuck&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s say you&#x27;ve opened the code and started digging in, but after a week you still feel stuck and don&#x27;t know how to proceed. That&#x27;s a very common feeling - nothing to panic about&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve hit a wall, I suggest asking for help as we&#x27;ve discussed it above: post a question on Zulip or on the GitHub issue itself (remember, you can mention people, or just write a polite question). Often the issue author or someone else will spot it and give pointers&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Another perfectly fine approach is to put the issue aside for now. Maybe you tried to make progress and realized you&#x27;re blocked or don&#x27;t have time at the moment&lt;&#x2F;p&gt;
&lt;p&gt;That happens to everyone. If you do put it on hold, leave a note in the issue about what you tried and what the obstacles were&lt;&#x2F;p&gt;
&lt;p&gt;For example: &quot;I explored the code around &lt;code&gt;X&lt;&#x2F;code&gt; and tried using &lt;code&gt;Y&lt;&#x2F;code&gt;, but I&#x27;m not sure if that&#x27;s the right approach. I&#x27;m stuck on how to proceed&quot;, yes, you didn&#x27;t fix the issue, but you&#x27;ve saved the next person who picks it up a lot of time - they&#x27;ll know where you left off and what you&#x27;ve already tried&lt;&#x2F;p&gt;
&lt;h2 id=&quot;your-first-pr&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#your-first-pr&quot; aria-label=&quot;Anchor link for: your-first-pr&quot;&gt;Your First PR&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now imagine you finally decide to tackle an issue and make your first pull request. You might wonder, &quot;What makes a good PR?&quot;, here&#x27;s the thing: any contribution is welcome. Really! Even if you&#x27;re just fixing a typo in documentation, adding a test, or cleaning up a bit of code for readability, it&#x27;s all valuable&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t like to divide contributions into &quot;good&quot; or &quot;bad.&quot; The more important part, imo, is that you did it yourself: you wrote the code and you wrote the PR description. It might be challenging at first, but we want to see your thought process and how you understand the problem. Write a clear summary of what you did in the PR so reviewers can follow along with your reasoning&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Personal example: in my first PRs, I often made suboptimal code choices (and honestly, I still do sometimes). At first I didn&#x27;t know most of the codebase. The reviewers were super helpful and always suggested a more idiomatic or correct approach.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, they might say, &quot;You don&#x27;t need to implement this yourself - there&#x27;s already a method doing this&quot;, there has never been (and I hope never will be) an occasion where someone yelled at me for writing imperfect code or doing mistakes. We all make mistakes - it&#x27;s part of learning. Even the core team members make mistakes. The reviewers&#x27; job is to help improve the code, not to shame you&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sometimes-even-a-well-crafted-pr-gets-closed&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sometimes-even-a-well-crafted-pr-gets-closed&quot; aria-label=&quot;Anchor link for: sometimes-even-a-well-crafted-pr-gets-closed&quot;&gt;Sometimes Even a Well-Crafted PR Gets Closed&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Not every contribution ends up merged - and that&#x27;s okay. Sometimes the code is fine, but the idea behind it isn&#x27;t what the community wants. Here&#x27;s a personal example:&lt;&#x2F;p&gt;
&lt;p&gt;I once submitted a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;147102&quot;&gt;PR&lt;&#x2F;a&gt; that aimed to suggest using method syntax &lt;code&gt;x.max(y)&lt;&#x2F;code&gt; when someone wrote &lt;code&gt;max(x, y)&lt;&#x2F;code&gt; but hadn&#x27;t imported the function. The fix itself was clean and worked correctly:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;   else if [&amp;quot;max&amp;quot;, &amp;quot;min&amp;quot;].contains(&amp;amp;item_str.as_str())
        &amp;amp;&amp;amp; let PathSource::Expr(Some(Expr {
            kind: ExprKind::Call(_, args),
            span: call_span,
            ..
        })) = source
        &amp;amp;&amp;amp; args.len() == 2
        &amp;amp;&amp;amp; let Some(arg0) = self.r.tcx.sess.source_map().span_to_snippet(args[0].span)
        &amp;amp;&amp;amp; let Some(arg1) = self.r.tcx.sess.source_map().span_to_snippet(args[1].span)
    {
        Some((
            *call_span,
            &amp;quot;you may have meant to use the method syntax&amp;quot;,
            format!(&amp;quot;{arg0}.{item_str}({arg1})&amp;quot;),
        ))
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some team members preferred the free function (&lt;code&gt;std::cmp::max(x, y)&lt;&#x2F;code&gt;) because it&#x27;s symmetric and feels more natural for a binary operation. The PR wasn&#x27;t rejected because of bad code - it was a stylistic disagreement&lt;&#x2F;p&gt;
&lt;p&gt;Just keep in mind, that even a &quot;failed&quot; PR is a win if you learn from it. Not every issue needs fixing the way you first think. Sometimes the best contribution is realizing when to step back&lt;&#x2F;p&gt;
&lt;h2 id=&quot;another-example-of-anti-success-of-mine&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#another-example-of-anti-success-of-mine&quot; aria-label=&quot;Anchor link for: another-example-of-anti-success-of-mine&quot;&gt;Another example of anti-success of mine&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I want to share one more personal example that might be useful, especially if you&#x27;re worried about &quot;breaking something&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Recently, I worked on a fairly large &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;150603&quot;&gt;PR&lt;&#x2F;a&gt; that introduced new logic for the MGCA feature. It wasn&#x27;t a small change: it added quite a bit of new code, went through a long review process, and required several iterations to address feedback. After many discussions and refinements, it finally got merged&lt;&#x2F;p&gt;
&lt;p&gt;The PR was well reviewed, had good test coverage, and didn&#x27;t cause any regressions in the existing test suite. At that point, everything looked solid&lt;&#x2F;p&gt;
&lt;p&gt;A few days ago, I randomly stumbled upon a new &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;151414&quot;&gt;issue&lt;&#x2F;a&gt;. I wasn&#x27;t pinged, mentioned, or otherwise notified - I just happened to see it while browsing. The issue described a problem that appeared after my PR landed&lt;&#x2F;p&gt;
&lt;p&gt;And this is the important part: this kind of thing is completely normal&lt;&#x2F;p&gt;
&lt;p&gt;Even carefully reviewed changes with good tests can expose new edge cases or interactions that weren&#x27;t obvious at the time. The compiler is a huge, complex system, and no one can predict all consequences upfront&lt;&#x2F;p&gt;
&lt;p&gt;What matters is not that a bug appeared, but how you react to it&lt;&#x2F;p&gt;
&lt;p&gt;I assigned the issue to myself and left a short note saying that I&#x27;d take a look when I had time. Not because I felt guilty, but because this is simply part of the responsibility that comes with contributing. Fixing follow-up issues, investigating regressions, and iterating on previous changes is a normal and expected part of the process&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sharing this to make one thing clear: introducing a bug does not make you a bad contributor, but ignoring it may&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dealing-with-reviews-and-ci&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dealing-with-reviews-and-ci&quot; aria-label=&quot;Anchor link for: dealing-with-reviews-and-ci&quot;&gt;Dealing with Reviews and CI&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So you sent your first pull request - great job, that&#x27;s a big achievement by itself! After that the CI will automatically start, it will build compiler, check &lt;code&gt;tidy&lt;&#x2F;code&gt;, style, all tests, and maybe something else, it took approx. about hour, so.. be ready&lt;&#x2F;p&gt;
&lt;p&gt;Also, if your CI fails, don&#x27;t be afraid of it. It&#x27;s perfectly normal, even for the most skilled top-tier Rust contributors. It&#x27;s so easy to miss something in the CI checks and cause a failure. Our bot will politely tell you exactly what failed and most likely tell you how to fix it. Just force-push the fix and move on. We all see it daily and fail CI ourselves :3&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Now let&#x27;s talk about what happens during review. You might worry: &quot;Will strict people come and nitpick every little thing in my code, just to embarrass me?&quot; Absolutely not. If the review process seems picky, keep in mind it&#x27;s not personal. Reviewers are not judging you as a person; they&#x27;re focused on the code. When someone asks you to fix a bunch of small issues, it&#x27;s only to improve the project, not to discourage you&lt;&#x2F;p&gt;
&lt;p&gt;As a newcomer, you might not immediately understand what a reviewer is asking for. That&#x27;s okay. Feel free to ask for clarification. Just comment on the review saying something like &quot;Could you help me understand this comment?&quot; Everyone was new once, and they will help you understand the feedback&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Sometimes review comments can sound a bit harsh or blunt. Remember, that&#x27;s usually just a tone issue - it&#x27;s much easier to criticize code than to criticize a person. Try to interpret comments as suggestions on the code. If something stings, don&#x27;t take it personally. You and your contribution matter to us, and we want to see you succeed&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you get a review and they ask you to make a change, but you&#x27;re not sure what they mean. Perhaps you&#x27;ve been staring at your editor for days, too intimidated to ask, and you feel like you&#x27;ve lost all sense of direction. Or maybe you immediately reach out and ask a reviewer for a clarification on something really simple, and they point out &quot;oh, it was literally 5 lines above your current code.&quot; Both situations happen to everyone&lt;&#x2F;p&gt;
&lt;p&gt;The balance is: try solving it yourself first, but not at the cost of burning out. If you spend a reasonable time trying to figure out the requested change and still can&#x27;t do it, that&#x27;s okay. Just go back to the reviewer and explain what you tried and where you&#x27;re stuck. For example: &quot;I tried inserting this line here and running the test, but it still fails with X. I&#x27;m not sure how to fix it.&quot; This shows you made an effort, and trust me, reviewers deeply appreciate when you explain your attempts. It makes it easier for them to help you and keeps the collaboration going smoothly&lt;&#x2F;p&gt;
&lt;h2 id=&quot;useful-resources&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#useful-resources&quot; aria-label=&quot;Anchor link for: useful-resources&quot;&gt;Useful resources&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;rustc-dev-guide.rust-lang.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;rustc-dev-guide.rust-lang.org&#x2F;&lt;&#x2F;a&gt; - your primary handbook for everything compiler related&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;forge.rust-lang.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;forge.rust-lang.org&#x2F;&lt;&#x2F;a&gt; - policies, procedures, and team information&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;random-tips&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#random-tips&quot; aria-label=&quot;Anchor link for: random-tips&quot;&gt;Random tips&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;They are not necesessary, but you may found them useful, they initally were in text, but I decided factor them out to its own chapter&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-1&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tip-1&quot; aria-label=&quot;Anchor link for: tip-1&quot;&gt;Tip 1&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;there are compiler flag, that might help you figuring out where error message was created &lt;code&gt;-Ztrack-diagnostics&lt;&#x2F;code&gt;, it will show you a line of code in compiler where error was actually created (it&#x27;s not always 100% helpful, but very likely would be a good starting point, I found this one very useful at my start)&lt;&#x2F;p&gt;
&lt;p&gt;here is an example&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;warning: function `is_maybe_transmutable` is never used
--&amp;gt; &amp;#x2F;home&amp;#x2F;gh-Kivooeo&amp;#x2F;test_&amp;#x2F;src&amp;#x2F;main.rs:6:12
|
6 |     pub fn is_maybe_transmutable&amp;lt;Src, Dst&amp;gt;()
|            ^^^^^^^^^^^^^^^^^^^^^
|
= note: -Ztrack-diagnostics: created at compiler&amp;#x2F;rustc_passes&amp;#x2F;src&amp;#x2F;dead.rs:1113:18
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;as you can see above, there is a note with a specific place&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tip-2&quot; aria-label=&quot;Anchor link for: tip-2&quot;&gt;Tip 2&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Once you have a working build, you can save hours of recompilation time by using the &lt;code&gt;--keep-stage&lt;&#x2F;code&gt; flag. For example&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;.&#x2F;x b --keep-stage 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This tells to &lt;code&gt;x&lt;&#x2F;code&gt; to reuse the already-compiled &lt;code&gt;stage 1&lt;&#x2F;code&gt; compiler when you make changes to later stages. Sometimes you still need a full rebuild, but for most iterative work this flag is a lifesaver&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-conclusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#small-conclusion&quot; aria-label=&quot;Anchor link for: small-conclusion&quot;&gt;Small conclusion&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Starting to contribute to Rust isn&#x27;t about genius, it&#x27;s about curiosity and persistence. You don&#x27;t have to know the entire codebase. You learn, ask questions, and take small steps&lt;&#x2F;p&gt;
&lt;p&gt;That was the first part. I hope it helped you at least a little and dispelled some of your fears&lt;&#x2F;p&gt;
&lt;p&gt;In the next part, I want to take a real issue and walk through the process from start to merge, showing the entire process in detail&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The `if let guard` stabilization path</title>
        <published>2026-01-25T00:00:00+00:00</published>
        <updated>2026-01-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/blog/if-let-guard/"/>
        <id>https://kivooeo.github.io/blog/if-let-guard/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/blog/if-let-guard/">&lt;p&gt;Hi all!&lt;&#x2F;p&gt;
&lt;p&gt;In this blog post, I&#x27;m going to talk about a feature I&#x27;ve been working on stabilizing&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;51114&quot;&gt;original tracking issue&lt;&#x2F;a&gt; was created more than 7 years ago&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been using Rust for less than 7 years, so I’ll relay what I’ve heard: the feature was stabilized at first, but some drop-order bugs appeared, and it was quickly destabilized. I guess it was then abandoned for a long time, currently, all the drop order bugs have been fixed, and it works correctly&lt;&#x2F;p&gt;
&lt;p&gt;I encountered some code where I tried to use &lt;code&gt;if let guard&lt;&#x2F;code&gt; and then compiler says&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;hey, that&#x27;s not stable, what are you trying to do here?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;and I was like&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;eeh, what do you mean not stable, this is so obvious and... simple, like, how is this different from an &lt;code&gt;if guard&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;After that, I started investigating this feature, this was at the very beginning of my contributing journey somewhere around end of April&lt;&#x2F;p&gt;
&lt;p&gt;And I got a lot of help from another Rust team member &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;est31&quot;&gt;est31&lt;&#x2F;a&gt;, who, not long before I started looking into this, had finished stabilizing &lt;code&gt;let chains&lt;&#x2F;code&gt; which was a major stabilization for Rust and one of the most requested features overall&lt;&#x2F;p&gt;
&lt;p&gt;As you can tell from the post&#x27;s title, it&#x27;s about the &lt;code&gt;if let guard&lt;&#x2F;code&gt; feature, which I think is a very pretty one :3&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-is-this-feature-even-about&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-this-feature-even-about&quot; aria-label=&quot;Anchor link for: what-is-this-feature-even-about&quot;&gt;What is this feature even about?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This is a pretty straightforward feature at first sight, I mean very straightforward, it&#x27;s basically allows you to use &lt;code&gt;let&lt;&#x2F;code&gt; patterns in match guards, like this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let x = &amp;quot;42&amp;quot;;
let y = Some(2);

match x.parse::&amp;lt;i32&amp;gt;() {
    Ok(s) if let Some(y) = y =&amp;gt; (),
    Ok(s) =&amp;gt; (),
    _ =&amp;gt; (),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This simple snippet shows what the feature does - nothing complicated, right? So roughly without this feature (there are many ways to rewrite it in Rust, I just pick one that is closest to the code above and what I&#x27;d use)&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let x = &amp;quot;42&amp;quot;;
let y = Some(2);

match x.parse::&amp;lt;i32&amp;gt;() {
    Ok(s) =&amp;gt; {
        if let Some(y) = y {
            &amp;#x2F;&amp;#x2F; first branch
        } else {
            &amp;#x2F;&amp;#x2F; second branch
        }
    }
    _ =&amp;gt; (),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Personally I don&#x27;t like this, I never liked this, just because there is cases where you really don&#x27;t want to create a block in match arm and just return value&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;struct A {
    x: i32,
    y: i32,
    related_points: Option&amp;lt;Vec&amp;lt;A&amp;gt;&amp;gt;,
}

fn main() {
    let a = A {
        x: 2,
        y: 3,
        related_points: Some(vec![]),
    };

    let x = Some(42);

    match x {
        Some(x)
            if let A { related_points, .. } = a
                &amp;amp;&amp;amp; let Some(points) = related_points =&amp;gt; points.len()
        _ =&amp;gt; 1,
    };
}

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, currently you are forced to write a block like this&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match x {
    Some(x) =&amp;gt; {
        if let A { related_points, .. } = a
            &amp;amp;&amp;amp; let Some(points) = related_points
        {
            points.len()
        } else {
            1
        }
    }
    _ =&amp;gt; 1,
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As I said before, I don&#x27;t like this, like, completely&lt;&#x2F;p&gt;
&lt;p&gt;As you might have already seen, &lt;code&gt;if let guard&lt;&#x2F;code&gt; could use &lt;code&gt;let chains&lt;&#x2F;code&gt;...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;let-chains&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#let-chains&quot; aria-label=&quot;Anchor link for: let-chains&quot;&gt;Let chains&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Yes, you get it right, this feature is fully compatible with &lt;code&gt;let chains&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;let chains&lt;&#x2F;code&gt; are actually one of my favorite Rust features, even though I started learning Rust only few years ago, I can definitely tell that &lt;code&gt;let chains&lt;&#x2F;code&gt; were my most used feature since then, I do really &lt;em&gt;love&lt;&#x2F;em&gt; patterns and hope you too!&lt;&#x2F;p&gt;
&lt;p&gt;So back to &lt;code&gt;let chains&lt;&#x2F;code&gt; in &lt;code&gt;if let guard&lt;&#x2F;code&gt;, you might be wondering, what&#x27;s so special about them?&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the answer: &lt;code&gt;let chains&lt;&#x2F;code&gt; were originally restricted to Rust 2024+ editions, so using them in edition 2021 (or earlier) would give an error&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;error: let chains are only allowed in Rust 2024 or later
 --&amp;gt; src&amp;#x2F;main.rs:4:8
  |
4 |     if let Some(x) = Some(42) &amp;amp;&amp;amp; x.is_positive() {
  | 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will not work as we just tried above, but you already have seen the possibility of using &lt;code&gt;let chains&lt;&#x2F;code&gt; in &lt;code&gt;if let guard&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A few questions might come to mind:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Does that mean that &lt;code&gt;if let guard&lt;&#x2F;code&gt; going to be stabilized in edition 2024+?&lt;&#x2F;li&gt;
&lt;li&gt;Or does it mean that I could use &lt;code&gt;if let guard&lt;&#x2F;code&gt; in all editions, but using &lt;code&gt;let chains&lt;&#x2F;code&gt; in &lt;code&gt;if let guard&lt;&#x2F;code&gt; will be restricted&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Sooo... my answer will be pretty short and direct: using &lt;code&gt;let chains&lt;&#x2F;code&gt; in &lt;code&gt;if let guard&lt;&#x2F;code&gt; will be allowed in all editions, which means&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;fn main() {
    match 0 {
        _ if let Some(x) = Some(42) &amp;amp;&amp;amp; x.is_negative() =&amp;gt; println!(&amp;quot;wow!&amp;quot;),
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This code will work perfectly fine in all editions even though it contains &lt;code&gt;let chains&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Important note here:&lt;&#x2F;p&gt;
&lt;p&gt;Currently, if you try to run this code in edition 2021 or lower, it will give you an error, about &lt;code&gt;let chains&lt;&#x2F;code&gt;, just because, when we are parsing &lt;code&gt;if let guard&lt;&#x2F;code&gt; in compiler we do have a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;blob&#x2F;4d38622e8bec00a9001264c4e9f4723fceca23cb&#x2F;compiler&#x2F;rustc_parse&#x2F;src&#x2F;parser&#x2F;expr.rs#L3459&quot;&gt;check&lt;&#x2F;a&gt; for &lt;code&gt;let chains&lt;&#x2F;code&gt; to gave such error,&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;if has_let_expr(&amp;amp;cond) {
    let span = if_span.to(cond.span);
    self.psess.gated_spans.gate(sym::if_let_guard, span);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But don&#x27;t worry, this will be deleted with stabilization, it&#x27;s fine that it doesn&#x27;t work now, it will work as stabilized&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;This is snippet from my code that I wrote to fix a diagnostic problem using both of these features, we are using a lot of unstable features in compiler so which is why I was able to do this,&lt;&#x2F;p&gt;
&lt;p&gt;Btw, if you aren&#x27;t comfortable with understanding this code, which is 100% fine, I&#x27;m not waiting for the reader to be a rustc developer, just try to see the differences in form itself, the semantics are pretty much the same&lt;&#x2F;p&gt;
&lt;p&gt;The problem was that an &lt;code&gt;Op::AssignOp(assign_op)&lt;&#x2F;code&gt; branch already existed and extending it for this new check would have been messy, since it wasn&#x27;t just a few lines, so it would have dramatically bloated the original branch, the solution was to create a separate branch and do all the checks right in the match guard:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;Op::AssignOp(assign_op)
    if assign_op.node == hir::AssignOpKind::AddAssign
        &amp;amp;&amp;amp; let hir::ExprKind::Binary(bin_op, left, right) = &amp;amp;lhs_expr.kind
        &amp;amp;&amp;amp; bin_op.node == hir::BinOpKind::And
        &amp;amp;&amp;amp; crate::op::contains_let_in_chain(left)
        &amp;amp;&amp;amp; let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) =
            &amp;amp;right.kind
        &amp;amp;&amp;amp; matches!(path.res, hir::def::Res::Local(_)) =&amp;gt;
{
    &amp;#x2F;&amp;#x2F; give a nice user friendly error here :3
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Actually, for those who wonder how the same code will looks without all this stuff is... this...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;Op::AssignOp(assign_op) =&amp;gt; {
    if assign_op.node == hir::AssignOpKind::AddAssign {
        if let hir::ExprKind::Binary(bin_op, left, right) = &amp;amp;lhs_expr.kind {
            if bin_op.node == hir::BinOpKind::And {
                if crate::op::contains_let_in_chain(left) {
                    if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) =
                        &amp;amp;right.kind
                    {
                        if matches!(path.res, hir::def::Res::Local(_)) {
                            &amp;#x2F;&amp;#x2F; give an nice user friendly error here :3
                        }
                    }
                }
            }
        }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is far from perfection! So please use both of these nice features to get closer to it ^^,&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-this-feature-will-be-out&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#when-this-feature-will-be-out&quot; aria-label=&quot;Anchor link for: when-this-feature-will-be-out&quot;&gt;When this feature will be out?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Actually, in perfect scenario, I&#x27;d say that this feature will be stable at 1.95, which is very optimistic. There is only one blocker left: documentation, so as far as I can tell, it will be FCP&#x27;ed and merged after the documentation is merged, in less optimistic scenario I think it will be ready to 1.96, but, to be honest both of these scenarios are very close and mostly important is very realistic, because all the concerns about drop order have been resolved, there is nothing blocking it&lt;&#x2F;p&gt;
&lt;h1 id=&quot;faq-section&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#faq-section&quot; aria-label=&quot;Anchor link for: faq-section&quot;&gt;FAQ section&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;This section will answer some of the questions that might come up in your head&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-are-let-chains-in-if-let-guard-stable-on-all-editions&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-are-let-chains-in-if-let-guard-stable-on-all-editions&quot; aria-label=&quot;Anchor link for: why-are-let-chains-in-if-let-guard-stable-on-all-editions&quot;&gt;Why are let chains in if let guard stable on all editions?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;That&#x27;s a really good question! It&#x27;s hard to say with complete confidence since I wasn&#x27;t working on the original &lt;code&gt;let chains&lt;&#x2F;code&gt; stabilization and I&#x27;m not deeply familiar with that part of the compiler. But from what I&#x27;ve learned from the team: &lt;code&gt;let chains&lt;&#x2F;code&gt; in &lt;code&gt;if let guard&lt;&#x2F;code&gt; don&#x27;t suffer from the drop order issues that affect regular &lt;code&gt;if chains&lt;&#x2F;code&gt; because there&#x27;s no &lt;code&gt;else&lt;&#x2F;code&gt; block like in &lt;code&gt;if let&lt;&#x2F;code&gt; has that can cause scoping complications.&lt;&#x2F;p&gt;
&lt;p&gt;To stabilize &lt;code&gt;let chains&lt;&#x2F;code&gt; for Edition 2024, the &lt;code&gt;if_let_rescope&lt;&#x2F;code&gt; feature was introduced to fix drop order behavior in contexts with &lt;code&gt;else&lt;&#x2F;code&gt; blocks. Match guards never had this problem—they&#x27;re just boolean conditions without an &lt;code&gt;else&lt;&#x2F;code&gt; branch, so temporaries already had predictable scoping. Since &lt;code&gt;if let guard&lt;&#x2F;code&gt; already behaves correctly without needing the rescoping fix, it works consistently across all editions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-was-the-drop-order-bug-that-was-fixed&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-was-the-drop-order-bug-that-was-fixed&quot; aria-label=&quot;Anchor link for: what-was-the-drop-order-bug-that-was-fixed&quot;&gt;What was the drop order bug that was fixed?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Well, I can&#x27;t tell about previous stabilization, since not much is known about it, but I can speak about current one&lt;&#x2F;p&gt;
&lt;p&gt;So in current stabilization, right after it was FCP&#x27;ed and I had fixed all (30+) the last nits, and it was sitting in the queue to be merged, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dianne&quot;&gt;dianne&lt;&#x2F;a&gt; raised a very good point with drop order,&lt;&#x2F;p&gt;
&lt;p&gt;I will leave &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;141295#issuecomment-2968975596&quot;&gt;her comment&lt;&#x2F;a&gt; here, just in case someone wants to see it for themselves, but I will explain this a little, honestly this comment is pretty well written as it, but here&#x27;s the problem:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match SignificantDrop(0) {
    x if let y = SignificantDrop(&amp;amp;x) =&amp;gt; {}
    _ =&amp;gt; unreachable!(),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;x&lt;&#x2F;code&gt; drops before &lt;code&gt;y&lt;&#x2F;code&gt; which is not obvious and maybe incorrect sometimes, and another case shows the actual problem of inconsistent drop order pretty well&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match [LogDrop(o, 2), LogDrop(o, 1)] {
    [x, y] if let z = LogDrop(o, 3) =&amp;gt; {}
    _ =&amp;gt; unreachable!(),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;First, let me explain how to read this, it exactly show drop order by numbers, so &lt;code&gt;LogDrop(o, 1)&lt;&#x2F;code&gt; will drop first, &lt;code&gt;LogDrop(o, 2)&lt;&#x2F;code&gt; second and so on&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So here, it will drop everything in the following order &lt;code&gt;y&lt;&#x2F;code&gt; -&amp;gt; &lt;code&gt;x&lt;&#x2F;code&gt; -&amp;gt; &lt;code&gt;z&lt;&#x2F;code&gt;, which is also not correct, you would expect right to left drop order, now, thanks to dianne&#x27;s efforts, it works as intended and expected: &lt;code&gt;z&lt;&#x2F;code&gt; -&amp;gt; &lt;code&gt;y&lt;&#x2F;code&gt; -&amp;gt; &lt;code&gt;x&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match [LogDrop(o, 3), LogDrop(o, 2)] {
    [x, y] if let z = LogDrop(o, 1) =&amp;gt; {}
    _ =&amp;gt; (),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;This behavior was fixed by dianne in &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;143376&quot;&gt;this pull request&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;what-is-the-current-drop-order-behavior&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-the-current-drop-order-behavior&quot; aria-label=&quot;Anchor link for: what-is-the-current-drop-order-behavior&quot;&gt;What is the current drop order behavior?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;So yes, as you might have seen above, the drop order is correct and right to left order&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match [LogDrop(o, 5), LogDrop(o, 4)] {
    [x, y]
        if let z = LogDrop(o, 3)
            &amp;amp;&amp;amp; let w = LogDrop(o, 2)
            &amp;amp;&amp;amp; let v = LogDrop(o, 1) =&amp;gt; {}
    _ =&amp;gt; (),
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is consistent and stable, so there is nothing to worry about. There was also a bug with &lt;code&gt;pin!()&lt;&#x2F;code&gt; that was found also during the limit testing of &lt;code&gt;if let guard&lt;&#x2F;code&gt; by &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;theemathas&quot;&gt;theemathas&lt;&#x2F;a&gt;, so this bug looked like this and it wasn&#x27;t necessarily a bug in the &lt;code&gt;if let guard&lt;&#x2F;code&gt;, but &lt;code&gt;let chains&lt;&#x2F;code&gt; one&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    if let x = LoudDrop(&amp;quot;0&amp;quot;)
        &amp;amp;&amp;amp; let y = pin!(LoudDrop(&amp;quot;1&amp;quot;))
        &amp;amp;&amp;amp; let z = pin!(LoudDrop(&amp;quot;2&amp;quot;))
        &amp;amp;&amp;amp; let w = LoudDrop(&amp;quot;3&amp;quot;)
    {}
    &amp;#x2F;&amp;#x2F; 3
    &amp;#x2F;&amp;#x2F; 0
    &amp;#x2F;&amp;#x2F; 2
    &amp;#x2F;&amp;#x2F; 1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And once again, this is not what you would expect, but yeah, on current stable version this is already fixed and working as intented&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Also was fixed by dianne &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;145342&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;performance-question&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#performance-question&quot; aria-label=&quot;Anchor link for: performance-question&quot;&gt;Performance question&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Q: Does this compile to the same code as using a block, and&#x2F;or does it have any overhead from creating a block with an &lt;code&gt;if let&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Well, this is a reasonable question and concern, but answer is no, both of these code examples compile to the same assembly, have the same semantics, and the same drop order&#x2F;scope behavior. So yeah, I&#x27;d say they are identical&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    match 0 {
        _ if let Some(new_x) = Some(2) &amp;amp;&amp;amp; new_x &amp;gt; 150 =&amp;gt; x = new_x,
        _ =&amp;gt; x = 1,
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    match 0 {
        _ =&amp;gt; {
            if let Some(new_x) = Some(2) &amp;amp;&amp;amp; new_x &amp;gt; 150  {
                x = new_x;
            } else {
                x = 1;
            }
        }
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;shadowing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#shadowing&quot; aria-label=&quot;Anchor link for: shadowing&quot;&gt;Shadowing&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Quick quiz: what will this print?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;match Some(4) {
    x if let Some(x) = Some(2) &amp;amp;&amp;amp; let Some(x) = Some(5) =&amp;gt; println!(&amp;quot;{x}&amp;quot;),
    _ =&amp;gt; panic!()
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;if you answered 5, you are correct, so yeah, it will just shadow all previous &lt;code&gt;x&lt;&#x2F;code&gt;&#x27;s&lt;&#x2F;p&gt;
&lt;h3 id=&quot;irrefutable-patterns&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#irrefutable-patterns&quot; aria-label=&quot;Anchor link for: irrefutable-patterns&quot;&gt;Irrefutable Patterns&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The compiler will correctly understand if a pattern is irrefutable, so like in this example&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;    match Some(()) {
        Some(x) if let () = x =&amp;gt; {}
        _ =&amp;gt; {}
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It will give you a nice warning :3&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;warning: irrefutable `if let` guard pattern
  --&amp;gt; src&amp;#x2F;main.rs:41:20
   |
41 |         Some(x) if let () = x =&amp;gt; {}
   |                    ^^^^^^^^^^
   |
   = note: this pattern will always match, so the guard is useless
   = help: consider removing the guard and adding a `let` inside the match arm
   = note: `#[warn(irrefutable_let_patterns)]` on by default
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;conclusion-personal-note&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion-personal-note&quot; aria-label=&quot;Anchor link for: conclusion-personal-note&quot;&gt;Conclusion &amp;amp; Personal Note&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I don&#x27;t like conclusions because they usually just repeat everything you already read, so I&#x27;ll keep this short: the feature is nice, the blockers are resolved, around 1.95 hopefully!&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s all! If you like what I&#x27;m doing and want to ✨ support ✨ my work, I have a &lt;a href=&quot;&#x2F;sponsor&quot;&gt;sponsor page&lt;&#x2F;a&gt;. I also just updated it with information on how you can support me without crypto (using crypto, yes xD)&lt;&#x2F;p&gt;
&lt;p&gt;Working on long-running compiler takes time and focus - which brings me to a small personal note&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m planning to move to my partner&#x27;s city soon. While I have the funds saved up, any support to make this transition smoother and less stressful would mean the world to me&lt;&#x2F;p&gt;
&lt;p&gt;With heartfelt thanks to the Rust community!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>First post</title>
        <published>2025-12-25T00:00:00+00:00</published>
        <updated>2025-12-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/blog/first/"/>
        <id>https://kivooeo.github.io/blog/first/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/blog/first/">&lt;p&gt;Hi, &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;1nck01w&#x2F;im_20_close_to_becoming_a_rust_compiler_team&#x2F;&quot;&gt;last time I wrote about uncertainty&lt;&#x2F;a&gt;. This time, I want to write about what came after. Here&#x27;s an update on my journey after that post - the progress, the difficulties, and where I ended up&lt;&#x2F;p&gt;
&lt;h2 id=&quot;there-where-it-all-ended-last-time&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#there-where-it-all-ended-last-time&quot; aria-label=&quot;Anchor link for: there-where-it-all-ended-last-time&quot;&gt;There, where it all ended last time&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;After my last post, I received an overwhelming amount of support - both in comments and private messages. Thank you all so much for that. Several people also reached out with job offers, which I genuinely appreciated&lt;&#x2F;p&gt;
&lt;p&gt;But none of them fit my situation in the end. Some were with established companies abroad that couldn&#x27;t cover relocation costs because of sanctions - something I currently can&#x27;t afford on my own. Others were in areas like crypto and web3: fields I respect, but not ones where my skills or interests truly lie&lt;&#x2F;p&gt;
&lt;p&gt;So my only sponsor all this time was my mom - in fact, it&#x27;s hard to say how much work she did for Rust without even realizing it&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-place-where-stars-align&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-place-where-stars-align&quot; aria-label=&quot;Anchor link for: the-place-where-stars-align&quot;&gt;The place where stars align&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Almost two months after my original post, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;team&#x2F;pull&#x2F;2059&quot;&gt;I was added to the compiler team&lt;&#x2F;a&gt;. In the four months since my post, I&#x27;ve been working on the compiler steadily - usually 1-3 hours a day, though some bugs demand more. Recently, there was one day when I didn&#x27;t open GitHub at all because I&#x27;d spent the day before and almost half the night until 4 am trying to understand &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;149981&quot;&gt;this bug&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When I finally fell asleep around 6 am and woke up about 10 hours later, I decided to take a break for the day. It&#x27;s funny - I don&#x27;t remember any other day when I didn&#x27;t open GitHub&lt;&#x2F;p&gt;
&lt;p&gt;Even on the day I was drafted into the army (a whole story of its own), I spent the morning &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;149160#issuecomment-3560606816&quot;&gt;reviewing a pull request&lt;&#x2F;a&gt; - literally just a few hours before they came for me. They took me to the distribution center, then brought me back home at 9 pm because I &quot;didn&#x27;t suit them&quot;&lt;&#x2F;p&gt;
&lt;p&gt;And I&#x27;m pretty sure that later that night, I went back to do some other reviews. If they hadn&#x27;t brought me back, I would have returned to Rust in a year LMAO&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-sum-of-all-that-happened&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-sum-of-all-that-happened&quot; aria-label=&quot;Anchor link for: the-sum-of-all-that-happened&quot;&gt;The sum of all that happened&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s talk about how the numbers have changed since the last post, I don&#x27;t like this kind of metrics, but that&#x27;s all we have I guess. At the time of writing, &lt;a href=&quot;https:&#x2F;&#x2F;thanks.rust-lang.org&#x2F;&quot;&gt;thanks.rust-lang.org&lt;&#x2F;a&gt; shows 171 contributions, compared to 88 in my last post - a pretty big jump&lt;&#x2F;p&gt;
&lt;p&gt;Despite that jump, my ranking didn&#x27;t move as dramatically - from 360th to 235th all-time. I&#x27;ve noticed that the higher you climb, the slower it gets :) I probably won&#x27;t reach the top 200 this year, but looking back at the progress - from my very first pull request to these numbers - still feels really good&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-idleness-that-never-rest&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-idleness-that-never-rest&quot; aria-label=&quot;Anchor link for: the-idleness-that-never-rest&quot;&gt;The idleness that never rest&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;As you may have guessed, I was technically unemployed all this time - though I wouldn&#x27;t call it that myself&lt;&#x2F;p&gt;
&lt;p&gt;So what did I decide by the end of the year? Considering I need relatively little to live on (about $250-300 a month, since I don&#x27;t pay rent), I decided to return to my previous job teaching IT to children. I left this job at the end of last school year, but it&#x27;s a good fit for my situation&lt;&#x2F;p&gt;
&lt;p&gt;The job takes only about two days per a week. The salary of $550–600 gives me enough to live on and even save a little for things I enjoy, plus plenty of time to work on the compiler. And the job itself:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I genuinely like it&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;helps me take my mind off code and remember real life exists - children are the best guide for that&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;removes financial stress&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The only downside is that it&#x27;s not scalable in the conventional sense. But since I&#x27;m not chasing big numbers - just stability and the opportunity to keep contributing - I think this is a good solution&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-unclenching&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-unclenching&quot; aria-label=&quot;Anchor link for: the-unclenching&quot;&gt;The Unclenching&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This will be the last chapter before Q&amp;amp;A&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s the end of the year now, and I want to say this has probably been the most emotionally difficult year for me - the army, finances, work, potential relocations, instability&lt;&#x2F;p&gt;
&lt;p&gt;In about three weeks I&#x27;ll turn 21&lt;&#x2F;p&gt;
&lt;p&gt;For now, I think I had found an opportunity to work on what I like and make it financially stable without sacrificing the part of myself that wants to work on Rust&lt;&#x2F;p&gt;
&lt;p&gt;For those who&#x27;ve asked - I&#x27;ve set up a &lt;a href=&quot;&#x2F;sponsor&quot;&gt;sponsor page&lt;&#x2F;a&gt; with the options currently available to me, only crypto :(&lt;&#x2F;p&gt;
&lt;p&gt;Thank you all for this year. Happy New Year, everyone!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;to-read-the-stars-first-learn-the-dark&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#to-read-the-stars-first-learn-the-dark&quot; aria-label=&quot;Anchor link for: to-read-the-stars-first-learn-the-dark&quot;&gt;To read the stars, first learn the dark&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Q: I want to contribute to the compiler, but it&#x27;s overwhelming. Where do I start?&lt;&#x2F;p&gt;
&lt;p&gt;A: Don&#x27;t think about the size - just find something specific that interests you and start there&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: But I don&#x27;t know anything. How can I make changes?&lt;&#x2F;p&gt;
&lt;p&gt;A: Search the codebase for keywords related to what you&#x27;re looking for. Most of the time, something similar already exists - variables, functions, comments, anything that gives you context. If you&#x27;re still stuck, please, don&#x27;t hesitate to ask in Zulip. People are helpful&lt;&#x2F;p&gt;
&lt;p&gt;And here&#x27;s slightly controversial advice: you can use LLMs to understand code snippets. If you&#x27;re staring at a function and have no idea what it does, an LLM can usually explain it. Ask &quot;why does this work?&quot; or &quot;what is this doing?&quot; But - and this is critical - use it to &lt;em&gt;understand&lt;&#x2F;em&gt; code, not to &lt;em&gt;write&lt;&#x2F;em&gt; code for you. Don&#x27;t submit generated pull requests that you don&#x27;t fully understand. That wastes reviewers&#x27; time and doesn&#x27;t help you learn&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What did you learn about sustaining motivation over months of unpaid work?&lt;&#x2F;p&gt;
&lt;p&gt;A: In my case, staying motivated was probably the least of my problems, to be honest. Here are some reasons (not in order of importance):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;the tasks are very interesting&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;there is a lot of room for learning and development&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I love Rust&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;the community is incredibly cool, and it&#x27;s a pleasure to work with them&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;it&#x27;s just a hobby among my other hobbies that I also devote time to, such as studying other sciences, creativity, or games&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: Any mistakes you made early on that you&#x27;d warn others about?&lt;&#x2F;p&gt;
&lt;p&gt;A: Yes, and it wasn&#x27;t even about code - it was about communication and the language barrier&lt;&#x2F;p&gt;
&lt;p&gt;Early on, I was using LLMs heavily to write my comments. Then I got a private message: &quot;Hey, I noticed you write strangely. Don&#x27;t be afraid to make mistakes or write in your own words - just don&#x27;t rely on LLMs so much.&quot; A couple days later, another reviewer commented that my writing seemed sloppy&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m grateful for that first message. Since then, I&#x27;ve stopped using LLMs for writing and only occasionally use translators for specific words or a grammar checker. It&#x27;s better to write imperfectly in your own voice than perfectly in an AI&#x27;s&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What would you tell someone else stuck in a difficult location&#x2F;situation who wants to do meaningful work?&lt;&#x2F;p&gt;
&lt;p&gt;A: It really depends on your situation. I had financial support from my mom, which gave me space to contribute full-time. If you don&#x27;t have that safety net, my honest advice is: stabilize your life first. Big projects like Rust aren&#x27;t going anywhere - they&#x27;ll still be there when you&#x27;re ready. Your personal situation matters more&lt;&#x2F;p&gt;
&lt;p&gt;That said, if you can&#x27;t wait or don&#x27;t want to - even 30 minutes to an hour a day adds up. Consistency matters more than volume. Just be realistic about what you can sustain&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: How did you deal with the uncertainty and financial stress mentally?&lt;&#x2F;p&gt;
&lt;p&gt;A: The hardest part was feeling like I was consuming resources - relying on my mother&#x27;s support - without creating anything materially useful in return. As someone who values family responsibility, that guilt slowly kept growing. What helped was looking at my actual results. It reminded me that the work was meaningful - even if it didn&#x27;t pay the bills. That kept me from giving up&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What kept you going when things looked hopeless?&lt;&#x2F;p&gt;
&lt;p&gt;A: Take real breaks. Step away, recharge, and come back fresh. And when I say &quot;real breaks&quot; - I mean actually disconnect. I kept checking GitHub even during mine, which defeated the purpose&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: How do you know when to push through vs. take a break?&lt;&#x2F;p&gt;
&lt;p&gt;A: Honestly, this is the hardest question because it requires self-awareness, and everyone&#x27;s different. For me, the key signal is autopilot - when I catch myself going through the motions without actually thinking, when I&#x27;m staring at code but not really seeing it. That&#x27;s when I know I need to stop&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: The teaching job solution - how did you figure out what &quot;enough&quot; money&#x2F;time looked like?&lt;&#x2F;p&gt;
&lt;p&gt;A: I just looked at the numbers. I tracked how much I actually spend each month - bills, food, personal stuff - and it came to around $250-300&lt;&#x2F;p&gt;
&lt;p&gt;For time, I knew that even an hour a day would be enough for compiler work if I stayed consistent. Working two days a week at the teaching job leaves me plenty of time while still providing the stability I need to contribute regularly&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What surprised you about the response to your first post?&lt;&#x2F;p&gt;
&lt;p&gt;A: Two things, actually&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;people who tried to spread negativity in the comments&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;the overwhelming support. I really didn&#x27;t expect so many people to reach out with genuine encouragement and offers to help. The community response was beyond anything I imagined&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: Any advice on asking for help vs. going it alone?&lt;&#x2F;p&gt;
&lt;p&gt;A: Learn to recognize the difference between &quot;I need more time to figure this out&quot; and &quot;I actually need help from someone who knows this area.&quot; Try to solve things yourself first, but don&#x27;t waste days being stuck when someone could answer in five minutes. It&#x27;s a balance, and it takes practice to find it&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What does &quot;звёзды все принадлежат богам&quot; means on your profile?&lt;&#x2F;p&gt;
&lt;p&gt;A: Ah, this is a line from the song of the same name&lt;&#x2F;p&gt;
&lt;blockquote&gt;
А звёзды все принадлежат богам
&lt;p&gt;И их не поймать, они не падают к ногам&lt;&#x2F;p&gt;
&lt;p&gt;И не уместен торг по рукам&lt;&#x2F;p&gt;
&lt;p&gt;Птице - небо, человеку - смерть&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It translates roughly to something like this&lt;&#x2F;p&gt;
&lt;blockquote&gt;
The stars remain in the keeping of the gods
&lt;p&gt;Uncatchable, they offer no descent to our level&lt;&#x2F;p&gt;
&lt;p&gt;There can be no bargains in such things&lt;&#x2F;p&gt;
&lt;p&gt;A wing has the air; a life has its grave&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Everyone will interpret this in their own way, so I&#x27;ll leave the meaning open. But yes - &quot;the stars all belong to the gods&quot; is the direct translation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Q: What is the main conclusion you have come to?&lt;&#x2F;p&gt;
&lt;p&gt;A: If I learned anything this year, it&#x27;s that consistency beats intensity - and that meaning is sometimes enough to keep going. That even small but steady steps are better than rare but wide ones&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sponsor</title>
        <published>2025-12-12T00:00:00+00:00</published>
        <updated>2025-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/sponsor/"/>
        <id>https://kivooeo.github.io/sponsor/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/sponsor/">&lt;p&gt;Hi!&lt;&#x2F;p&gt;
&lt;p&gt;I am a member of the Rust compiler team. Over the past ten months, I have made over 400 contributions, including fixing bugs, improving diagnostics, stabilising features, reviewing pull requests and mentoring new contributors&lt;&#x2F;p&gt;
&lt;p&gt;I care deeply about Rust, and I plan to continue investing a lot of time in improving the compiler, the test suite and the experience of contributors&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-support-me&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-support-me&quot; aria-label=&quot;Anchor link for: why-support-me&quot;&gt;Why support me?&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Your support enables me to dedicate more focused time to compiler development and mentoring. I am transitioning from part-time teaching into a position related to Rust and also moving to another city. Any additional support would make this transition smoother and enable me to maintain my focus on long-term contributions&lt;&#x2F;p&gt;
&lt;p&gt;If you have found my work, blog posts, mentoring or compiler improvements valuable, this is one way you can help me to continue doing them&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-only-crypto&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-only-crypto&quot; aria-label=&quot;Anchor link for: why-only-crypto&quot;&gt;Why only crypto?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;m in Russia, where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GitHub Sponsors doesn&#x27;t work&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;International payment systems are blocked&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Bank transfers are nearly impossible&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Grant programs can&#x27;t send funds here&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At the moment, cryptocurrency is the only viable option for receiving support&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-support&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-to-support&quot; aria-label=&quot;Anchor link for: how-to-support&quot;&gt;How to support?&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;SOL: Ao3QhbFqBidnMnhKVHxsETmvWBfpL3oZL876FDArCfaX&lt;&#x2F;p&gt;
&lt;p&gt;ETC: 0xe1f27D7B1665D88B72874E327e70e4e439751Cfa&lt;&#x2F;p&gt;
&lt;h3 id=&quot;if-you-really-want-to-support-financially-but-don-t-have-crypto&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#if-you-really-want-to-support-financially-but-don-t-have-crypto&quot; aria-label=&quot;Anchor link for: if-you-really-want-to-support-financially-but-don-t-have-crypto&quot;&gt;If you really want to support financially but don&#x27;t have crypto&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;All you need is&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;visit &lt;a href=&quot;https:&#x2F;&#x2F;simpleswap.io&#x2F;&quot;&gt;this website&lt;&#x2F;a&gt;, no registration or anything needed&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Then choose second tab &quot;Buy&#x2F;Sell Crypto&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Here you select&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;USD or EUR on top&lt;&#x2F;li&gt;
&lt;li&gt;SOL on bot&lt;&#x2F;li&gt;
&lt;li&gt;and paste my wallet in here&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Confirm payment and that&#x27;s it! :3&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;You can see all donations &lt;a href=&quot;https:&#x2F;&#x2F;solscan.io&#x2F;account&#x2F;Ao3QhbFqBidnMnhKVHxsETmvWBfpL3oZL876FDArCfaX&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;other-ways-to-help&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#other-ways-to-help&quot; aria-label=&quot;Anchor link for: other-ways-to-help&quot;&gt;Other ways to help&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Whether you choose to support me financially, follow my journey or contribute to Rust yourself, I truly appreciate it. Being part of this community means a lot to me!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>About Me</title>
        <published>2005-01-19T00:00:00+00:00</published>
        <updated>2005-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kivooeo.github.io/about/"/>
        <id>https://kivooeo.github.io/about/</id>
        
        <content type="html" xml:base="https://kivooeo.github.io/about/">&lt;p&gt;Hi, my name is [DATA REDACTED], known as Kivooeo, working as a compiler engineer on Rust Compiler Team on a volunteer basis daily!&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t know what to say here, but I&#x27;m sure that this page will grow in size over time :3&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
