<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Sabrina Jewson&apos;s Blog</title><id>https://sabrinajewson.org/blog/</id><updated>2024-09-22T00:00:00+00:00</updated><author><name>Sabrina Jewson</name><uri>https://sabrinajewson.org</uri></author><generator uri="https://github.com/SabrinaJewson/sabrinajewson.github.io">sabrinajewson.github.io</generator><icon>https://sabrinajewson.org/apple-touch-icon.png</icon><link href="https://sabrinajewson.org/blog/feed.xml" rel="self" type="application/atom+xml"/><link href="https://sabrinajewson.org/blog/" rel="alternate" type="text/html"/><entry><title>“Truly Hygienic” Let Statements in Rust</title><id>https://sabrinajewson.org/blog/truly-hygienic-let</id><updated>2024-09-22T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/truly-hygienic-let" rel="alternate" type="text/html" title="“Truly Hygienic” Let Statements in Rust"/><published>2024-09-22T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/truly-hygienic-let" type="html">&lt;p&gt;Remon is a responsible library developer. She cares about stability, flexibility and correctness, using whichever tools are presently accessible to achieve those goals. Her authored libraries feature automated testing and extensive documentation; she allots design decisions rationale; she knows her language features and traditions and how to apply them to best effect.&lt;/p&gt;&lt;p&gt;And, somewhere to be discovered bound in the tangle of &lt;code class=&apos;scode&apos;&gt;.rs&lt;/code&gt; files, there is Remon herself, tranquil and yet focused, meticulously crafting, polishing, studying and crafting again, a component she forsees to ease the life of her users, provides ergonomics inaccessible by traditional methods, brings to life the great gift of syntax without glue added to the cogs of the build process – a declarative macro.&lt;/p&gt;&lt;p&gt;Refined and learned code-witch she is, Remon is keenly aware of Rust Cultures and Traditions, and so in keeping, would do nothing but summon a monstrous (documented, without doubt, but monstrous nonetheless) tornado of dollar signs and brackets, one whose gales would surely lift up and send flying a meek blog post as this one. Have sympathy! I cannot handle that – I must admit I have not even implemented &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Send&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, so the results could verge on disastrous. But a trained magician knows better than to create a beast they cannot tame, and so for this chronicle it is simplified to a wisp of its wild self – one where you must excuse the apparent folly of its existence – as follows:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta smacro srust&quot;&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;macro_rules!&lt;/span&gt; &lt;span class=&quot;sentity sname smacro srust&quot;&gt;oh_my&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_input&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;svariable sother srust&quot;&gt;$crate&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;process&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remon is a responsible library developer, and understands that all humans will make mistakes – and so she has solicited the services of a good friend, Wolfie, to comment on this slice of code.&lt;/p&gt;&lt;p&gt;Well, Wolfie says, this macro is very impressive feat, and shall surely ease the lives of our users, provide ergonomics inaccessible by traditional methods, and bring to life the great gift of syntax without glue added to the cogs of the build process. But I do have one concern – the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; in this macro is not hygienic.&lt;/p&gt;&lt;p&gt;Now, Remon has read her literature, and knows that Rust macros &lt;em&gt;are&lt;/em&gt; hygienic with regards to locals – they are guaranteed not to interfere with variables of the caller’s scope unless the variable’s name is explicitly passed in.&lt;/p&gt;&lt;p&gt;Is that so?, asks Remon. You and I both know that Rust macros use mixed-site hygiene. But I trust your experience as a developer and respect you as a person, so I will approach this incongruence with curiosity rather than dismissal. Thus I must ask you: Whatever do you mean?&lt;/p&gt;&lt;p&gt;Wolfie thinks for a second, and concludes this point best communicated through the medium of code. So he quickly types out a demo of a certain way of use causing bugs:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; x&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;26ad109e6f4d14e5cc2c2ccb1f5fb497abcaa223&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport smacro srust&quot;&gt;oh_my!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And upon entering input that is not the latest commit hash of the greatest Rust library of all time, Remon is dismayed and ashamed to discover that the code, incorrectly, results in an error. But it’s at least not hard to discover &lt;em&gt;why&lt;/em&gt;: in the line containing &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;x&lt;/code&gt; is a identifier pattern, which means it can either refer to a constant if the constant is in scope, or create a new variable otherwise. Of course, the macro &lt;em&gt;expects&lt;/em&gt; the latter to happen, but since constants are items, and thus unlike variables are unhygienic, if there is a constant &lt;code class=&apos;scode&apos;&gt;x&lt;/code&gt; at the call site, it will be used instead. So our pattern becomes equivalent to &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;26ad109…&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, which will of course reject any value that is not the latest commit hash of the greatest Rust library of all time, resulting in silent bugs.&lt;/p&gt;&lt;p&gt;Okay, thinks Remon. I know of a way to fix this: the pattern &lt;code class=&apos;scode&apos;&gt;IDENT @ PATTERN&lt;/code&gt; will unambiguously have &lt;code class=&apos;scode&apos;&gt;IDENT&lt;/code&gt; bound as a variable, never to be treated as a constant. Since there are no other restrictions to be placed on the data, our &lt;code class=&apos;scode&apos;&gt;PATTERN&lt;/code&gt; can simply be a wildcard – &lt;code class=&apos;scode&apos;&gt;_&lt;/code&gt;. So that’s what she does:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta smacro srust&quot;&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;macro_rules!&lt;/span&gt; &lt;span class=&quot;sentity sname smacro srust&quot;&gt;oh_my&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;skeyword soperator srust&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_input&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;svariable sother srust&quot;&gt;$crate&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;process&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But Wolfie is still not pleased, and Remon is still surprised, because now there is a compilation error.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0530]: let bindings cannot shadow constants
 --&amp;gt; src/main.rs:3:10
  |
3 |         let Ok(x @ _) = read_input() else { return Err(Error) };
  |                ^ cannot be named the same as a constant
...
8 |     const x: &amp;amp;str = &amp;quot;TODO&amp;quot;;
  |     ---------------------- the constant `x` is defined here
9 |     oh_my!();
  |     -------- in this macro invocation
  |
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is of course not as bad as buggy behaviour, but Wolfie knows that Remon is a responsible library developer who cares about flexibility and correctness, and it is unpredicable that the macro would suddenly start failing just because of some constants that happen to be there at the call site.&lt;/p&gt;&lt;p&gt;Remon has never seen this error before, but remains undeterred. After all, there is one more trick up her sleeve: although &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bindings cannot shadow constants, those two do not account for every member of the value namespace. Functions are a member just as well. And functions, unlike &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s, have the property that they &lt;em&gt;can&lt;/em&gt; be shadowed – and by virtue of being an item, they may shadow the latter as well (if introduced in a smaller scope).&lt;/p&gt;&lt;p&gt;So, she introduces that new scope into her macro, and inside it, defines a dummy function. As it happens, functions are never valid in patterns, and so the &lt;code class=&apos;scode&apos;&gt;x @ _&lt;/code&gt; trick is no longer needed.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta smacro srust&quot;&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;macro_rules!&lt;/span&gt; &lt;span class=&quot;sentity sname smacro srust&quot;&gt;oh_my&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;allow&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;dead_code&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_input&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;svariable sother srust&quot;&gt;$crate&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;process&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And despite Wolfie’s attempts to break it, this iteration remains hygienic even in the presence of strange environments.&lt;/p&gt;&lt;p&gt;But Remon isn’t satisfied. Because now, being the responsible library developer she is, whenever she uses this trick, she must document it. And she has to introduce a shadowing helper function for every single identifier used in the macro – something that is very easy to forget, negating the benefit of using this trick in the first place. It increases her codebase’s size, in an already-complex macro, for a gain that seems marginal at best.&lt;/p&gt;&lt;p&gt;And so, against her instincts to be fully correct, Remon turns to Wolfie and says, plainly, &lt;em&gt;No&lt;/em&gt;. With the incantation of a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;git&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, she erases these changes from history, choosing instead to live in the ignorant bliss of very-slightly-unhygienic declarative macros.&lt;/p&gt;&lt;p&gt;After all, who names constants in lowercase anyway?&lt;/p&gt;</content></entry><entry><title>Why the “Null” Lifetime Does Not Exist</title><id>https://sabrinajewson.org/blog/null-lifetime</id><updated>2023-07-22T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/null-lifetime" rel="alternate" type="text/html" title="Why the “Null” Lifetime Does Not Exist"/><published>2023-07-18T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/null-lifetime" type="html">&lt;p&gt;This post originated from an interesting conversation had &lt;a href=&apos;https://discord.com/channels/273534239310479360/818964227783262209/1130515943756406874&apos;&gt;on the Rust community Discord&lt;/a&gt; the other day, in which a user asks:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Does &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; have an opposite? Zero lifetime that’s shorter than anything?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Details of the question are not relevant, but intuitively the question does make sense. After all, Rust already has &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, representing a lifetime that is longer than or equal to all other lifetimes — so why wouldn’t there be a counterpart, maybe called &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;empty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, that is shorter than every other lifetime? To the type theorists out there, if &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is our bottom type (as it can become any lifetime), wouldn’t there also hypothetically be some top type that any lifetime can become?&lt;/p&gt;&lt;p&gt;The short answer is “not in any way that allows you to construct a value with the lifetime”. Rust’s type system, as this post will show, is designed with the assumption that given a valid lifetime, you can always make a shorter one, so any hypothetical &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; lifetime would have to be non-constructible in the first place.&lt;/p&gt;&lt;p&gt;But why is that? Well, that takes a bit of explaining, but first I’d like to take a bit of a detour into the world of self-referential types…&lt;/p&gt;&lt;h2 id=&apos;self-referential-types&apos;&gt;&lt;a href=&apos;#self-referential-types&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;An Overlong Interlude Where I Am Increasingly Pedantic About Self-Referential Types&lt;/h2&gt;&lt;p&gt;(This is going somewhere, I promise.)&lt;/p&gt;&lt;p&gt;You may often hear it be said that Rust does not support self-referential types. This is typically in response to a beginner attempting code like the following and thoroughly confusing themselves:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;OhNo&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;base_string&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; String,
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&amp;#39;&lt;span class=&quot;sinvalid sillegal srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;?? &lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&amp;gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where &lt;code class=&apos;scode&apos;&gt;parts&lt;/code&gt; is supposed to borrow from &lt;code class=&apos;scode&apos;&gt;base_string&lt;/code&gt;. The beginner of course expects this to be possible but has no clue what lifetime to write in there.&lt;/p&gt;&lt;p&gt;Inevitably, you, the seasoned Rustacean, will put on a grave expression and slowly shake your head in frank resignation. Then, bearing the bad news like a parent informing their child of the truth about Santa Claus, you say:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not support self-referential types.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;And the beginner’s dreams are crushed, for no matter how much they may argue against it, they will eventually have to accept the tragic truth such an abstraction is simply not possible.&lt;/p&gt;&lt;p&gt;But we’re programmers here, and we like things to be precise. And if this interaction should occur in any technical space, it is quite expected that some other user be rather pleased with themselves by chiming in: But what about &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt;?&lt;/p&gt;&lt;p&gt;Well, they’re not &lt;em&gt;wrong&lt;/em&gt;. So what about it?&lt;/p&gt;&lt;p&gt;If you’ve ever worked with &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; before, you will know that futures declared with &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; blocks have the ability to borrow values across &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; points. For example:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; future &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; data &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; r &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;data&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;something_else&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Point A
&lt;/span&gt;	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{r}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above future, once it suspends for the first time at point A, has to store all of the data required for resumation in its type. This means that we have to store both &lt;code class=&apos;scode&apos;&gt;data&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;r&lt;/code&gt; in the future — &lt;code class=&apos;scode&apos;&gt;r&lt;/code&gt; needs to be kept because we directly access it, and &lt;code class=&apos;scode&apos;&gt;data&lt;/code&gt; needs to be kept since otherwise &lt;code class=&apos;scode&apos;&gt;r&lt;/code&gt;’s reference would dangle into thin air. But &lt;code class=&apos;scode&apos;&gt;r&lt;/code&gt; also needs to reference &lt;code class=&apos;scode&apos;&gt;data&lt;/code&gt;, which means one part of the type needs to reference another — meeting exactly the definition of a self-referential type!&lt;/p&gt;&lt;p&gt;Okay then, you say, let’s refine the statement. &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; blocks can indeed be self-referential, but that’s not particularly useful because we can’t extract any data from them beyond the very limited &lt;code class=&apos;scode&apos;&gt;Future&lt;/code&gt; interface. So we restrict our claim:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not support self-referential &lt;em&gt;data structures&lt;/em&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This is better but still not quite true, because you can simply make a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; item that depends on itself:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;SelfRef&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;SELF_REF&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; SelfRef &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;SELF_REF&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well that’s just being pedantic now. But fine, let’s adjust the claim:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not support &lt;em&gt;non-static&lt;/em&gt; self-referential data structures.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Except, with a little interior mutability trickery with &lt;code class=&apos;scode&apos;&gt;Cell&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Option&lt;/code&gt; to get around the acyclic nature of runtime execution, this same trick &lt;em&gt;also&lt;/em&gt; works on the stack:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;SelfRef&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Cell&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Cell&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&apos;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=6fb49accec79ec9903e7753c8912159d&apos;&gt;Try it yourself&lt;/a&gt; — although it might be surprising, this compiles just fine, and does indeed result in a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; that technically references itself.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Edit (2023-07-22): After this blog post was pubished, &lt;a href=&apos;https://github.com/danielhenrymantilla&apos;&gt;Daniel Henry-Mantilla&lt;/a&gt; helpfully pointed out that you don’t even need interior mutability to make a stack self-referential struct like this, so long as you’re willing to sacrifice having a &lt;em&gt;literal&lt;/em&gt; self-reference (&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;) for a reference to an earlier field. Specifically, the following code just works:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;SelfRef&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;,
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; a&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	self_ref.b &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref.a&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The resulting &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; exhibits the same behaviour we talk about later in this section, but it’s worth putting in this example as a more “pure” demonstration of the same effect. Thanks, Yandros!&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So, did we do it? Have we solved the years-long problem of self-referential types?&lt;/p&gt;&lt;p&gt;Well, of course not, because this approach comes with one huge problem that is a deal-breaker for almost all real-life situations: the resulting value cannot be moved or uniquely borrowed for the rest of its lifetime. Even if we do something as trivial and innocuous as dropping it, we start to see the issue.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource sdiff&quot;&gt;struct SelfRef&amp;lt;&amp;#39;this&amp;gt; {
	this: Cell&amp;lt;Option&amp;lt;&amp;amp;&amp;#39;this Self&amp;gt;&amp;gt;,
}

fn main() {
	let self_ref = SelfRef {
		this: Cell::new(None),
	};
	self_ref.this.set(Some(&amp;amp;self_ref));
&lt;span class=&quot;smarkup sinserted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sinserted sdiff&quot;&gt;+&lt;/span&gt;	drop(self_ref);
&lt;/span&gt;}

use std::cell::Cell;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0505]: cannot move out of `self_ref` because it is borrowed
  --&amp;gt; src/main.rs:10:10
   |
6  |     let self_ref = SelfRef {
   |         -------- binding `self_ref` declared here
...
9  |     self_ref.this.set(Some(&amp;amp;self_ref));
   |                            --------- borrow of `self_ref` occurs here
10 |     drop(self_ref);
   |          ^^^^^^^^
   |          |
   |          move out of `self_ref` occurs here
   |          borrow later used here

For more information about this error, try `rustc --explain E0505`.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And with unique borrowing we get a similar error:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource sdiff&quot;&gt;&lt;span class=&quot;smarkup sdeleted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sdeleted sdiff&quot;&gt;-&lt;/span&gt;	let self_ref = SelfRef {
&lt;/span&gt;&lt;span class=&quot;smarkup sinserted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sinserted sdiff&quot;&gt;+&lt;/span&gt;	let mut self_ref = SelfRef {
&lt;/span&gt;		this: Cell::new(None),
	};
&lt;span class=&quot;smarkup sdeleted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sdeleted sdiff&quot;&gt;-&lt;/span&gt;	drop(self_ref);
&lt;/span&gt;&lt;span class=&quot;smarkup sinserted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sinserted sdiff&quot;&gt;+&lt;/span&gt;	&amp;amp;mut self_ref.this;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0502]: cannot borrow `self_ref.this` as mutable because it is also borrowed as immutable
  --&amp;gt; src/main.rs:10:5
   |
9  |     self_ref.this.set(Some(&amp;amp;self_ref));
   |                            --------- immutable borrow occurs here
10 |     &amp;amp;mut self_ref.this;
   |     ^^^^^^^^^^^^^^^^^^
   |     |
   |     mutable borrow occurs here
   |     immutable borrow later used here

For more information about this error, try `rustc --explain E0502`.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, this makes perfect sense. If we &lt;em&gt;were&lt;/em&gt; allowed to uniquely borrow the &lt;code class=&apos;scode&apos;&gt;self_ref&lt;/code&gt; value we could trivially use that to produce a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;&amp;amp;&lt;/code&gt; to the same location, which is a textbook case of UB!&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_1&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_2&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Oops, UB!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These examples are quite abstract, but they show that you are barred from doing basically anything useful with the value, including returning it from functions or setting any of its fields without interior mutability. Well what did I expect, we just can’t have nice things.&lt;/p&gt;&lt;p&gt;At least we can improve our claim:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not support &lt;em&gt;movable&lt;/em&gt; self-referential data structures.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Surely we’re done now? Well, for the purposes of the main point of the post we are, but since I’ve started this game I feel only obliged to indulge in this pedantry to its natural terminus. So yes, let’s continue…&lt;/p&gt;&lt;p&gt;Our next counterexample is that C supports movable self-referential data structures. So if Rust can’t do this, does this mean Rust is inherently less powerful than C? Well no, of course not, we were just only considering &lt;em&gt;safe&lt;/em&gt; code up until now. You can do anything that C can with a little &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;unsafe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, so let’s add that qualifier:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not support &lt;em&gt;safe&lt;/em&gt; movable self-referential data structures.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;But then we can’t ignore one of Rust’s most powerful features, the wrapping of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;unsafe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; code with safe code. That is to say, one can create &lt;em&gt;safe abstractions&lt;/em&gt; over what the C code would do to enable this kind of thing with safe code, through dependencies that use &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;unsafe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;As it turns out, this kind of thing is easier said than done. The original attempts at these, &lt;code class=&apos;scode&apos;&gt;owning_ref&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;rental&lt;/code&gt;, are now both unsound and unmaintained; &lt;a href=&apos;https://docs.rs/yoke&apos;&gt;&lt;code class=&apos;scode&apos;&gt;yoke&lt;/code&gt;&lt;/a&gt; is also unsound in two separate ways (&lt;a href=&apos;https://github.com/unicode-org/icu4x/issues/2095&apos;&gt;1&lt;/a&gt;, &lt;a href=&apos;https://github.com/unicode-org/icu4x/issues/3696&apos;&gt;2&lt;/a&gt;; although neither are as of today considered exploitable) and only &lt;a href=&apos;https://docs.rs/ouroboros&apos;&gt;&lt;code class=&apos;scode&apos;&gt;ouroboros&lt;/code&gt;&lt;/a&gt; has managed to fix all the issues. But it is at least &lt;em&gt;possible&lt;/em&gt;, so we can arrive at our final (really final this time, I promise) &lt;em&gt;true&lt;/em&gt; statement:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Rust does not natively support safe movable self-referential data structures.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Well isn’t that a mouthful?&lt;/p&gt;&lt;h2 id=&apos;always-a-shorter-lifetime&apos;&gt;&lt;a href=&apos;#always-a-shorter-lifetime&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Always A Shorter Lifetime&lt;/h2&gt;&lt;p&gt;Let’s go back to the code example from before, where Rust prevented us from causing UB with our stack-based self-referential type.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_1&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_2&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt;                                  ^^^^^^^^^^^^^ Compiler error!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is &lt;em&gt;weird&lt;/em&gt;, isn’t it? Because suppose we delete the second line — then it all compiles just fine, that’s just basic Rust borrowing rules. So what is up with that line? How can one usage of a value, involving only that value, get it into this weird twilight state where you can normally borrow but not uniquely borrow or move no matter what you do?&lt;/p&gt;&lt;p&gt;We know that calling any normal function on this value would &lt;em&gt;not&lt;/em&gt; put it in that twilight state:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_1&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_2&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Compiles just fine!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So this might lead you to believe that this is some special case in the Rust compiler, that it detected we were building a self-referential type and intervened personally to protect us. But one of the beauties of the borrow checker is that’s it’s &lt;em&gt;not&lt;/em&gt;, and we can show that if we first desugar the lifetimes of &lt;code class=&apos;scode&apos;&gt;uwu&lt;/code&gt;, and then try to actually construct the self-referential type within it:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self_ref&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error: lifetime may not live long enough
 --&amp;gt; src/main.rs:4:2
  |
3 | fn uwu&amp;lt;&apos;a, &apos;b&amp;gt;(self_ref: &amp;amp;&apos;a SelfRef&amp;lt;&apos;b&amp;gt;) {
  |        --  -- lifetime `&apos;b` defined here
  |        |
  |        lifetime `&apos;a` defined here
4 |     self_ref.this.set(Some(&amp;amp;self_ref));
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `&apos;a` must outlive `&apos;b`
  |
  = help: consider adding the following bound: `&apos;a: &apos;b`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fact than an error occurred at all first tells us that there is some material difference between using our magic line we had and calling the &lt;code class=&apos;scode&apos;&gt;uwu&lt;/code&gt; function as we’ve currrently defined it. The clue to this difference can be found in the compiler help message:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;consider adding the following bound: &lt;code class=&apos;scode&apos;&gt;&apos;a: &apos;b&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So we can do that, and recompile:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self_ref&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; SelfRef &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; this&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_1&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference_2&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; self_ref&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt;                                  ^^^^^^^^^^^^^ error: cannot borrow `self_ref` as mutable
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt;                                                because it is also borrowed as immutable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The same error as before! This means we’ve perfectly been able to extract the underlying “borrowing behaviour” behind the line &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; self_ref.this.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;self_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; into a function, which gives us clues as to what’s really going on here. Since we now have the right signature, we can even delete the body of &lt;code class=&apos;scode&apos;&gt;uwu&lt;/code&gt; and observe that the error remains the same:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;uwu&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Recall that &lt;code class=&apos;scode&apos;&gt;:&lt;/code&gt; in lifetimes means “outlives” or “lives at least as long as”. Therefore, the generic parameter section &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname slabel srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; of &lt;code class=&apos;scode&apos;&gt;uwu&lt;/code&gt; tells us that it operates on the lifetimes&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, which is the same length or longer than, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;and &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, which can be any lifetime.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can also use pure logic to reach the conclusion that a function accepting &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; where &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sentity sname slabel srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is enough to construct a self-referential type, and thus is also enough to prevent any future moves or unique borrows: the reference type held inside the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, but &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; in this context is &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, so therefore procuring a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is sufficient to fill that field in. If we then have some &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; where &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sentity sname slabel srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, as it’s always valid to treat objects as living shorter then they actually do, it can be implicitly converted into the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;SelfRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; as desired.&lt;/p&gt;&lt;p&gt;So what was all this about? Well really, it was just a long and roundabout way to demonstrate to you a theorem, in the mathematical sense, that holds in Rust:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;When you have some type with an invariant lifetime parameter &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and you borrow it with the lifetime &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; such that &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; outlives &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; (producing &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;), one is prevented from moving the value thereafter.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;(you might notice the presence of the qualifier “invariant” there; this is another thing I won’t go into because it’s not that relevant right now, but it is necessary for the theorem to hold).&lt;/p&gt;&lt;p&gt;We can then take the &lt;a href=&apos;https://en.wikipedia.org/wiki/Contraposition&apos;&gt;contrapositive&lt;/a&gt; of this theorem, giving us the corollary:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If one is able to move some type with an invariant lifetime parameter &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; after borrowing it, then the lifetime which it was borrowed for is strictly shorter than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; (as if it outlived &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, one would not have been able to move it).&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You might be able to see where this is going now. Take the below code, which compiles:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `Cell` is used to make T invariant in `&amp;#39;b`
&lt;/span&gt;&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Cell&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt; &lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;owo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; reference &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;value&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Cell&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here we have a function &lt;code class=&apos;scode&apos;&gt;owo&lt;/code&gt;, accepting some &lt;code class=&apos;scode&apos;&gt;T&amp;lt;&apos;b&amp;gt;&lt;/code&gt;, borrowing it, and then moving it. This satisfies all the conditions to apply the theorem above, which tells us that the duration &lt;code class=&apos;scode&apos;&gt;reference&lt;/code&gt; borrowed &lt;code class=&apos;scode&apos;&gt;value&lt;/code&gt; for &lt;strong&gt;must&lt;/strong&gt; be a lifetime that is strictly shorter than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;But as &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; was a lifetime parameter to the function &lt;code class=&apos;scode&apos;&gt;owo&lt;/code&gt;, we know that it could have been &lt;em&gt;any&lt;/em&gt; lifetime — it’s not constrained in any way. This gives the final result for this section:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Given any lifetime parameter &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, it must be possible to construct a reference whose lifetime is required to live strictly shorter than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; in order for Rust to be sound.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Or, in other words,&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;There is always a shorter lifetime.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;And this is the reason why the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; lifetime doesn’t exist, at least in its naïve form. Because if it did exist, and if you could pass it to functions, those functions could always use the trick outlined above to construct a lifetime that must be shorter. This leaves us with only two possibilities:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is not actually shorter than every other lifetime, defeating its purpose;&lt;/li&gt;&lt;li&gt;Rust is unsound.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Of course, this doesn’t not rule out a hypothetical “opposite of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;” existing entirely; merely, it proves that it must not be allowed to actually construct a variable with this lifetime. &lt;a href=&apos;https://internals.rust-lang.org/t/opposite-of-static/5128&apos;&gt;dtolnay’s 2017 proposal for the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;void&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; lifetime&lt;/a&gt; (which to my knowledge was unfortunately never pursued after that initial thread) is an example of the way in which &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; &lt;em&gt;could&lt;/em&gt; have an opposite: it can be useful in traits as he shows, but it can never actually be constructed because it’s so short that any value containing a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;void&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; would live longer than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;void&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, and thus would be disallowed.&lt;/p&gt;&lt;p&gt;This is quite counterintuitive, as after all if one can never construct a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; reference to a stack value, surely one would always be able to construct a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;void&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; reference to a stack value — but as you’ve seen, it’s the only way for Rust’s borrow checker to still be sound.&lt;/p&gt;</content></entry><entry><title>Modular Errors in Rust</title><id>https://sabrinajewson.org/blog/errors</id><updated>2023-04-08T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/errors" rel="alternate" type="text/html" title="Modular Errors in Rust"/><published>2023-04-08T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/errors" type="html">&lt;p&gt;It is thankfully common wisdom nowadays that documentation must be placed as near as possible to the code it documents, and should be fine-grained to a minimal unit of describability (the thing being documented). The practice provides numerous benefits to the codebase and project as a whole:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;When editing the source code, contributors are less likely to forget to update the documentation as well, ensuring it is kept up-to-date and accurate.&lt;/li&gt;&lt;li&gt;When reading the source code, reviewers can easily jump back and forth between the docs and the code it documents, helping them understand it and allowing them to contrast the expected with actual behaviour.&lt;/li&gt;&lt;li&gt;The codebase becomes more modular. Individual parts can be extracted into different crates or projects if necessary, and strong abstraction boundaries make the code easier to understand in small pieces.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;But you probably already knew this; after all, Rust made the excellent design choice of making it the by far easiest method of writing documentation at all. And you probably also know that these same principles apply to tests: when unit tests are kept next to their minimum unit of checkability, you get the same benefits of convenient updating, assisted understanding and modularity. And most Rust projects do use unit tests in this way (when they can, for often there are limitations that prevent it from working), which again we can thank the tooling for.&lt;/p&gt;&lt;p&gt;But that’s all old news. What I’m here to convince you of today is that this principle applies additionally to &lt;em&gt;error types&lt;/em&gt;: that is, error types should be located near to their unit of fallibility. To illustrate this point, I will follow the initial development and later API improvement of a hypothetical Rust library.&lt;/p&gt;&lt;h2 id=&apos;blocks-txt&apos;&gt;&lt;a href=&apos;#blocks-txt&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Case Study: A Blocks.txt Parser&lt;/h2&gt;&lt;p&gt;Suppose you’re a library author, and you’re working on a crate to implement the parsing of &lt;a href=&apos;https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt&apos;&gt;Blocks.txt&lt;/a&gt; in the &lt;a href=&apos;https://unicode.org/ucd/&apos;&gt;Unicode Character Database&lt;/a&gt;. If you’re not familiar with this file, it defines the list of so-called &lt;a href=&apos;https://en.wikipedia.org/wiki/Unicode_block&apos;&gt;Unicode blocks&lt;/a&gt;, which are non-overlapping contiguous categories that Unicode characters can be sorted into. It looks a bit like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;0000..007F; Basic Latin
0080..00FF; Latin-1 Supplement
0100..017F; Latin Extended-A
0180..024F; Latin Extended-B
0250..02AF; IPA Extensions
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This file tells you that, for example, the character “½”, &lt;code class=&apos;scode&apos;&gt;U+00BD&lt;/code&gt;, is in the block “Latin-1 Supplement” because &lt;code class=&apos;scode&apos;&gt;0x0080 ≤ 0x00BD ≤ 0x00FF&lt;/code&gt;. Every character has an associated block; characters which have not yet been assigned a block in the file above are considered to be in the special pseudo-block &lt;code class=&apos;scode&apos;&gt;No_Block&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So let’s get started on a Rust parser. The specification for the format is given by &lt;a href=&apos;https://www.unicode.org/reports/tr44/#Format_Conventions&apos;&gt;section 4.2 of Unicode Annex #44&lt;/a&gt;, but the format is so trivial you could almost guess it. Upon seeing this task, a typical Rustacean may write code like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdocumentation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//!&lt;/span&gt; This crate provides tools for working with Unicode blocks and its data files.
&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;RangeInclusive&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, String&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_file&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;read_to_string&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;download&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Agent&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; response &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; agent.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;LATEST_URL&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;response.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;into_string&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;FromStr &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Err&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; Error&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_str&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Err&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; ranges &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; s
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;#&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; _&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;l&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;line&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;is_empty&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;ok_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Error&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoSemicolon&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; end&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;..&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;ok_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Error&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoDotDot&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; start &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str_radix&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; end &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str_radix&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;end&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt;end&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;to_owned&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;smeta spath srust&quot;&gt;collect&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; ranges &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we need to define an error type, so let’s just follow the “big &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;” convention and bash out some boilerplate that gets the job done:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdocumentation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;///&lt;/span&gt; An error in this library.
&lt;/span&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	NoSemicolon&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	NoDotDot&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	ParseInt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseIntError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Io&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Ureq&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;From&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;ParseIntError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Error&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseIntError&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;From&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Error&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Io&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;From&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Error&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Ureq&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Error&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoSemicolon &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no semicolon&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoDotDot &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no `..` in character range&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Display&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fmt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Io&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Display&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fmt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Ureq&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Display&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fmt&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;error&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Error&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Lastly, a couple other bits and imports go at the end:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;LATEST_URL&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;cmp&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fmt&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Display&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Formatter&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fs&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;io&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;num&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseIntError&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ops&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;RangeInclusive&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;path&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;str&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;FromStr&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we’re done.&lt;/p&gt;&lt;p&gt;There are a few small things to note with this code just before we move on:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I omitted documentation, since it’s not relevant to the real example; in actual code, all the public items would be documented. Similarly, unit tests are omitted.&lt;/li&gt;&lt;li&gt;In a real library, one would not hard-depend on &lt;a href=&apos;https://docs.rs/ureq&apos;&gt;ureq&lt;/a&gt; and &lt;code class=&apos;scode&apos;&gt;std&lt;/code&gt; and would use feature-flags instead, but again I omitted that for this example.&lt;/li&gt;&lt;li&gt;You might have noticed I put my imports on separate lines each at bottom — I do have my reasons for this, but that’s best saved for another day ;)&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Blocks&lt;/code&gt; implements &lt;a href=&apos;https://doc.rust-lang.org/stable/std/str/trait.FromStr.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;FromStr&lt;/code&gt;&lt;/a&gt;, but not &lt;a href=&apos;https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;TryFrom&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;. This is actually intentional, because despite being nearly identical traits signature-wise they mean two very different things: &lt;code class=&apos;scode&apos;&gt;FromStr&lt;/code&gt; implies &lt;em&gt;parsing&lt;/em&gt; from a string whereas &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;TryFrom&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is for when your data type &lt;em&gt;is&lt;/em&gt; a subset of all strings. In our case, &lt;code class=&apos;scode&apos;&gt;FromStr&lt;/code&gt; is the correct one to use.&lt;/li&gt;&lt;li&gt;The &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; implementation of &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; formats error messages like &lt;code class=&apos;scode&apos;&gt;no semicolon&lt;/code&gt; in lowercase and without a full stop at the end — this is in accordance with &lt;a href=&apos;https://doc.rust-lang.org/stable/std/error/trait.Error.html&apos;&gt;conventions established by the Standard Library&lt;/a&gt; (“Error messages are typically concise lowercase sentences without trailing punctuation”). A common pitfall of both new and experienced Rustaceans is using incorrect casing for error messages.&lt;/li&gt;&lt;li&gt;Another common pitfall is naming things like what we’ve named &lt;code class=&apos;scode&apos;&gt;Error::Io&lt;/code&gt; as &lt;code class=&apos;scode&apos;&gt;Error::IoError&lt;/code&gt; instead. Simply: you don’t need the &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; suffix, it says it in the name already!&lt;/li&gt;&lt;li&gt;One could use the &lt;a href=&apos;https://docs.rs/thiserror/latest/thiserror/&apos;&gt;thiserror&lt;/a&gt; crate to shorten the code by using a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Error&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. Personally, I would never use this for a library crate since it’s really not that many lines of code saved for a whole extra dependency, but you might want to know about it.&lt;/li&gt;&lt;li&gt;The &lt;code class=&apos;scode&apos;&gt;Ureq&lt;/code&gt; variant of the &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; enum is boxed because &lt;code class=&apos;scode&apos;&gt;ureq::Error&lt;/code&gt; is actually very large and Clippy complains about it.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So there we have it: our perfect little library, let’s go off and publish it to crates.io.&lt;/p&gt;&lt;p&gt;What we’ve written so far, with regard to error handling, is what I’d say most libraries on crates.io do. It’s by far the most &lt;em&gt;common&lt;/em&gt; way of handling errors: just stick everything in a big &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; of “different ways things can go wrong in the library” and don’t think about it after that. But unfortunately, while it is &lt;em&gt;common&lt;/em&gt; it is not exactly &lt;em&gt;good&lt;/em&gt;, for a few reasons the rest of this post will be covering.&lt;/p&gt;&lt;h3 id=&apos;problem-1-backtraces&apos;&gt;&lt;a href=&apos;#problem-1-backtraces&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Problem 1: Backtraces&lt;/h3&gt;&lt;p&gt;Suppose you then decide to use your library in a CLI application; and as per usual advice and your own experience, you decide to use &lt;a href=&apos;https://docs.rs/anyhow&apos;&gt;anyhow&lt;/a&gt; to handle the errors in it. So you write out all your code and it looks a little like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;anyhow&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;init_something&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; blocks &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Blocks&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_file&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;init_something_else&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Run the main code…
&lt;/span&gt;	&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;unicode_blocks&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Blocks&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Looks good, so you go ahead and run it — only, you’re rather abruptly met with:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;Error: invalid digit found in string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Um, okay. That doesn’t help us very much at all. What went wrong here?&lt;/p&gt;&lt;p&gt;Well, much pain and many &lt;code class=&apos;scode&apos;&gt;dbg!&lt;/code&gt; statements later, you discover that the culprit is that somehow, on line 223 of &lt;code class=&apos;scode&apos;&gt;Blocks.txt&lt;/code&gt; you replaced a &lt;code class=&apos;scode&apos;&gt;0&lt;/code&gt; with an &lt;code class=&apos;scode&apos;&gt;O&lt;/code&gt;. Oops!&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource sdiff&quot;&gt;&lt;span class=&quot;smeta sdiff sheader sfrom-file&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sfrom-file sdiff&quot;&gt;---&lt;/span&gt; Blocks.txt
&lt;/span&gt;&lt;span class=&quot;smeta sdiff sheader sto-file&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sto-file sdiff&quot;&gt;+++&lt;/span&gt; Blocks.txt
&lt;/span&gt;&lt;span class=&quot;smeta sdiff srange sunified&quot;&gt;&lt;span class=&quot;spunctuation sdefinition srange sdiff&quot;&gt;@@&lt;/span&gt; &lt;span class=&quot;smeta stoc-list sline-number sdiff&quot;&gt;-222,3 +222,3&lt;/span&gt; &lt;span class=&quot;spunctuation sdefinition srange sdiff&quot;&gt;@@&lt;/span&gt;
&lt;/span&gt; 10800..1083F; Cypriot Syllabary
&lt;span class=&quot;smarkup sdeleted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sdeleted sdiff&quot;&gt;-&lt;/span&gt;10840..1O85F; Imperial Aramaic
&lt;/span&gt;&lt;span class=&quot;smarkup sinserted sdiff&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sinserted sdiff&quot;&gt;+&lt;/span&gt;10840..1085F; Imperial Aramaic
&lt;/span&gt; 10860..1087F; Palmyrene
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then you run it again and it works fine.&lt;/p&gt;&lt;p&gt;But it didn’t have to be this hard. The error message &lt;em&gt;could&lt;/em&gt; have displayed something more useful, and maybe this is just a pipe dream, but I’ve seen &lt;code class=&apos;scode&apos;&gt;anyhow&lt;/code&gt; emit this sort of thing before:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;Error: error reading `Blocks.txt`

Caused by:
	0: invalid Blocks.txt data on line 223
	1: one end of range is not a valid hexidecimal integer
	2: invalid digit found in string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s so much more helpful — you wouldn’t ever have had to suspect &lt;code class=&apos;scode&apos;&gt;init_something&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;init_something_else&lt;/code&gt; as potential causes of the error, or even search &lt;code class=&apos;scode&apos;&gt;Blocks.txt&lt;/code&gt; for mistakes, it completely guides you to exactly where it went wrong!&lt;/p&gt;&lt;p&gt;Oh well, you say to yourself, at least this time it was decently obvious where the source of the error came from; at least I wasn’t getting a &lt;a href=&apos;https://github.com/tokio-rs/mio/issues/1444&apos;&gt;file not found error from &lt;code class=&apos;scode&apos;&gt;TcpListener::bind&lt;/code&gt;&lt;/a&gt; (the natural conclusion to this kind of “flat”-style error handling). But wouldn’t it be nice if all errors came with backtrace and context tracking built-in?&lt;/p&gt;&lt;h3 id=&apos;problem-2-inextensibility&apos;&gt;&lt;a href=&apos;#problem-2-inextensibility&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Problem 2: Inextensibility&lt;/h3&gt;&lt;p&gt;At least one of the things in the above image looks feasible to fix though: adding line numbers as context to the error messages. All we have to do is return to our &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; enum and add more fields to the &lt;code class=&apos;scode&apos;&gt;NoSemicolon&lt;/code&gt;, and &lt;code class=&apos;scode&apos;&gt;NoDotDot&lt;/code&gt;, and &lt;code class=&apos;scode&apos;&gt;ParseInt&lt;/code&gt;, variants:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	NoSemicolon &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; line&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	NoDotDot &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; line&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; line&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; source&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseIntError &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Io&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Ureq&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Except… we can’t do that without breaking backward compatibility, because while the enum itself is &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; the individual variants aren’t, meaning you’ve fixed them to forever have the fields they do currently (without breaking changes).&lt;/p&gt;&lt;h3 id=&apos;problem-3-error-matching&apos;&gt;&lt;a href=&apos;#problem-3-error-matching&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Problem 3: Error Matching&lt;/h3&gt;&lt;p&gt;Okay, so back to the application. You’ve now realized that you still want to call &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Blocks&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_file&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, but if it fails with a “file not found” error you actually want to download the file automatically instead of exiting the program entirely. We have to match on the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Result&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; for that:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; blocks &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Blocks&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_file&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;blocks&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; blocks&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;unicode_blocks&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Error&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Io&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; e.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NotFound &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; download and retry…
&lt;/span&gt;	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Great! But the compiler is yelling that the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; arms aren’t exhaustive. Not too hard to fix, let’s look at the cases we need to deal with:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;NoSemicolon&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;NoDotDot&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ParseInt&lt;/code&gt;: Those are pretty obvious, they look like parsing errors, so we can just propagate them.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Io&lt;/code&gt;: Other I/O errors than “file not found” can also safely be propagated.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Ureq&lt;/code&gt;: Ummm…? Wait, is this function doing HTTP requests? Let me check the source code again… [please stand by…] oh okay, so it’s not. Then I could add an &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;unreachable!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; here which would be correct and indicates semantics nicely; on the other hand, nowhere is it written in the documentation of the API that it &lt;em&gt;won’t&lt;/em&gt; ever return this, so maybe I should just propagate it anyway?&lt;/li&gt;&lt;li&gt;Oh, and I forgot, we added &lt;code class=&apos;scode&apos;&gt;#[non_exhaustive]&lt;/code&gt; to &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;Error&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; so there’s always the possibility of it returning a variant that doesn’t exist yet. Well, I guess we can just propagate it anyway.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, this situation isn’t ideal. The library doesn’t document anywhere what errors a given function &lt;em&gt;can&lt;/em&gt; return, so users are often left shooting in the dark. From personal experience, there have been many times I have seen an error variant which was appropriate for me to catch, then I had to spend ages digging around in the source code to find out whether it was &lt;em&gt;actually&lt;/em&gt; generated or not — and even an answer to that doesn’t constitute an API guarantee that it will or won’t be in future.&lt;/p&gt;&lt;p&gt;Another issue with the code that we’ve written is that it’s entirely non-obvious that our &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; arm refers specifically to the &lt;code class=&apos;scode&apos;&gt;Blocks.txt&lt;/code&gt; file not being found. The arm itself just says “check if an I/O not found error occurred”, but in theory, and especially for more complex functions, an I/O not found error could mean one of several different things that the user can no longer differentiate between because they were all put together in a single &lt;code class=&apos;scode&apos;&gt;Io&lt;/code&gt; variant.&lt;/p&gt;&lt;h3 id=&apos;problem-4-privacy-and-stability&apos;&gt;&lt;a href=&apos;#problem-4-privacy-and-stability&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Problem 4: Privacy and Stability&lt;/h3&gt;&lt;p&gt;One very common mistake libraries make with this style of big-&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; error is accidentally exposing dependencies intended to be private in their public API through error types. In our example code, suppose &lt;code class=&apos;scode&apos;&gt;std::fs&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;io::Error&lt;/code&gt; weren’t part of the standard library but were rather types from an external library that was on version &lt;code class=&apos;scode&apos;&gt;0.4&lt;/code&gt;. Now, when they bump their version to &lt;code class=&apos;scode&apos;&gt;0.5&lt;/code&gt; I &lt;em&gt;also&lt;/em&gt; have to make a breaking change to update it to the newer version, because I exposed the &lt;code class=&apos;scode&apos;&gt;io::Error&lt;/code&gt; type in my public API through the &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; enum, even though I never expose my usage of the library anywhere else (it’s covered up by the opaque interface of &lt;code class=&apos;scode&apos;&gt;from_file&lt;/code&gt;). The same issue occurs if I tried to switch out my usage of that library for a different one; it also forbids me from ever releasing 1.0 until the dependency library also reaches 1.0 as per the &lt;a href=&apos;https://rust-lang.github.io/api-guidelines/necessities.html#public-dependencies-of-a-stable-crate-are-stable-c-stable&apos;&gt;C-STABLE&lt;/a&gt; API requirement.&lt;/p&gt;&lt;p&gt;This is hard to fix with this approach to errors, because &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; data is hardcoded to always use inherited visibility, meaning if the outer &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; fields are public &lt;em&gt;all&lt;/em&gt; inner fields are too. Private fields are also useful in errors in general, for reasons other than stability: private fields are just generally a nice feature to have on types.&lt;/p&gt;&lt;h3 id=&apos;problem-5-non-modularity&apos;&gt;&lt;a href=&apos;#problem-5-non-modularity&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Problem 5: Non-Modularity&lt;/h3&gt;&lt;p&gt;And lastly, touching back on what I mentioned at the beginning of this article: this approach to error handling is &lt;em&gt;non-modular&lt;/em&gt;. I couldn’t easily take a component alone, like the parser, and extract it to a different crate, because I’d have to change many APIs or otherwise hack around it. Every API is interconnected with each other through the underlying error type, tying the crate together in a big knot that makes it difficult to untangle and remove stuff.&lt;/p&gt;&lt;p&gt;This kind of non-modularity also makes the codebase more difficult to understand: one is forced, to a greater degree, to learn the entire codebase at once to work on it, rather than learn it piece by piece, a far preferable way of learning.&lt;/p&gt;&lt;h2 id=&apos;guidelines-for-good-errors&apos;&gt;&lt;a href=&apos;#guidelines-for-good-errors&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Guidelines for Good Errors&lt;/h2&gt;&lt;p&gt;So the current error type we have has problems. But how do we fix them? And this is where we bring in that principle from the start:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Error types should be located near to their unit of fallibility.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The key phrase here is “unit of fallibility”. What are the units of fallibility in our library? Well, it’s certainly not &lt;em&gt;the library itself&lt;/em&gt; — the library is just a way of interacting with Unicode blocks, and it’s not like that can particularly fail. The only libraries that &lt;em&gt;would&lt;/em&gt; have the entire library as a unit of fallibility are those whose only purpose is to perform a single operation (they typically have an API surface of no more than two functions, maybe a &lt;code class=&apos;scode&apos;&gt;Params&lt;/code&gt; builder type, and nothing more).&lt;/p&gt;&lt;p&gt;This tells us that the &lt;code class=&apos;scode&apos;&gt;unicode_blocks::Error&lt;/code&gt; type is inherently misguided. Rather, the units of fallibility in our case are the &lt;em&gt;operations we do&lt;/em&gt;, like downloading, reading a file, and parsing.&lt;/p&gt;&lt;p&gt;Now, things get a little subjective at this point on deciding what counts as two separate units or the same unit. In general, you should ask yourself the following two questions:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Do they have different ways in which they can fail?&lt;/li&gt;&lt;li&gt;Should they show different error messages should they fail?&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If the answer to either of those questions is “yes”, then they should normally be separate error types.&lt;/p&gt;&lt;p&gt;For us, this means we actually want &lt;em&gt;three&lt;/em&gt; separate error types:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;FromFileError&lt;/code&gt;, for errors in &lt;code class=&apos;scode&apos;&gt;Blocks::from_file&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;DownloadError&lt;/code&gt;, for errors in &lt;code class=&apos;scode&apos;&gt;Blocks::download&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;ParseError&lt;/code&gt;, for errors in &lt;code class=&apos;scode&apos;&gt;from_str&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&apos;leveraging-source&apos;&gt;&lt;a href=&apos;#leveraging-source&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Leveraging the &lt;code class=&apos;scode&apos;&gt;.source()&lt;/code&gt; method&lt;/h3&gt;&lt;p&gt;Earlier, we said we wanted our error messages (printed with &lt;code class=&apos;scode&apos;&gt;anyhow&lt;/code&gt;) to look good, like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;Error: error reading `Blocks.txt`

Caused by:
	0: invalid Blocks.txt data on line 223
	1: one end of range is not a valid hexidecimal integer
	2: invalid digit found in string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So how do we get &lt;code class=&apos;scode&apos;&gt;anyhow&lt;/code&gt; to print this? It turns out what the library calls internally is the &lt;a href=&apos;https://doc.rust-lang.org/stable/std/error/trait.Error.html#method.source&apos;&gt;&lt;code class=&apos;scode&apos;&gt;Error::source()&lt;/code&gt;&lt;/a&gt; method, a default-implemented method of the &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; trait that tells you the cause of an error. What we see in the above graphic depicts:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;an error type (we know to be &lt;code class=&apos;scode&apos;&gt;FromFileError&lt;/code&gt;) whose &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; implementation prints “error reading &lt;code class=&apos;scode&apos;&gt;Blocks.txt&lt;/code&gt;”, and whose &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; is…&lt;/li&gt;&lt;li&gt;…another error type, whose &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; implementation prints “invalid Blocks.txt data on line 223”, and whose &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; is…&lt;/li&gt;&lt;li&gt;…another error type, whose &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; implementation prints “one end of range is not a valid hexidecimal integer”, and whose &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; is…&lt;/li&gt;&lt;li&gt;…another error type (we know to be &lt;code class=&apos;scode&apos;&gt;ParseIntError&lt;/code&gt;) whose &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; implementation prints “invalid digit found in string” and whose &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; is &lt;code class=&apos;scode&apos;&gt;None&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That might seem like a lot of layers, but they all map very nicely to our code: layer 1 is a &lt;code class=&apos;scode&apos;&gt;FromFileError&lt;/code&gt;, layer 2 has to be our &lt;code class=&apos;scode&apos;&gt;ParseError&lt;/code&gt;, layer 3 has to be something contained within the &lt;code class=&apos;scode&apos;&gt;ParseError&lt;/code&gt;, and layer 4 is &lt;code class=&apos;scode&apos;&gt;ParseIntError&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This leads us to a much nicer structure for the error types in the &lt;code class=&apos;scode&apos;&gt;from_file&lt;/code&gt; API.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FromFileErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;error reading `&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{}&lt;/span&gt;`&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadFile&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;FromFileErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	ReadFile&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This error:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;has very good backtraces, as it implements &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;source()&lt;/code&gt; well;&lt;/li&gt;&lt;li&gt;is extensible, as the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is attributed with &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;supports precise error matching, as we’ve now &lt;em&gt;automatically&lt;/em&gt; given the public API guarantee that we won’t produce HTTP errors from our function, so our users needn’t worry about dealing with that case;&lt;/li&gt;&lt;li&gt;makes it clear where the &lt;code class=&apos;scode&apos;&gt;io::Error&lt;/code&gt;s can come from, because the variant is named &lt;code class=&apos;scode&apos;&gt;ReadFile&lt;/code&gt; instead of simply &lt;code class=&apos;scode&apos;&gt;Io&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;would easily be able to adjust to support hiding &lt;code class=&apos;scode&apos;&gt;io::Error&lt;/code&gt; from the public API surface simply by making &lt;code class=&apos;scode&apos;&gt;kind&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;FromFileErrorKind&lt;/code&gt; private;&lt;/li&gt;&lt;li&gt;is entirely modular, being conceptually contained within the &lt;code class=&apos;scode&apos;&gt;from_file&lt;/code&gt; logic portion of the code, so it can be extracted, learnt independently, et cetera.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code class=&apos;scode&apos;&gt;ParseError&lt;/code&gt; can be defined in a somewhat similar fashion, also with the above benefits.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;,
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;invalid Blocks.txt data on line &lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.line &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	NoSemicolon&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	NoDotDot&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseIntError &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoSemicolon &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no semicolon&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoDotDot &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no `..` in range&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;one end of range is not a valid hexadecimal integer&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;source&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; variants themselves are &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, so that they can be extended in future with more information.&lt;/p&gt;&lt;p&gt;There is a slight deviation from &lt;code class=&apos;scode&apos;&gt;FromFileError&lt;/code&gt;’s design here, that its corresponding &lt;code class=&apos;scode&apos;&gt;*Kind&lt;/code&gt; type actually implements &lt;code class=&apos;scode&apos;&gt;Display&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Error&lt;/code&gt; in and of itself instead of simply existing as a data holder for other error types. The logic is that while we could separate make unit structs for &lt;code class=&apos;scode&apos;&gt;NoSemicolon&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;NoDotDot&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;ParseInt&lt;/code&gt;, it just isn’t very necessary here (where on the other hand &lt;code class=&apos;scode&apos;&gt;io::Error&lt;/code&gt; is an external type and &lt;code class=&apos;scode&apos;&gt;ParseError&lt;/code&gt; is required to be a distinct type because of &lt;code class=&apos;scode&apos;&gt;FromStr&lt;/code&gt;). However, sometimes it is still better to make unit structs: it depends on the use case.&lt;/p&gt;&lt;p&gt;Finally, &lt;code class=&apos;scode&apos;&gt;DownloadError&lt;/code&gt; showcases a similar pattern (although it’s not that interesting at this point):&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; DownloadErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;failed to download Blocks.txt from the Unicode website&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Request&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadBody&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;DownloadErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	Request&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	ReadBody&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that we could have merged &lt;code class=&apos;scode&apos;&gt;DownloadErrorKind&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;DownloadError&lt;/code&gt; into a single type; I chose not to here in favour of extensibility, because it seems quite possible that one would want to add more fields to &lt;code class=&apos;scode&apos;&gt;DownloadError&lt;/code&gt; in future. But for some cases it definitely makes sense.&lt;/p&gt;&lt;h3 id=&apos;constructing-the-error-types&apos;&gt;&lt;a href=&apos;#constructing-the-error-types&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Constructing the error types&lt;/h3&gt;&lt;p&gt;If you try to implement the functions that return these error types, you’ll quickly run into something rather annoying: they require quite a bit of boilerplate to use. For example, the body of &lt;code class=&apos;scode&apos;&gt;from_file&lt;/code&gt; now looks like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_file&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, FromFileError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; path &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;as_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;read_to_string&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadFile&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;s&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;FromFileError &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		path&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		kind&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Yeah, not the prettiest. Unfortunately, I don’t think there’s much we can actually do here; once we get &lt;code class=&apos;scode&apos;&gt;try&lt;/code&gt; blocks it’ll definitely be nicer, but it seems to be an unavoidable cost of many good error-handling schemes.&lt;/p&gt;&lt;h3 id=&apos;on-from&apos;&gt;&lt;a href=&apos;#on-from&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;On &lt;code class=&apos;scode&apos;&gt;From&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;One thing notably omitted from the definitions of the new error types was implementations of &lt;code class=&apos;scode&apos;&gt;From&lt;/code&gt; for inner types. There is no problem with them really, one just has to be careful that it (a) works with extensibility and (b) actually makes &lt;em&gt;sense&lt;/em&gt;. For example, taking &lt;code class=&apos;scode&apos;&gt;FromFileErrorKind&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;FromFileErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	ReadFile&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While it does make sense to implement &lt;code class=&apos;scode&apos;&gt;From&amp;lt;ParseError&amp;gt;&lt;/code&gt;, because &lt;code class=&apos;scode&apos;&gt;Parse&lt;/code&gt; is literally the name of one of the variants of &lt;code class=&apos;scode&apos;&gt;FromFileErrorKind&lt;/code&gt;, it does not make sense to implement &lt;code class=&apos;scode&apos;&gt;From&amp;lt;io::Error&amp;gt;&lt;/code&gt; because such an implementation would implicitly add meaning that one failed during the process of reading the file from disk (as the variant is named &lt;code class=&apos;scode&apos;&gt;ReadFile&lt;/code&gt; instead of &lt;code class=&apos;scode&apos;&gt;Io&lt;/code&gt;). Constraining the meaning of “any I/O error” to “an error reading the file from the disk” is helpful but should not be done implicitly, thus rendering &lt;code class=&apos;scode&apos;&gt;From&lt;/code&gt; inappropriate.&lt;/p&gt;&lt;h3 id=&apos;on-nearness&apos;&gt;&lt;a href=&apos;#on-nearness&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;On “nearness”&lt;/h3&gt;&lt;p&gt;One part of my principle of errors I haven’t yet touched on is the aspect of “nearness”; that errors should, as well as having an appropriate associated unit of fallibility, be sufficiently &lt;em&gt;near&lt;/em&gt; to it. The fact is, with Rust’s current design you can’t put them as close as I’d like without sacrificing documentation quality. That is, while you’d ideally write something like:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_file&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, FromFileError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;download&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Agent&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, DownloadError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This just makes your rustdoc look bad, since the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; blocks are needlessly separated. So usually I end up writing something more like:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_file&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, FromFileError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;download&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Agent&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, DownloadError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; … &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s unfortunate, but I don’t think it’s terrible — you still get most the benefits of nearness.&lt;/p&gt;&lt;p&gt;The only thing to make sure of is that they stay in the same module; this same concept of “nearness” is a similar reason why one should be extremely wary of any module named “errors”, which is of equal organizational value to having a drawer labelled “medium-sized and flat”.&lt;/p&gt;&lt;h3 id=&apos;verbosity&apos;&gt;&lt;a href=&apos;#verbosity&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Verbosity&lt;/h3&gt;&lt;p&gt;Possibly the biggest objection to this style of error is the sheer number of lines of code required to implement it; error types aren’t a trivial number of lines, and making a new error type for every function can easily hugely increase the number of lines a library needs. This is definitely a valid criticism, I also find it tiresome to write the same things over and over again, but let me also offer an alternate perspective: rather than seeing it as simply a more verbose way to do the same thing, see it as due treatment for an oft ignored area.&lt;/p&gt;&lt;p&gt;Traditionally, errors as something to be pushed to the side as soon as possible to get on with “real” logic. But the art of resilient, reliable and user-friendly systems considers &lt;em&gt;all&lt;/em&gt; outcomes, not just the successful one. As a success story, look no further than the Rust compiler itself; I don’t think it would be an exaggeration to say that Rust enjoys the current popularity it does &lt;em&gt;because of&lt;/em&gt; how good its error messages are, and how much effort was put into it.&lt;/p&gt;&lt;h2 id=&apos;conclusion&apos;&gt;&lt;a href=&apos;#conclusion&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;This post is not here to give you a structure that you should follow for your errors. The structure I used as an example in this post had one specific use case, and filled it appropriately. If you find you can apply the same structure to your own code and it works well, then great! But really, what post is for is to get people to &lt;em&gt;start caring&lt;/em&gt; about errors, putting actual thought into their designs, and learning how to elegantly pull off	ever-present balancing act between the five goals of good backtraces, extensibility, inspectability (matching), stability and modularity.&lt;/p&gt;&lt;p&gt;If there’s one thing I wish for you to take away, it’s that error handling is &lt;em&gt;hard&lt;/em&gt;, but it’s &lt;em&gt;worth it&lt;/em&gt; to learn. Because I’m tired of having to deal with lazy kitchen-sink-type errors.&lt;/p&gt;&lt;details&gt;&lt;summary&gt;The final code&lt;/summary&gt;
&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdocumentation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//!&lt;/span&gt; This crate provides types for UCD’s `Blocks.txt`.
&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;RangeInclusive&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, String&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;block_of&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;char&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.ranges
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;binary_search_by&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; _&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;c&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;smeta spath srust&quot;&gt;cmp&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Ordering&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Less
				&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;c&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;smeta spath srust&quot;&gt;cmp&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Ordering&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Greater
				&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;smeta spath srust&quot;&gt;cmp&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Ordering&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Equal
				&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.ranges&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;No_Block&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_file&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, FromFileError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; path &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;as_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;read_to_string&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadFile&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
				.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;FromFileError &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			path&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			kind&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;download&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Agent&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, DownloadError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; response &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; agent
				.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;LATEST_URL&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
				.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
				.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Request&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;
				&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;response
					.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;into_string&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
					.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadBody&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;DownloadError &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; kind &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;FromStr &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Blocks&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Err&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; ParseError&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_str&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Err&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; ranges &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; s
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;
					i&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
					line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;#&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; _&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;line&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;line&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
				&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;_&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;is_empty&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;line&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; line.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;ok_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ParseErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoSemicolon&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; end&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; range.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;split_once&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;..&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;ok_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ParseErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoDotDot&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; start &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str_radix&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
						.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ParseErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; end &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_str_radix&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;end&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
						.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ParseErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt;end&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; name.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;to_owned&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
				&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
				.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;ParseError &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; line&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; i&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; kind &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			.&lt;span class=&quot;smeta spath srust&quot;&gt;collect&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, ParseError&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport stype srust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; ranges &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; DownloadErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;failed to download Blocks.txt from the Unicode website&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;DownloadError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Request&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadBody&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;DownloadErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;DownloadErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	Request&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ureq&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	ReadBody&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FromFileErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;error reading `&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{}&lt;/span&gt;`&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.path.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;FromFileError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ReadFile&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;FromFileErrorKind&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;FromFileErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	ReadFile&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;io&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	Parse&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;ParseError&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;,
	&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;svariable sother smember srust&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseErrorKind,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;invalid Blocks.txt data on line &lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.line &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseError&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.kind&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	NoSemicolon&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	NoDotDot&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;non_exhaustive&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ParseIntError &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Display &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fmt&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Formatter&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Result&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoSemicolon &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no semicolon&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;NoDotDot &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; f.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;write_str&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;no `..` in range&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;ssupport smacro srust&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;f,&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;one end of range is not a valid hexadecimal integer&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Error &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ParseErrorKind&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;dyn Error + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseInt &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; source &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;source&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;test&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta smodule srust&quot;&gt;&lt;span class=&quot;sstorage stype smodule srust&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;sentity sname smodule srust&quot;&gt;tests&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;real_unicode&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; data &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;include_str!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;../Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;smeta spath srust&quot;&gt;parse&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Blocks&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;data.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;block_of&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant scharacter sescape srust&quot;&gt;\u{0080}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Latin-1 Supplement&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;data.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;block_of&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;½&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Latin-1 Supplement&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;data.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;block_of&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant scharacter sescape srust&quot;&gt;\u{00FF}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Latin-1 Supplement&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;data.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;block_of&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted ssingle srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant scharacter sescape srust&quot;&gt;\u{EFFFF}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;No_Block&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;crate&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Blocks&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;LATEST_URL&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;cmp&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;error&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Error&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fmt&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Display&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fmt&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Formatter&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;fs&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;io&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;num&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;ParseIntError&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;ops&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;RangeInclusive&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;path&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;str&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;FromStr&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
</content></entry><entry><title>The Better Alternative to Lifetime GATs</title><id>https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats</id><updated>2022-05-30T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats" rel="alternate" type="text/html" title="The Better Alternative to Lifetime GATs"/><published>2022-05-01T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats" type="html">&lt;p&gt;Update (2022-05-30): &lt;a href=&apos;https://github.com/danielhenrymantilla&apos;&gt;danielhenrymantilla&lt;/a&gt; recently released a crate, &lt;a href=&apos;https://docs.rs/nougat&apos;&gt;nougat&lt;/a&gt;, which provides a proc macro that allows you to use the technique presented in this article with the same syntax as regular GATs. I encourage you to check it out!&lt;/p&gt;&lt;h2 id=&apos;where-real-gats-fall-short&apos;&gt;&lt;a href=&apos;#where-real-gats-fall-short&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Where real GATs fall short&lt;/h2&gt;&lt;p&gt;&lt;a href=&apos;https://github.com/rust-lang/rust/issues/44265&apos;&gt;GATs&lt;/a&gt; are an unstable feature of Rust, likely to be stabilized in the next few versions, that allow you to add generic parameters on associated types in traits. The motivating example for this feature is the “lending iterator” trait, which allows you to define an iterator for which only one of its items can exist at any given time. With lifetime GATs, its signature would look something like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and it would allow you to implement iterators you otherwise wouldn’t have been able to, like &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; (since the slices it returns overlap, a regular iterator won’t work):&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;core&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;mem&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;windows_mut&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;svariable sparameter srust&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; [T],
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_ne!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	WindowsMut &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; slice&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; first&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;true&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; [T],
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;bool&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sentity sname slabel srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;mem&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;take&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get_mut&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;try_into&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Great! That’s our &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; trait, done and dusted, and we’ve proven that it works. End of article.&lt;/p&gt;&lt;p&gt;Well, before we go let’s just try one last thing: actually consuming the &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; iterator. There’s no need to really because I’m sure it’ll work, but we’ll do it anyway for the learning experience, right?&lt;/p&gt;&lt;p&gt;So first we’ll define a function that prints each element of a lending iterator. This is pretty simple, we just have to use &lt;a href=&apos;https://doc.rust-lang.org/nomicon/hrtb.html&apos;&gt;HRTBs&lt;/a&gt; to write the trait bound and a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; loop for the actual consumption.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;print_items&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; iter.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{item:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All good so far, this compiles fine. Now we’ll actually call it with an iterator:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;print_items&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;windows_mut&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This should obviously compile since &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is definitely &lt;code class=&apos;scode&apos;&gt;Debug&lt;/code&gt;. So we can just run &lt;code class=&apos;scode&apos;&gt;cargo run&lt;/code&gt; and see the ou–&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0716]: temporary value dropped while borrowed
  --&amp;gt; src/main.rs:45:58
   |
45 |     print_items::&amp;lt;WindowsMut&amp;lt;&apos;_, _, 2&amp;gt;&amp;gt;(windows_mut(&amp;amp;mut [1, 2, 3]));
   |     -----------------------------------------------------^^^^^^^^^--
   |     |                                                    |
   |     |                                                    creates a temporary which is freed while still in use
   |     argument requires that borrow lasts for `&apos;static`
46 | }
   | - temporary value is freed at the end of this statement
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;oh.&lt;/p&gt;&lt;p&gt;oh no.&lt;/p&gt;&lt;h2 id=&apos;what-went-wrong&apos;&gt;&lt;a href=&apos;#what-went-wrong&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;What went wrong?&lt;/h2&gt;&lt;p&gt;Clearly, something’s not right here. rustc is telling us that for some reason, our borrow of the array &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is required to live for &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; — but we haven’t written any &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bounds anywhere, so this doesn’t really make much sense. We’ll have to put ourselves in the mindset of the compiler for a bit so that we can try to figure out what’s happening.&lt;/p&gt;&lt;p&gt;First of all, we create an iterator of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, where &lt;code class=&apos;scode&apos;&gt;&apos;0&lt;/code&gt; is the name of some local lifetime (notably, this lifetime is necessarily shorter than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;). Then we pass this iterator type into the function &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt;, in doing so setting its &lt;code class=&apos;scode&apos;&gt;I&lt;/code&gt; generic parameter to the aforementioned type &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So now we just need to make sure that the trait bounds hold. Substituting &lt;code class=&apos;scode&apos;&gt;I&lt;/code&gt; for its actual type in the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause of &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt;, we get this bound that needs to be checked:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;as&lt;/span&gt; LendingIterator&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; syntax means that we must verify that &lt;em&gt;any&lt;/em&gt; lifetime can be substituted in the right hand side and the trait bound must still pass. A good edge case to check here is &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, since we know that if that check fails the overall bound will definitely fail. So we end up with this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;as&lt;/span&gt; LendingIterator&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or in other words, the associated item type of &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; must implement &lt;code class=&apos;scode&apos;&gt;Debug&lt;/code&gt; when fed the lifetime &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. Let’s hop back to the implementation of &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; for &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; to see if that actually holds. As a quick refresher, the relevant bit of code is here:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sentity sname slabel srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Uhh…that’s a bit complex. Let’s replace the generic types with our concrete ones to simplify it.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;LendingIterator &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And now we can finally see what’s going wrong. As we established earlier, &lt;code class=&apos;scode&apos;&gt;&apos;0&lt;/code&gt; is the local lifetime of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and is therefore definitely a shorter lifetime than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. This means that there is absolutely no way that the bound &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; will hold, making &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;as&lt;/span&gt; LendingIterator&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; an invalid type altogether. So of course the compiler can’t verify that it implements &lt;code class=&apos;scode&apos;&gt;Debug&lt;/code&gt; — it doesn’t even exist at all! This was what the compiler was really trying to tell us earlier, even if it was a bit obtuse about it.&lt;/p&gt;&lt;p&gt;The ultimate conclusion of all this is that HRTBs basically can’t be used with lifetime GATs at all. &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; just doesn’t express the right requirement — we don’t want to require the bound for &lt;em&gt;any&lt;/em&gt; lifetime, we only really want to require it for lifetimes &lt;em&gt;shorter than &lt;code class=&apos;scode&apos;&gt;&apos;0&lt;/code&gt;&lt;/em&gt;. Ideally, we would be able to write in a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause there, so the bounds of &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt; could become:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;print_items&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; where I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This would mean that &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; can’t be selected as the lifetime chosen for the HRTB since &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is &lt;em&gt;definitely not&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, so our above proof-by-contradiction would no longer work and the compiler would accept our correct code without problem.&lt;/p&gt;&lt;p&gt;But unfortunately it doesn’t look like we’ll be getting this feature any time soon. At the time of writing I do not know of any RFC or formal suggestion for this feature (other than &lt;a href=&apos;https://github.com/rust-lang/rust/issues/95268&apos;&gt;one rust-lang/rust issue&lt;/a&gt;) so it’ll be a long time before it actually arrives on stable should we get it at all. Until then, we’re stuck with a hard limitation every time you use lifetime GATs: you can’t place trait bounds on GATs or require them to be a specific type unless the trait implementor is &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This makes real GATs practically unusable for most use cases. I’m still happy they’re being stabilized, but they likely won’t see wide adoption in APIs until this problem is solved.&lt;/p&gt;&lt;p&gt;So, what can we do in the meantime?&lt;/p&gt;&lt;h2 id=&apos;dyn-trait-as-a-hkt&apos;&gt;&lt;a href=&apos;#dyn-trait-as-a-hkt&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Workaround 1: &lt;code class=&apos;scode&apos;&gt;dyn Trait&lt;/code&gt; as a HKT&lt;/h2&gt;&lt;p&gt;As first shared in &lt;a href=&apos;https://gist.github.com/jix/42d0e4a36ace4c618a59f0ba03be5bf5&apos;&gt;this gist&lt;/a&gt; by &lt;a href=&apos;https://github.com/jix&apos;&gt;@jix&lt;/a&gt;, one workaround is to use &lt;code class=&apos;scode&apos;&gt;dyn Trait&lt;/code&gt; as a form of HKT, because &lt;code class=&apos;scode&apos;&gt;dyn Trait&lt;/code&gt; accepts an HRTB in its type, &lt;em&gt;and&lt;/em&gt; supports changing associated types based on the HRTB’s lifetime.&lt;/p&gt;&lt;p&gt;To implement the design in our code, first we modify the &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; trait to look like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;GivesItem&lt;/span&gt;&amp;lt;&amp;#39;a&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Sized&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The magic comes in the implementation of &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; for specific types. For &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; it looks like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;
		&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
		Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt;&lt;/span&gt; WINDOW_SIZE],
	&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, the &lt;code class=&apos;scode&apos;&gt;Item&lt;/code&gt; type is set to a &lt;code class=&apos;scode&apos;&gt;dyn Trait&lt;/code&gt; with an HRTB, where the &lt;code class=&apos;scode&apos;&gt;dyn Trait&lt;/code&gt;’s associated type depends on the input HRTB lifetime. So even though &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is only a single type, it actually acts like a function from a lifetime to a type, just like a real GAT.&lt;/p&gt;&lt;p&gt;We can then modify the signature of &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt; like so:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;print_items&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And lo and behold, it works!&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, this approach runs into some nasty limitations rather quickly. Let’s say that we have now defined a mapping operation on lending iterators:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;map&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I, &lt;span class=&quot;svariable sparameter srust&quot;&gt;mapper&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Map&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	Map &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; mapper &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I,
	&lt;span class=&quot;svariable sother smember srust&quot;&gt;mapper&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; LendingIterator &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;
		&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
		Item = &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Output,
	&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;GivesItem&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.iter.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.mapper&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Trait helper to allow the lifetime of a mapping function&amp;#39;s output to depend
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; on its input. Without this, `map` on an iterator would always force lending
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; iterators to become non-lending which we don&amp;#39;t really want.
&lt;/span&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Mapper&lt;/span&gt;&amp;lt;&amp;#39;a, I&amp;gt;: FnMut(I) -&amp;gt; &amp;lt;Self as Mapper&amp;lt;&amp;#39;a, I&amp;gt;&amp;gt;::Output &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, I, F, O&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;F&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;I&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; O,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; O&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then decide to use a mapped iterator instead of the normal one:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; iter &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;mapper&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; [&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;; 2]&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; input&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; mapped &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; mapper&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta spath srust&quot;&gt;print_items&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Map&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;mapped&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works fine, printing the desired result of &lt;code class=&apos;scode&apos;&gt;1&lt;/code&gt; followed by &lt;code class=&apos;scode&apos;&gt;2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;But if we suddenly decide that the code in &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt; should be inlined, we’re in for a not-so-fun little surprise:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; mapped &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; mapper&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; mapped.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{item:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0308]: mismatched types
  --&amp;gt; src/main.rs:97:35
   |
97 |     while let Some(item) = mapped.next() {
   |                                   ^^^^ one type is more general than the other
   |
   = note: expected associated type `&amp;lt;(dyn for&amp;lt;&apos;this&amp;gt; GivesItem&amp;lt;&apos;this, for&amp;lt;&apos;this&amp;gt; Item = &amp;amp;&apos;this mut [i32; 2]&amp;gt; + &apos;static) as GivesItem&amp;lt;&apos;_&amp;gt;&amp;gt;::Item`
              found associated type `&amp;lt;(dyn for&amp;lt;&apos;this&amp;gt; GivesItem&amp;lt;&apos;this, for&amp;lt;&apos;this&amp;gt; Item = &amp;amp;&apos;this mut [i32; 2]&amp;gt; + &apos;static) as GivesItem&amp;lt;&apos;this&amp;gt;&amp;gt;::Item`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To be honest, I have absolutely no idea what this error message is saying — but I’m pretty sure it’s just nonsense because the generic version works fine.&lt;/p&gt;&lt;p&gt;This isn’t the worst problem in the world — it’s inconvenient but it can probably always be worked around. That said, it is still possible to improve the ergonomics.&lt;/p&gt;&lt;h2 id=&apos;hrtb-supertrait&apos;&gt;&lt;a href=&apos;#hrtb-supertrait&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Workaround 2: HRTB supertrait&lt;/h2&gt;&lt;p&gt;Let’s try a different approach then. We’ll start again from the real GAT version, but this time with explicit lifetimes (you’ll see why in a minute):&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You’ll notice that all items of the trait use the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; lifetime. So we can eliminate the use of GATs by raising that lifetime up one level, to become a generic parameter of the whole trait instead of each item on the trait.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;&amp;lt;&amp;#39;this&amp;gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; This where bound is raised from the GAT
&lt;/span&gt;where
	Self: &amp;#39;this,
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This way, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; becomes an identical trait to the old &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; trait — given a specific lifetime, we get both a &lt;code class=&apos;scode&apos;&gt;next&lt;/code&gt; function and &lt;code class=&apos;scode&apos;&gt;Item&lt;/code&gt; associated type.&lt;/p&gt;&lt;p&gt;However, there are a few problems with a trait declared this way:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is verbose and doesn’t allow eliding the lifetimes.&lt;/li&gt;&lt;li&gt;The trait bound &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is long and inconvenient to spell out.&lt;/li&gt;&lt;li&gt;Some functions like &lt;code class=&apos;scode&apos;&gt;for_each&lt;/code&gt; need &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt; to implement &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; in order for their signature to work. But it’s hard to express that within a trait &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; where the HRTB is not already present.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To solve them we can split the trait into two, moving the parts that can have generic parameters (functions) into an outer lifetime-less subtrait and the parts that can’t have generic parameters (types) into an inner lifetimed supertrait:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&amp;lt;&amp;#39;this&amp;gt;
where
	Self: &amp;#39;this,
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;: for&amp;lt;&amp;#39;this&amp;gt; LendingIteratorLifetime&amp;lt;&amp;#39;this&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can finally get to reimplementing &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;mem&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;take&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get_mut&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;try_into&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s try it out then! Just run &lt;code class=&apos;scode&apos;&gt;cargo build&lt;/code&gt; and…&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0477]: the type `WindowsMut&amp;lt;&apos;a, T, WINDOW_SIZE&amp;gt;` does not fulfill the required lifetime
  --&amp;gt; src/main.rs:41:39
   |
41 | impl&amp;lt;&apos;a, T, const WINDOW_SIZE: usize&amp;gt; LendingIterator
   |                                       ^^^^^^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Right — I should know better than to expect things to work first try at this point.&lt;/p&gt;&lt;p&gt;That error’s extremely unhelpful, but there is actually a legitimate explanation for what’s happening here. Once again putting on our compiler hats, one of our jobs when checking a trait implementation is to check whether the supertraits hold. In this case that means we have to satisfy this trait bound:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Like before, a good edge case to check for with HRTB bounds is whether substituting in &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; holds. In other words, a necessary condition for the above bound to be satisfied is that this bound is also satisfied:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So let’s check that. Jumping to the implementation of &lt;code class=&apos;scode&apos;&gt;LendingIteratorLifetime&lt;/code&gt; for &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt;, we see this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and substituting in &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; for &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;…ah. &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. That’s probably a problem.&lt;/p&gt;&lt;p&gt;Indeed, if we add a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; to the &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; implementation it &lt;em&gt;does&lt;/em&gt; compile:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But that’s definitely not something we want to do — it would mean that &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; would only work on empty slices, global variables and leaked variables.&lt;/p&gt;&lt;p&gt;This is a very similar problem to the one we faced before with the GAT version: ideally, we’d be able to specify a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause within the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bound so that only lifetimes shorter than &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt; could be substituted in, excluding lifetimes like &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; for non-&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt;s. The signature could look something like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;
where
	Self: for&amp;lt;&amp;#39;this where Self: &amp;#39;this&amp;gt; LendingIteratorLifetime&amp;lt;&amp;#39;this&amp;gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But just as before &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clauses in HRTBs unfortunately don’t exist yet, so it looks like this is just another dead end. What a shame.&lt;/p&gt;&lt;h2 id=&apos;hrtb-implicit-bounds&apos;&gt;&lt;a href=&apos;#hrtb-implicit-bounds&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;HRTB implicit bounds&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;Having failed thoroughly in your mission to bring reliable and stable lifetime GATs to the Rust ecosystem, you quit programming altogether out of shame and vow to live out the rest of your days as a lowly potato farmer in the countryside. With nothing but a small amount savings and a dream, you move in to a run-down stone farmhouse in Scotland where you can live onwards peacefully and undisturbed.&lt;/p&gt;&lt;p&gt;Many years pass. You have grown accustomed to nature: you have seen plants grow, wither and die before your eyes more times than smallvec has had CVEs, and the seasons are now no more than a blur — day, night, summer, winter all morphing into one another and passing faster than the blink of an eye. You sleep deeply and peacefully every night, safe and comfortable in the knowledge that you’ll never have to deal with wall of text linker errors ever again. You have become so familiar with the pathways and routes around your home that you can walk them in your sleep. Every single nook and cranny of the place down to the most minute detail is etched deep into your brain: the position of each plant, the location of every nest, the size and shape of each pebble.&lt;/p&gt;&lt;p&gt;So it is no surprise that on one chilly March morning, you immediately notice the abnormal presence of a thin white object sticking out from under a bush. Drawing closer, it appears to be a piece of paper, slightly damp from absorbing the cold morning dew. You pick it up, and as you stare at the mysterious sigils printed on the page, slowly — very slowly — a vague memory begins to come back to you. That’s right, it’s “Rust”. And this “Rust” on the page appears to form a very short program:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;example&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;eprintln!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;{:?}&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; array &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you make your way back to the farmhouse, mysterious piece of paper in hand, you ponder about what it could mean. Of course, there’s no way it would compile, you know &lt;em&gt;that&lt;/em&gt; much: &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; would be able to select &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; as its lifetime, meaning &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt; would need to implement &lt;code class=&apos;scode&apos;&gt;Debug&lt;/code&gt;, which is obviously not true for the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;array&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; shown (as &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;array&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; can’t even exist, let alone be &lt;code class=&apos;scode&apos;&gt;Debug&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;So why would someone go to the effort of printing out code that doesn’t even work — and what’s more, placing it all the way in your farm? It is this that you wonder about while you dig out your old laptop from deep inside storage. It hasn’t been touched for five years, so it’s gotten a little dusty — but you press the power button and screen bursts into colour and life, exactly as it used to do those so many years ago.&lt;/p&gt;&lt;p&gt;Tentatively, you open a text editor, and begin copying out the contents of that paper inside it. Now, how do I build it again? Shipment? Freight? Haul? No, it was something different…ah, cargo, that was it. Into the shell you type out the words you haven’t seen for so, so long:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt;&lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; run&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You take a deep breath, and then press the enter key. The fan whirrs as the CPU starts into life. For a short moment that feels like an eon, Cargo displays “Building” — but eventually it finishes, and as it does, one line of text rolls down the screen:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Wait, what? Do that again.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;You take a deep breath, and then press the enter key. The fan whirrs as the CPU starts into life. For a short moment that feels like an eon, Cargo displays “Building” — but eventually it finishes, and as it does, one line of text rolls down the screen:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;So it wasn’t just a fluke. But that makes no sense at all: by all the rules we knew, there is &lt;em&gt;no way&lt;/em&gt; that code should’ve compiled. So what’s happening here?&lt;/p&gt;&lt;p&gt;The answer is that while &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; does not support explicit &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clauses, it actually can, sometimes, have an &lt;em&gt;implied&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause — in this case, it’s &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. But it only occurs in specific scenarios: in particular, when there is an &lt;em&gt;implicit bound&lt;/em&gt; in the type or trait bound the HRTB is applied to, that implicit bound gets forwarded to the implicit &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause of the HRTB.&lt;/p&gt;&lt;p&gt;An implicit bound is a trait bound that is present, but not stated explicitly by a colon in the generics or &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; clause. As you can infer from the example above, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt; contains an implicit bound for &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; — this is a really simple rule to prevent nonsense types like &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;short_lifetime&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; (a reference that outlives borrowed contents). It’s this rule that causes &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt; to act like it’s actually &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt;, enabling that code to run and successfully print &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Implicit bounds can appear on structs too. For example, take this struct:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt; has an implicit bound of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, the struct &lt;code class=&apos;scode&apos;&gt;Reference&lt;/code&gt; &lt;em&gt;also&lt;/em&gt; has an implicit bound of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. You can prove this because this code compiles:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;example&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; where T: &amp;#39;a &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Reference&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;dbg!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Reference&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; array &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, as soon as you try to upgrade the implicit bound to an explicit one you will notice it no longer compiles:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Reference&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;example&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Reference&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Debug,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;dbg!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Reference&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; array &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;error[E0597]: `array` does not live long enough
  --&amp;gt; src/main.rs:15:13
   |
15 |     example(&amp;amp;array);
   |     --------^^^^^^-
   |     |       |
   |     |       borrowed value does not live long enough
   |     argument requires that `array` is borrowed for `&apos;static`
16 | }
   | - `array` dropped here while still borrowed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Implicit bounds in HRTBs are…a very weird feature of Rust. I’m still not sure whether they are intended to exist or are just an obscure side-effect of the current implementation. But either way, this is an incredibly useful feature for us. If we can somehow leverage this to apply it in our supertrait HRTB of &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt;, then we can maybe get it to actually work without the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bound! Thanks, mysterious piece of paper.&lt;/p&gt;&lt;h2 id=&apos;the-better-gats&apos;&gt;&lt;a href=&apos;#the-better-gats&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Workaround 3: The better GATs&lt;/h2&gt;&lt;p&gt;Armed with our new knowledge of implied bounds, all we have to do is get it to work in conjuction with that &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; supertrait. One way to achieve this is to introduce a new dummy type parameter to &lt;code class=&apos;scode&apos;&gt;LendingIteratorLifetime&lt;/code&gt;, so that HRTBs can make use of it to apply their own implicit bounds:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&amp;lt;&amp;#39;this, ExtraParam&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;
where
	Self: for&amp;lt;&amp;#39;this &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; where Self: &amp;#39;this &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&amp;gt;
		LendingIteratorLifetime&amp;lt;&amp;#39;this, &amp;amp;&amp;#39;this Self&amp;gt;,
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;em&gt;works&lt;/em&gt;, but it’s a pain to have to write out &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; every time you want to use the trait. Ergonomics can be improved slightly by using a default type parameter:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Give every usage of this trait an implicit `where Self: &amp;#39;this` bound
&lt;/span&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&amp;lt;&amp;#39;this, ImplicitBounds = &amp;amp;&amp;#39;this Self&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;
where
	Self: for&amp;lt;&amp;#39;this &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; where Self: &amp;#39;this &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&amp;gt; LendingIteratorLifetime&amp;lt;&amp;#39;this&amp;gt;,
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is still one slight improvement we can make to reduce the chance the API is accidentally misused by setting the &lt;code class=&apos;scode&apos;&gt;ImplicitBounds&lt;/code&gt; parameter to something other than &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, and that is using a sealed type and trait. This leads to my current recommended definition for this trait:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&amp;lt;&amp;#39;this, ImplicitBounds: Sealed = Bounds&amp;lt;&amp;amp;&amp;#39;this Self&amp;gt;&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta smodule srust&quot;&gt;&lt;span class=&quot;sstorage stype smodule srust&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;sentity sname smodule srust&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Sealed&lt;/span&gt;: Sized &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Bounds&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Sealed &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Bounds&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;sealed&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;Bounds&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; Sealed&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIterator&lt;/span&gt;: for&amp;lt;&amp;#39;this&amp;gt; LendingIteratorLifetime&amp;lt;&amp;#39;this&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;New trait in hand, we can rewrite our type &lt;code class=&apos;scode&apos;&gt;WindowsMut&lt;/code&gt; to use it:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, const WINDOW_SIZE&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;WindowsMut&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, T, WINDOW_SIZE&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;mem&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;take&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.first &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.slice.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get_mut&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;WINDOW_SIZE&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;try_into&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;as well as &lt;code class=&apos;scode&apos;&gt;Map&lt;/code&gt; (the &lt;code class=&apos;scode&apos;&gt;Mapper&lt;/code&gt; trait is still needed):&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;
		&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
		&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item,
	&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; LendingIterator &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; LendingIterator,
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Mapper&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.iter.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.mapper&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and unlike both real GATs and &lt;a href=&apos;#dyn-trait-as-a-hkt&apos;&gt;workaround 1&lt;/a&gt;, this works with both consuming the concrete type directly &lt;em&gt;and&lt;/em&gt; through the generic &lt;code class=&apos;scode&apos;&gt;print_items&lt;/code&gt; function. Perfect!&lt;/p&gt;&lt;h2 id=&apos;dyn-safety&apos;&gt;&lt;a href=&apos;#dyn-safety&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Dyn safety&lt;/h2&gt;&lt;p&gt;The main disadvantage of workaround 3 in comparison to workaround 1 is that it is not &lt;code class=&apos;scode&apos;&gt;dyn&lt;/code&gt;-safe. If you try to use it as a trait object, &lt;code class=&apos;scode&apos;&gt;rustc&lt;/code&gt; helpfully tells you this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;note: for a trait to be &amp;quot;object safe&amp;quot; it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit &amp;lt;https://doc.rust-lang.org/reference/items/traits.html#object-safety&amp;gt;
   --&amp;gt; src/main.rs:14:28
    |
14  | pub trait LendingIterator: for&amp;lt;&apos;this&amp;gt; LendingIteratorLifetime&amp;lt;&apos;this&amp;gt; {
    |           ---------------  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |           |
    |           this trait cannot be made into an object...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When it says “because it uses &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt; as a type parameter” it’s actually referring to the hidden &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Bounds&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; default parameter we inserted. As a result, making &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; &lt;em&gt;directly&lt;/em&gt; work with &lt;code class=&apos;scode&apos;&gt;dyn&lt;/code&gt; is simply not possible.&lt;/p&gt;&lt;p&gt;But that is &lt;em&gt;not&lt;/em&gt; to say that dynamic dispatch is altogether impossible — all we have to do is define a helper trait for it! And as long as that helper trait uses workaround 1, it will be perfectly object-safe. This does lead to slightly worse ergnomics when using trait objects (due to that compiler bug with concrete types) but there really isn’t much we can do about that.&lt;/p&gt;&lt;p&gt;So let’s start by bringing back our old definition of &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt;, but this time under the name &lt;code class=&apos;scode&apos;&gt;ErasedLendingIterator&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;LendingIteratorGats&lt;/span&gt;&amp;lt;&amp;#39;a&amp;gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;ErasedLendingIterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Gats&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Sized&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;erased_next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Gats as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, we add a blanket implementation of this trait for all &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt;s:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Sized&lt;/span&gt; + &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;&amp;gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ErasedLendingIterator&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;I&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Gats&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;
		&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;,
		Item = &lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item,
	&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;erased_next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Gats as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we implement the regular &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt; trait on all the trait objects we own:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;, Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIteratorLifetime&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;dyn&lt;/span&gt; &amp;#39;_ + &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ErasedLendingIterator&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	Gats&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Sized + &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;this&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;LendingIterator&lt;/span&gt;
	&lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;dyn&lt;/span&gt; &amp;#39;_ + &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ErasedLendingIterator&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	Gats&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Sized + &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; as &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;erased_next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; omitted implementations for all the permutations of auto traits. in a real
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; implementation, you&amp;#39;d probably use a macro to generate all 32 versions
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; (since there are 5 auto traits)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is fairly standard boilerplate for defining an object-safe version of a non-object-safe trait, so I won’t explain it in great detail here.&lt;/p&gt;&lt;p&gt;Great, let’s try it out! Here, we can use it to create an iterator over either windows of size 2 or windows of size 3.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;unsize&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;const N&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; [&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;; N]&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	array
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Gats&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Erased&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;ErasedLendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Erased&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 3&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; iter.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{item:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and &lt;code class=&apos;scode&apos;&gt;cargo build&lt;/code&gt; it…&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;error&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; implementation of `LendingIteratorLifetime` is not general enough
   &lt;span class=&quot;skeyword soperator srust&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; src&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;/&lt;/span&gt;main.rs&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;166&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;3&lt;/span&gt;
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;166&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;^&lt;/span&gt; implementation of `LendingIteratorLifetime` is not general enough
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; `&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Map&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;WindowsMut&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;, 2_usize&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;smeta sgeneric srust&quot;&gt;for&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;r&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;r&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; [&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;; 2]&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;r&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;unsize&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;2_usize&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;}&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;` must implement `&lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;0&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;`&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt; any lifetime `&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;`&lt;span class=&quot;skeyword soperator srust&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;...&lt;/span&gt;but it actually implements `&lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;1&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;`&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt; some specific lifetime `&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;1&lt;/span&gt;`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;…ah. Another cryptic error.&lt;/p&gt;&lt;p&gt;I believe what’s happening here is the same ergnomics issue as faced with &lt;a href=&apos;#dyn-trait-as-a-hkt&apos;&gt;workaround 1&lt;/a&gt;: There’s some compiler bug which makes this not work with concrete types.&lt;/p&gt;&lt;p&gt;So that means all we have to do to fix it is to move it into a generic function! And indeed this version does compile:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;box_erase&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;, I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Erased&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; + LendingIterator,
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;iter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Erased&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;box_erase&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;box_erase&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 3&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But we can do better than that, because generics are only &lt;em&gt;one&lt;/em&gt; way to erase a value’s concrete type: you can also do it via return-position &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Trait&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;, I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; impl &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;ErasedLendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = Gats&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; LendingIterator&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	iter
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Erased&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 3&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And this also works.&lt;/p&gt;&lt;p&gt;If you want to, you can generalize &lt;code class=&apos;scode&apos;&gt;funnel_opaque&lt;/code&gt; further so that it works with any &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt; type instead of just &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Gats&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorGats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Erased&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; T&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; dyn &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;ErasedLendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Gats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt;, I, T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; impl &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;ErasedLendingIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Gats = &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Gats&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;iter&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; LendingIterator&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
	I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;LendingIteratorLifetime&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, Item = &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	iter
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Erased&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sconstant slanguage srust&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 2&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;funnel_opaque&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;windows_mut&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;, 3&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; array&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; unsize&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But unfortunately you can’t generalize it completely to any &lt;code class=&apos;scode&apos;&gt;LendingIterator&lt;/code&gt;, because you just run into that compiler bug again.&lt;/p&gt;&lt;h2 id=&apos;conclusion&apos;&gt;&lt;a href=&apos;#conclusion&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;So there we have it - this technique is, to my knowledge, the best way to use lifetime GATs in Rust. Even once real GATs become stabilized, I predict it’ll likely still be useful for a long time to come, so you might want to familiarize yourself with it.&lt;/p&gt;</content></entry><entry><title>Async destructors, async genericity and completion futures</title><id>https://sabrinajewson.org/blog/async-drop</id><updated>2022-03-24T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/async-drop" rel="alternate" type="text/html" title="Async destructors, async genericity and completion futures"/><published>2022-03-24T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/async-drop" type="html">&lt;p&gt;The main focus of this article will be on attempting to design a system to support asynchronous destructors in the Rust programming language, figuring the exact semantics of them and resolving any issues encountered along the way. By side effect, it also designs a language feature called “async genericity” which enables supporting blocking and asynchronous code with the same codebase, as well as designing a system for completion-guaranteed futures to be added to the language.&lt;/p&gt;&lt;h2 id=&apos;why-async-destructors&apos;&gt;&lt;a href=&apos;#why-async-destructors&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Why async destructors?&lt;/h2&gt;&lt;p&gt;Async destructors, at a high level, would allow types to run code with &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;s inside it when they are dropped. This enables cleanup code to actually perform I/O, giving much more freedom in the extent to which resources can be properly cleaned up. One notable use case for this is implementing the TLS protocol, in which:&lt;/p&gt;&lt;blockquote&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;Each party MUST send a &amp;quot;close_notify&amp;quot; alert before closing its write
side of the connection, unless it has already sent some error alert.
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;(&lt;a href=&apos;https://datatracker.ietf.org/doc/html/rfc8446#section-6.1&apos;&gt;RFC 8446&lt;/a&gt;). In order to make sure that this requirement is consistently fulfilled, TLS implementations should be able to send this alert when the &lt;code class=&apos;scode&apos;&gt;TlsStream&lt;/code&gt; type is dropped - and if all I/O is done asynchronously, this requires asynchronous destructors.&lt;/p&gt;&lt;p&gt;Currently, this kind of cleanup is generally managed by methods like &lt;a href=&apos;https://docs.rs/tokio/1/tokio/io/trait.AsyncWrite.html#tymethod.poll_shutdown&apos;&gt;&lt;code class=&apos;scode&apos;&gt;poll_shutdown&lt;/code&gt;&lt;/a&gt; and &lt;a href=&apos;https://docs.rs/futures-io/0.3/futures_io/trait.AsyncWrite.html#tymethod.poll_close&apos;&gt;&lt;code class=&apos;scode&apos;&gt;poll_close&lt;/code&gt;&lt;/a&gt;: asynchronous functions that can optionally be called by the user if they want the type to be cleanly disposed of. However, this approach has several limitations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;There is no way to statically guarantee that the method isn’t called twice, that’s up to the user.&lt;/li&gt;&lt;li&gt;There is no way to statically guarantee that the method is called at all - it can be very easy to forget.&lt;/li&gt;&lt;li&gt;Calling it at the lifecycle end of each value is cumbersome boilerplate, and would ideally not be necessary.&lt;/li&gt;&lt;li&gt;It only works on types that actually implement &lt;code class=&apos;scode&apos;&gt;AsyncWrite&lt;/code&gt;. If your type is not actually a byte stream, too bad.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Clearly we need a better solution than this. So let’s look at some practical examples to work out what features we’d need to improve the situation.&lt;/p&gt;&lt;h2 id=&apos;async-drop-after-future-cancellation&apos;&gt;&lt;a href=&apos;#async-drop-after-future-cancellation&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Async drop after future cancellation&lt;/h2&gt;&lt;p&gt;Let’s start simple, with this trivial function:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;wait_then_drop_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta spath srust&quot;&gt;time&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;sleep&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Duration&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_secs&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s an asynchronous function that takes ownership of a &lt;code class=&apos;scode&apos;&gt;TlsStream&lt;/code&gt;, sleeps for 10 seconds, then implicitly drops it at the end. The most obvious characteristic we want of this function is that the TLS stream should perform graceful &lt;code class=&apos;scode&apos;&gt;close_notify&lt;/code&gt; shutdown after the 10 seconds. However there’s also a slightly more subtle but equally important one: because in Rust every future is implicitly made cancellable at &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; points, the same graceful shutdown should also happen if the future is cancelled. For example, suppose the function is used like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; handle &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;wait_then_drop_stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;some_tls_stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;smeta spath srust&quot;&gt;time&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;sleep&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Duration&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_secs&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
handle.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Just because we cancel the task overall doesn’t mean we suddenly want to sidestep the regular graceful shutdown and have the TLS stream finish in an unclean manner - in fact, we almost never want that. So somehow we need a way to register async operations to occur after a future is cancelled, in order to support running the graceful shutdown code in there. How do we do that?&lt;/p&gt;&lt;p&gt;As it turns out, with async destructors in the language that becomes quite easy: since future cancellation is signalled to the future is via calling its destructor, the future can simply itself have an async destructor and run the cleanup code in there. The precise semantics of this would work in a very similar way to how synchronous destruction works today: drop each of the local variables in reverse order (and this critically includes the &lt;code class=&apos;scode&apos;&gt;_stream&lt;/code&gt; variable).&lt;/p&gt;&lt;!--_--&gt;
&lt;h2 id=&apos;hidden-awaits&apos;&gt;&lt;a href=&apos;#hidden-awaits&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Hidden awaits&lt;/h2&gt;&lt;p&gt;A second question we have to answer is what happens when async destruction &lt;em&gt;itself&lt;/em&gt; is cancelled - for example, you might be in the middle of dropping a TLS stream, but at the same time your task suddenly gets aborted. To demonstrate this problem, take a look at this function:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;assign_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; TlsStream, &lt;span class=&quot;svariable sparameter srust&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;target &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; source&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Async destructor is implicitly called!
&lt;/span&gt;	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;1&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;3&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;yield_now&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;4&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It assigns the &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; TLS stream to the &lt;code class=&apos;scode&apos;&gt;target&lt;/code&gt; TLS stream (dropping the old &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; stream in the process), then prints out numbers 1 to 4. Under normal circumstances, this task would just run from top to bottom and always print out every number; but when cancellation gets involved, things become more complicated. If cancellation were to happen during the assignment of &lt;code class=&apos;scode&apos;&gt;source&lt;/code&gt; to &lt;code class=&apos;scode&apos;&gt;target&lt;/code&gt;, the language now has to decide what to do with the rest of the code - should it run it to the end? Should it immediately exit? Should it run only &lt;em&gt;some&lt;/em&gt; of it?&lt;/p&gt;&lt;p&gt;There are three main categories of option worth talking about here: “abort now” designs, “never abort” designs and “delayed abort” designs. Each one has both advantages and drawbacks, which are explored in detail below.&lt;/p&gt;&lt;h3 id=&apos;abort-now&apos;&gt;&lt;a href=&apos;#abort-now&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;“Abort now” designs&lt;/h3&gt;&lt;p&gt;Under these designs, none of the four prints in the code above are guaranteed to run - if the assignment is aborted, it will exit the future as soon as possible while performing the minimum amount of cleanup (i.e. just running destructors and nothing else).&lt;/p&gt;&lt;p&gt;There are three variants of this design, differing slightly in when they require &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; to be specified:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Sometimes await: Under this design, &lt;code class=&apos;scode&apos;&gt;=&lt;/code&gt; is kept to never require an &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; and async function calls are kept to always require an &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;. This mostly keeps things the same way as they are: no special new syntax is introduced, and no major breaking changes are made.&lt;/p&gt;&lt;p&gt;To get a feel for how this looks, here is a non-trivial “real world” async function implemented using it:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;handle_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_message&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Redirect&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				stream &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; The below line isn&amp;#39;t guaranteed to run even if
&lt;/span&gt;				&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; redirection succeded, since the future could be
&lt;/span&gt;				&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; cancelled during the drop of the old `TlsStream`.
&lt;/span&gt;				&lt;span class=&quot;smeta spath srust&quot;&gt;log&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;info&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Redirected&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Exit &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It does introduce a footgun as it will no longer be obvious at which points control flow can exit a function. It can also be considered inconsistent as some suspend points require an &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; while others don’t, despite the fact that there is no meaningful semantic difference between the two kinds.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Never await: To resolve that inconsistency, this design removes &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;s altogether, making all cancellation points completely invisible. Adapting our example from before, it would look like:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;handle_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_message&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Redirect&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				stream &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;smeta spath srust&quot;&gt;log&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;info&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Redirected&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Exit &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Aside from the technical issues of removing &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; (is it done recursively? does it make implementing &lt;code class=&apos;scode&apos;&gt;Future&lt;/code&gt; a breaking change? are async blocks made redundant? et cetera) and the backwards compatibility/churn issue, this has the same footgun issue as the previous option but turned up to the extreme - it would now be basically impossible to carefully manage where cancellations can occur and most users would end up having to treat cancellation more as a &lt;code class=&apos;scode&apos;&gt;pthread_kill&lt;/code&gt; than a helpful control flow construct.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Always await: On the flip side, this design makes &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;s mandatory everywhere. Assignments to a value with an asynchronous destructor must be done with a new &lt;code class=&apos;scode&apos;&gt;=.await&lt;/code&gt; operator instead of plain &lt;code class=&apos;scode&apos;&gt;=&lt;/code&gt;, and values cannot implicitly fall out of scope but must instead be explicitly &lt;code class=&apos;scode&apos;&gt;drop&lt;/code&gt;ped by the user. Once again returning to the &lt;code class=&apos;scode&apos;&gt;handle_stream&lt;/code&gt; example:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;handle_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Result&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;read_message&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Redirect&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				stream &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt;.await &lt;span class=&quot;ssupport sfunction srust&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;address&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;skeyword soperator srust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;smeta spath srust&quot;&gt;log&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;info&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Redirected&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;smeta spath srust&quot;&gt;Message&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Exit &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;skeyword scontrol srust&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is the only option of the three to definitively avoid the “implicit cancel” footgun, but it’s still not ideal as it ends up introducing new weird-looking syntax and makes writing async code pretty verbose.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;All three of these variants end up with pretty significant drawbacks - fundamentally, it’s pretty incompatible with the current async syntax and model. So if aborting is so tricky to support, what if we could sidestep the problem by avoiding it altogether?&lt;/p&gt;&lt;h3 id=&apos;never-abort&apos;&gt;&lt;a href=&apos;#never-abort&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;“Never abort” designs&lt;/h3&gt;&lt;p&gt;This design category eliminates implicit cancellation entirely from the language. Futures would, much like synchronous functions, run from linearly top to bottom without the possibility of caller-induced early exit (of course, panics can still cause early exit to happen). This means that all of &lt;code class=&apos;scode&apos;&gt;1&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;2&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;3&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;4&lt;/code&gt; are guaranteed to be printed in the &lt;code class=&apos;scode&apos;&gt;assign_stream&lt;/code&gt; function shown at the start of this section, since at no point is code execution ever allowed to stop. &lt;a href=&apos;https://carllerche.netlify.app/2021/06/17/six-ways-to-make-async-rust-easier/&apos;&gt;This approach has been proposed by Carl Lerche previously&lt;/a&gt;, if you want to read more about it.&lt;/p&gt;&lt;p&gt;Much like the “abort now” category, it has three sub-designs, “always await”, “sometimes await” and “never await” depending on where &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; is deemed to be necessary. Much of the same arguments listed up there apply, although there is no longer the issue of the footgun caused by potential cancellation points being implicit so it is mostly a question of weighing up consistency, breakage and new syntax.&lt;/p&gt;&lt;p&gt;This is another highly consistent approach, however it comes with the major downside of throwing away the very useful tool that is implicit cancellation contexts. While it is definitely possible for cancellation to be implemented as a library feature (see &lt;a href=&apos;https://docs.rs/tokio-util/0.7/tokio_util/sync/struct.CancellationToken.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;CancellationToken&lt;/code&gt;&lt;/a&gt; and &lt;a href=&apos;https://docs.rs/stop-token/0.7/stop_token/struct.StopToken.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;StopToken&lt;/code&gt;&lt;/a&gt;) and I want that to be an option for use cases that need it, most of the time having an implicit context is far more useful since it is less verbose and requires much less boilerplate to make use of. I would hate to see otherwise infallible functions become fallible, or an enormous migration effort to add cancellation token parameters to every function.&lt;/p&gt;&lt;p&gt;One argument Carl Lerche used to support his point was an example code snippet in which future cancellation combined with &lt;code class=&apos;scode&apos;&gt;select!&lt;/code&gt; turned out to be a footgun. But as Yoshua Wuyts argued in &lt;a href=&apos;https://blog.yoshuawuyts.com/futures-concurrency-3/&apos;&gt;Futures Concurrency III&lt;/a&gt;, the primary problem in code like that is the confusing semantics of &lt;code class=&apos;scode&apos;&gt;select!&lt;/code&gt; and not the cancellation behaviour of futures. Ultimately, I do not believe cancellation to be problematic enough to warrant removing it from the language. Although this approach’s consistency and its parallel with blocking code is nice, cancellation is still useful and there are ways to combine it with async destructors that don’t introduce footguns.&lt;/p&gt;&lt;p&gt;Note that even with the other options, adding async destructors to the language would make it trivial to create a combinator that executes futures in a “no-cancellation” mode if such semantics are desired - see &lt;a href=&apos;#uncancellable-futures&apos;&gt;appendix D&lt;/a&gt; for more.&lt;/p&gt;&lt;h3 id=&apos;delayed-abort&apos;&gt;&lt;a href=&apos;#delayed-abort&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;“Delayed abort” designs&lt;/h3&gt;&lt;p&gt;Unlike the previous two designs, these approaches try to fully embrace the syntactical difference between assigning and falling out of scope, which don’t require an &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;, and calling an async function, which does. When the caller attempts to cancel the future during one of the former operations, the future will actually continue to run for a short while afterwards until it is able to reach one of the latter operations and properly exit.&lt;/p&gt;&lt;p&gt;This immediately solves the main set of problems that plagued the “abort now” designs without going to the extreme that never-abort did: there is no footgun as cancellation points are never implicitly introduced, no new syntax is added and no major breaking changes are made, and there is now a definite reason &lt;em&gt;why&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;=&lt;/code&gt; doesn’t need &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; but calling functions does.&lt;/p&gt;&lt;p&gt;However, it is not perfect. It effectively introduces two different kinds of suspend point which behave pretty differently, an inconsistency not present with “abort now” and “never abort” designs. Additionally, it means that if you call a wrapper function around the &lt;code class=&apos;scode&apos;&gt;=&lt;/code&gt; operator or call &lt;code class=&apos;scode&apos;&gt;drop&lt;/code&gt; manually, it has subtly different semantics from using the built-in language behaviour since it changes what kind of suspend point it is. This is probably unexpected and unintuitive for most users.&lt;/p&gt;&lt;p&gt;There are three variations of this design, depending on when the code stops running:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Abort before first await: Code will continue to run after cancellation of an operation like &lt;code class=&apos;scode&apos;&gt;=&lt;/code&gt; until the next point at which &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; occurs, at which point the outer future will promptly exit without even polling the inner future once. In the &lt;code class=&apos;scode&apos;&gt;assign_stream&lt;/code&gt; example, that means that &lt;code class=&apos;scode&apos;&gt;1&lt;/code&gt; is guaranteed to be printed, but everything after that isn’t.&lt;/li&gt;&lt;li&gt;Abort after first await: As with the previous one, but the future will be polled once (only to have its result discarded and the outer future to exit). In our example, that means &lt;code class=&apos;scode&apos;&gt;1&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;2&lt;/code&gt; are guranteed to be printed, but not anything beyond that.&lt;/li&gt;&lt;li&gt;Abort at first suspend: The outer future will abort the first time a future which it &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;s returns &lt;code class=&apos;scode&apos;&gt;Poll::Pending&lt;/code&gt; when it is polled. In the example code, this will force all of &lt;code class=&apos;scode&apos;&gt;1&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;2&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;3&lt;/code&gt; to be printed, but not &lt;code class=&apos;scode&apos;&gt;4&lt;/code&gt; since &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;yield_now&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; causes a suspend point to occur. This is the most similar to how future cancellation works today, because cancellation cannot currently appear to happen without a suspend point (it still can’t with the above proposals, but it appears to because &lt;code class=&apos;scode&apos;&gt;async {}.await&lt;/code&gt; potentially exits control flow). From the future’s perspective, this behaves is exactly as if the caller had just waited and then attempted cancellation later on.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Although they might seem very similar, with the first two approaches an extremely subtle but very important paradigm shift is made: &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; changes its meaning from being a “might suspend” operator to a “might halt” or “might abort” operator, since &lt;code class=&apos;scode&apos;&gt;async {}.await;&lt;/code&gt; is now able to cause computation to suddenly stop. This is a small difference, but ends up very problematic as we now have to answer a whole host of new questions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; is just about cancellation, should we allow omitting it to call async functions while forbidding cancellation?&lt;/li&gt;&lt;li&gt;Should we allow calling &lt;em&gt;synchronous&lt;/em&gt; functions with &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; to introduce cancellation points around them?&lt;/li&gt;&lt;li&gt;Should we introduce plain &lt;code class=&apos;scode&apos;&gt;await;&lt;/code&gt; statements to introduce those cancellation points, equivalent to &lt;code class=&apos;scode&apos;&gt;async {}.await;&lt;/code&gt;?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Phrased another way, we open ourselves up to this table existing whose empty boxes will come across as obvious holes:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Caller can’t cancel&lt;/th&gt;&lt;th&gt;Caller can cancel&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Callee can’t cancel&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;code class=&apos;scode&apos;&gt;foo()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Callee can cancel&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;?&lt;/td&gt;&lt;td&gt;&lt;code class=&apos;scode&apos;&gt;foo().await&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;I don’t think that’s a situation we want to be in. The third approach avoids the whole situation altogether by tying abort opportunities to suspend points, removing the need for the second column in that table and thus closing those holes.&lt;/p&gt;&lt;p&gt;Additionally, the third variant is less of a breaking change because code that previously relied on the immediately-completing parts of an &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; operation not being able to abort won’t have to adjust their expectations. Technically it’s still non-breaking either way because no existing code uses asynchronous destructors, but it allows programmers to keep their mental model which is important too.&lt;/p&gt;&lt;p&gt;Because of all these reasons, I am in favour using a delayed abort design with abort-at-first-suspend: it would require little migration effort, avoids footguns and I don’t think is too surprising for users. The rest of this post will be written assuming that design is chosen.&lt;/p&gt;&lt;h2 id=&apos;async-drop-in-a-sync-function&apos;&gt;&lt;a href=&apos;#async-drop-in-a-sync-function&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Async drop in a sync function&lt;/h2&gt;&lt;p&gt;Perhaps the hardest problem any async drop design has to face is what happens when a type with an async destructor gets dropped in a synchronous context. Consider this code:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;sync_drop_stream&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The synchronous function declared takes a TLS stream as a parameter. It must do something with the stream it has been given since it has ownership and there’s no return value to pass it back to the caller, but it can’t use a regular asynchronous drop because it is a synchronous function. So what can it do? In &lt;a href=&apos;https://without.boats/blog/poll-drop/#the-non-async-drop-problem&apos;&gt;withoutboats’ post on this subject&lt;/a&gt; they hypothesized two options:&lt;/p&gt;&lt;blockquote&gt;&lt;ol&gt;&lt;li&gt;Call it’s non-async destructor, like every other type.&lt;/li&gt;&lt;li&gt;Introduce some kind of executor to the runtime (probably just &lt;code class=&apos;scode&apos;&gt;block_on&lt;/code&gt;) to call as part of the drop glue.&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;p&gt;To me, both solutions seem pretty bad. Solution 2 is obviously unworkable for the reasons Boats’ outlined, but I believe solution 1 is far more of a footgun than it appears. Many many functions from the standard library become essentially off-limits, so not only do you not get their ergonomics in well-written code it would be very easy to create bug-ridden code too, simply by calling any function like &lt;a href=&apos;https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.insert&apos;&gt;&lt;code class=&apos;scode&apos;&gt;Option::insert&lt;/code&gt;&lt;/a&gt; on a TLS stream.&lt;/p&gt;&lt;p&gt;My alternative solution is to forbid that code from compiling entirely. For a type to be dropped in a synchronous context it must implement a certain trait, and this just wouldn’t be implemented for &lt;code class=&apos;scode&apos;&gt;TlsStream&lt;/code&gt; and similar types. Therefore, barring using of an explicit &lt;code class=&apos;scode&apos;&gt;close_unclean&lt;/code&gt; method on &lt;code class=&apos;scode&apos;&gt;TlsStream&lt;/code&gt;, it becomes totally impossible to cause an unclean TLS close from anywhere, eliminating an entire category of bugs.&lt;/p&gt;&lt;p&gt;This approach is not without its difficulties - in fact, it has more of them than the others and lots of this article will be simply dedicated to figuring them out. But ultimately, I do believe it to a better solution for the sake of those stronger static guarantees.&lt;/p&gt;&lt;h2 id=&apos;panic-checks&apos;&gt;&lt;a href=&apos;#panic-checks&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Panic checks&lt;/h2&gt;&lt;p&gt;I mentioned that this design would forbid at compile time async drop types being dropped in a synchronous context. So, seems easy right? Just detect when the compiler would run the destructor for each value and error out if it’s invalid.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Error
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;bad&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; stream.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;protocol_version&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Implicitly dropped here: error!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; OK
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;good&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; TlsStream&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; stream.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;protocol_version&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	stream
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Except…it’s not so simple. Because at nearly every point in a program, it is possible for the thread to panic, and if that happens unwinding might start to occur and if &lt;em&gt;that&lt;/em&gt; happens you need to drop all the local variables in scope but you can only do that if they have a synchronous destructor! So really the compiler ought to forbid &lt;em&gt;any&lt;/em&gt; usage of values with an asynchronous destructor in a synchronous context since panics can always happen and mess things up.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Error
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;bad&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; TlsStream&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; stream &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But that doesn’t work either. The usage of types with an asynchronous destructor in a synchronous context is absolutely necessary in many circumstances, for example &lt;code class=&apos;scode&apos;&gt;TlsStream::close_unclean&lt;/code&gt; which takes &lt;code class=&apos;scode&apos;&gt;self&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;block_on&lt;/code&gt; which takes a future. What the compiler actually needs to enforce is then slightly more relaxed: While a value that cannot be synchronously dropped is held in scope, no operations that might panic can occur. “Operations that might panic” here includes calling any function or triggering any operator overload. It only doesn’t include simple things like constructing a struct or tuple, accessing a type’s field (without overloaded &lt;code class=&apos;scode&apos;&gt;Deref&lt;/code&gt;), matching, returning, or any other built-in and trivial operation.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Error
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;bad&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; TlsStream&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{:?}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; stream.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;protocol_version&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	stream
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; OK
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;good&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; TlsStream&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; stream &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This rule is quite limited, but actually provides all the tools necessary for dealing with this situation. It is particularly effective when combined with &lt;code class=&apos;scode&apos;&gt;ManuallyDrop&lt;/code&gt;: because &lt;code class=&apos;scode&apos;&gt;ManuallyDrop&lt;/code&gt; skips running the destructor of a type, it is always able to be synchronously dropped even if the type inside isn’t. So as long as the first might-panic operation you do upon obtaining one of these values is calling &lt;code class=&apos;scode&apos;&gt;ManuallyDrop::new&lt;/code&gt; on it, the compiler will allow you to do anything you like since the burden has effectively been shifted to &lt;em&gt;you&lt;/em&gt; to drop the value if you want. What’s more, &lt;code class=&apos;scode&apos;&gt;ManuallyDrop::new&lt;/code&gt; itself doesn’t have to be implemented with any compiler magic - since all it does is execute a struct expression and return it, it passes the panic check just fine.&lt;/p&gt;&lt;h2 id=&apos;unwinding-in-async&apos;&gt;&lt;a href=&apos;#unwinding-in-async&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Unwinding in async&lt;/h2&gt;&lt;p&gt;Now that we’ve looked at what unwinding looks like in a synchronous context, let’s see what it looks like in an asynchronous one. It should be easier because this time we’re actually allowed to await on each value’s destruction.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;unwinds&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_stream&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;panic!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sticking with the principle of forbidding ungraceful TLS stream shutdown entirely, it makes sense for the future to catch this panic and then asynchronously drop everything in scope like it usually would, before eventually propagating the panic to the caller.&lt;/p&gt;&lt;p&gt;For parity with synchronous code, while performing these asynchronous drops &lt;a href=&apos;https://doc.rust-lang.org/stable/std/thread/fn.panicking.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;std::thread::panicking&lt;/code&gt;&lt;/a&gt; would return &lt;code class=&apos;scode&apos;&gt;true&lt;/code&gt; and similarly panicking again would result in an abort. Actually storing the in-flight panic in the future is easy: simply store an optional pointer that is the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Box&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;dyn Any &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; Send&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; returned by &lt;code class=&apos;scode&apos;&gt;catch_unwind&lt;/code&gt;, ready to be passed to &lt;code class=&apos;scode&apos;&gt;resume_unwind&lt;/code&gt; later.&lt;/p&gt;&lt;p&gt;Unfortunately, those functions &lt;a href=&apos;https://github.com/rust-lang/rfcs/issues/2810&apos;&gt;aren’t available in &lt;code class=&apos;scode&apos;&gt;no_std&lt;/code&gt; environments yet&lt;/a&gt; so for now the compiler will probably have to use a workaround like aborting or leaking the values - or maybe implementing async destructors could be forbidden entirely on &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;no_std&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. If that issue is ever resolved it would be possible to improve the handling to something more useful.&lt;/p&gt;&lt;p&gt;There is one big issue with this approach however, and that is unwind safety. Unwind safety is the idea that panics in code can cause shared data structures to enter a logically invalid state, so whenever you are given the opportunity to observe the world after a panic it should be checked that you know that that might happen. This is regulated by two traits, &lt;a href=&apos;https://doc.rust-lang.org/stable/std/panic/trait.UnwindSafe.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;UnwindSafe&lt;/code&gt;&lt;/a&gt; and &lt;a href=&apos;https://doc.rust-lang.org/stable/std/panic/trait.RefUnwindSafe.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;RefUnwindSafe&lt;/code&gt;&lt;/a&gt;, which provide the necessary infrastructure to check all of this at compile time.&lt;/p&gt;&lt;p&gt;Implemented simply, this proposal would trivially break that concept:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;derive&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;Clone&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; Copy&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; PartialEq&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; Eq&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; Valid&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; Invalid &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; state &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Cell&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;State&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Valid&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; task &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;pin!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; stream &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; some_tls_stream&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	state.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;State&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Invalid&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport smacro srust&quot;&gt;panic!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	state.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;State&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Valid&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; task.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;poll&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; cx&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Now the task is panicking and polling the TLS stream...
&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; But we can observe the invalid state!
&lt;/span&gt;&lt;span class=&quot;ssupport smacro srust&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;state.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;State&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Invalid&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So what do we do? Well, we have a few options:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Require that all local variables in async contexts are &lt;code class=&apos;scode&apos;&gt;UnwindSafe&lt;/code&gt;. This would prevent the above code from compiling because &lt;code class=&apos;scode&apos;&gt;&amp;amp;Cell&amp;lt;T&amp;gt;&lt;/code&gt; is &lt;code class=&apos;scode&apos;&gt;!UnwindSafe&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Have compiler-generated &lt;code class=&apos;scode&apos;&gt;async {}&lt;/code&gt; types only implement &lt;code class=&apos;scode&apos;&gt;Future&lt;/code&gt; when &lt;code class=&apos;scode&apos;&gt;Self: UnwindSafe&lt;/code&gt;. This is mostly the same as the first option, it just causes an error later in compilation.&lt;/li&gt;&lt;li&gt;Ignore unwind safety entirely - it’s already kind of useless because &lt;code class=&apos;scode&apos;&gt;std::thread::spawn&lt;/code&gt; doesn’t require &lt;code class=&apos;scode&apos;&gt;F: UnwindSafe&lt;/code&gt; and that can already be used to witness broken invariants. The system as a whole is definitely one of the more confusing and less understood parts of &lt;code class=&apos;scode&apos;&gt;std&lt;/code&gt;, and it usually just amounts to slapping &lt;code class=&apos;scode&apos;&gt;AssertUnwindSafe&lt;/code&gt; on everything until rustc is happy while not actually considering the implications.&lt;/li&gt;&lt;li&gt;Have async panics always cause synchronous drops of locals. This would force a sync drop option on types where it might not even make logical sense to have one, and async panic handling would permanently be done suboptimally.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Personally, I’m quite in favour of option 3 - ignoring unwind safety entirely. I can’t think of a time where it has actually been useful for me or prevented a bug, but of course your mileage may vary (&lt;a href=&apos;https://github.com/rust-lang/chalk/issues/260&apos;&gt;I know &lt;code class=&apos;scode&apos;&gt;rust-analyzer&lt;/code&gt; has been saved by unwind safety at least once&lt;/a&gt;). I’m also open to option 1, although it could end up being quite a pain.&lt;/p&gt;&lt;h2 id=&apos;poll-drop-ready&apos;&gt;&lt;a href=&apos;#poll-drop-ready&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;&lt;code class=&apos;scode&apos;&gt;poll_drop_ready&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;In the now-closed &lt;a href=&apos;https://github.com/rust-lang/rfcs/pull/2958&apos;&gt;RFC 2958&lt;/a&gt;, withoutboats proposed the following design for implementing asynchronous destructors:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Drop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;poll_drop_ready&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;cx&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Context&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Poll&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta spath srust&quot;&gt;Poll&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Ready&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Under this design, dropping a type would be a simple matter of forwarding to &lt;code class=&apos;scode&apos;&gt;poll_drop_ready&lt;/code&gt; inside the future’s &lt;code class=&apos;scode&apos;&gt;poll&lt;/code&gt; function until it returns &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Poll&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Ready&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and execution can continue. Types would need to hold all state they need to use for destruction inside the type itself.&lt;/p&gt;&lt;p&gt;But this design comes with one &lt;em&gt;major&lt;/em&gt; drawback that I haven’t seen mentioned so far: it breaks &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt;’s three-pointer layout guarantee. The problem is that &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt;, when destroyed, needs to drop each of its elements in order. So with an approach like &lt;code class=&apos;scode&apos;&gt;poll_drop_ready&lt;/code&gt;, it would need to keep track of how many elements it has destroyed so far within the &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt; itself, since it isn’t allowed to introduce any new external state during destruction. It can’t use any existing fields to do this - &lt;code class=&apos;scode&apos;&gt;ptr&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;len&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;capacity&lt;/code&gt; are all necessary to keep around - therefore the only other option is adding a new field, but &lt;a href=&apos;https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#guarantees&apos;&gt;Rust already guarantees&lt;/a&gt; that &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt; will never do that.&lt;/p&gt;&lt;p&gt;It’s not like there aren’t potential solutions to this, like hardcoding &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt;’s async drop code into the language or only making it four &lt;code class=&apos;scode&apos;&gt;usize&lt;/code&gt;s for async-drop types. But both of those are a hack, and to me appear to just be working around a more fundamental problem with the design.&lt;/p&gt;&lt;p&gt;So how do we avoid this? Well, we have to allow types to hold state - &lt;em&gt;new&lt;/em&gt; state - in their asynchronous destructors. Such a design was &lt;a href=&apos;https://without.boats/blog/poll-drop/#the-destructor-state-problem&apos;&gt;rejected by withoutboats&lt;/a&gt; for two reasons:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The resulting future can be unexpectedly &lt;code class=&apos;scode&apos;&gt;!Send&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;It doesn’t play well with trait objects.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I don’t believe the first problem to be particularly bad, as if a type’s asynchronous destructor ends up being &lt;code class=&apos;scode&apos;&gt;!Send&lt;/code&gt; that simply forms part of the type’s public API, similarly to how the type itself being &lt;code class=&apos;scode&apos;&gt;Send&lt;/code&gt; is. And in generic contexts, since &lt;code class=&apos;scode&apos;&gt;Send&lt;/code&gt; implementations leak all over the place anyway the &lt;code class=&apos;scode&apos;&gt;Send&lt;/code&gt;ness of destructors can too: it would be up to the user to provide a type with a &lt;code class=&apos;scode&apos;&gt;Send&lt;/code&gt; destructor if they want the resulting future to be &lt;code class=&apos;scode&apos;&gt;Send&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Trait objects definitely pose a larger challenge - since the new state is of variable size, it’s not possible to stack-allocate it anywhere like we usually would with non-type-erased types. But this isn’t a problem that needs to be immediately solved: it’s possible to just forbid &lt;code class=&apos;scode&apos;&gt;dyn&lt;/code&gt; trait objects with asynchronous destructors for now, and potentially fill in this gap later. Since users can always create user-space workarounds for this feature, it’s not urgent to attempt to stabilize a solution immediately. Additionally because it’s a problem shared with all async traits, not just async destructors, if a general solution is found for those it would end up working for this too.&lt;/p&gt;&lt;h2 id=&apos;function-implicit-bounds&apos;&gt;&lt;a href=&apos;#function-implicit-bounds&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Function implicit bounds&lt;/h2&gt;&lt;p&gt;Now we need to begin to consider how async drop works in generic code. In particular, when will a generic parameter enforce that a type does or does not support synchronous drop?&lt;/p&gt;&lt;p&gt;Within the current edition, it is essential that backward compatibility is maintained. Therefore, we can’t suddenly force &lt;code class=&apos;scode&apos;&gt;T: ?Drop&lt;/code&gt; on any existing function or implementation, synchronous or asynchronous since they could very well be relying on synchronous drop support. If asynchronous drop is to be supported at all by an API, they must have to explicitly opt in to it (&lt;a href=&apos;#relaxed-drop-bounds&apos;&gt;more on this later&lt;/a&gt;). All generic parameters and associated types without that opt-in would default to requiring a synchronous drop in every context.&lt;/p&gt;&lt;p&gt;To illustrate how this would work, here is an implementation of &lt;code class=&apos;scode&apos;&gt;FromIterator&lt;/code&gt; for &lt;code class=&apos;scode&apos;&gt;Option&lt;/code&gt; annotated with the implicit bounds:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, V&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;FromIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;V&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; A: Drop,
&lt;/span&gt;	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; V: Drop,
&lt;/span&gt;	V&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;FromIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_iter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;I&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; I&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		I&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;IntoIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Item = &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; I: Drop,
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; No `I::IntoIter: Drop` bound is implied here since
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; that&amp;#39;s provided by the IntoIterator trait already.
&lt;/span&gt;	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		iter.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;into_iter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;_&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;item&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As a side note, I’m using &lt;code class=&apos;scode&apos;&gt;T: Drop&lt;/code&gt; syntax to mean “supports synchronous drop”. Unfortunately, that is counterintuitively &lt;em&gt;not&lt;/em&gt; what &lt;code class=&apos;scode&apos;&gt;T: Drop&lt;/code&gt; currently means, nor does it mean “the type &lt;a href=&apos;https://doc.rust-lang.org/stable/std/mem/fn.needs_drop.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;needs_drop&lt;/code&gt;&lt;/a&gt;”; instead, it is satisfied only if there a literal &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; block for the type, making the bound entirely useless in any actual code. But let’s ignore that and assume the more sensible meaning for now.&lt;/p&gt;&lt;p&gt;We get a lot more freedom when considering the next edition, and we can start relaxing the defaults of those bounds to something more commonly useful. As long as the standard library provides an adequate set of utilities for dealing with async drop types migrating should be painless.&lt;/p&gt;&lt;p&gt;Let’s look at a few simple examples to try and work out what these defaults should actually be.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;sync_drops_a_value&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;sync_takes_a_ref&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;sync_drops_a_clone&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Clone&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; v.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;async_drops_a_value&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code class=&apos;scode&apos;&gt;sync_drops_a_value&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;sync_drops_a_clone&lt;/code&gt; should probably compile as-is and not work with async drop types. Similarly, &lt;code class=&apos;scode&apos;&gt;async_drops_a_value&lt;/code&gt; should obviously work with async drop types, because of course async destructors would be supported in an asynchronous context. At first glance it looks like &lt;code class=&apos;scode&apos;&gt;sync_takes_a_ref&lt;/code&gt; can follow suit - after all, it’s not trying to drop anything - but in practicality it can’t, because the compiler shouldn’t have to look into its function body to determine whether it actually does something like &lt;code class=&apos;scode&apos;&gt;sync_drops_a_clone&lt;/code&gt; does or not. While that situation is unfortunate, it is not all bad because as it turns out the extra restriction does not matter in most cases, since users can often add an extra reference to the type to bridge the gap.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;takes_a_ref&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; implied to require not-async-drop &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; stream&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; TlsStream &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;takes_a_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; doesn&amp;#39;t work, since TlsStream is async-drop
&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;takes_a_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;stream&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; does work, since &amp;amp;TlsStream is not async-drop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Normally, a double reference functions totally equivalently to a single one, so this shouldn’t be a too big problem. And as older APIs gradually migrate to new syntax it becomes less and less of one.&lt;/p&gt;&lt;p&gt;So past the next edition all synchronous functions would implicitly bound each generic parameter by &lt;code class=&apos;scode&apos;&gt;T: Drop&lt;/code&gt; and all asynchronous functions would use the async equivalent. While this doesn’t cover the desired behaviour 100% of the time, it covers the majority of cases and that’s all that’s needed for a default - explicit bounds can be used whereever necessary.&lt;/p&gt;&lt;p&gt;Inherent functions follow much the same idea. Consider this example:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;some_sync_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;ref_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;some_async_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With all the implicit bounds made explicit, it would look like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;some_sync_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Drop &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;ref_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Drop &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;some_async_method&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; AsyncDrop &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is one small addition though: because of the frequency of wanting to define several synchronous methods that don’t care about drop, one can specify relaxed bounds on the &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; block itself and have it apply to every function inside of it. This would be useful for defining many of the &lt;code class=&apos;scode&apos;&gt;Option&lt;/code&gt; methods:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt;&amp;gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;is_some&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;bool&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;is_none&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;bool&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;as_ref&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;as_mut&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; et cetera
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The choices of the exact syntax for this is discussed more later.&lt;/p&gt;&lt;h2 id=&apos;drop-supertrait&apos;&gt;&lt;a href=&apos;#drop-supertrait&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Drop supertrait&lt;/h2&gt;&lt;p&gt;The following code compiles today:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;consumes_self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If any declared trait didn’t imply &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; as a supertrait, then we would have a breaking change as there would no longer be a guarantee that &lt;code class=&apos;scode&apos;&gt;self&lt;/code&gt; can be dropped like that. Ultimately, I would like to follow in the path of &lt;code class=&apos;scode&apos;&gt;Sized&lt;/code&gt; and have &lt;code class=&apos;scode&apos;&gt;Foo: Drop&lt;/code&gt; &lt;em&gt;never&lt;/em&gt; implied so that the above code would need an explicit &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Drop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bound, but until then that code must desugar like so:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Foo&lt;/span&gt;: Drop &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;consumes_self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And everything can compile again.&lt;/p&gt;&lt;p&gt;It’s also possible that we could introduce some more complex rules about this in the current edition, like “the supertrait is only implied if there are any default methods”; but they would only help in a small number of cases and it would be easier to just convince users to use the next edition.&lt;/p&gt;&lt;h2 id=&apos;async-genericity&apos;&gt;&lt;a href=&apos;#async-genericity&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Async genericity&lt;/h2&gt;&lt;p&gt;With the current suggestions taken alone, although async drop will be supported it would be rather inconvenient since almost no existing standard library APIs would support it. Just to show how difficult it would be to use, here are some functions that wouldn’t work with async drop types:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Option::insert&lt;/code&gt;, since it can drop the old value in the &lt;code class=&apos;scode&apos;&gt;Option&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Many &lt;code class=&apos;scode&apos;&gt;HashMap&lt;/code&gt; functions: &lt;code class=&apos;scode&apos;&gt;insert&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;entry&lt;/code&gt;, etc since they call methods of user-supplied generics which can always panic.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Vec::push&lt;/code&gt;, since it’s synchronous and can panic if the &lt;code class=&apos;scode&apos;&gt;Vec&lt;/code&gt;’s length exceeds &lt;code class=&apos;scode&apos;&gt;isize::MAX&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Box::new&lt;/code&gt;, since it’s possible that allocation will be allowed to panic.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;One potential option is to introduce &lt;code class=&apos;scode&apos;&gt;_async&lt;/code&gt; variants of each of these functions that are &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s. When dealing with async-drop types, you’d call &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; vec.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;push_async&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; instead of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; vec.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new_async&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;/span&gt;&lt;/code&gt; instead of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. However this would nearly double the API surface of the standard library and lead to a large amount of code duplication. This is obviously undesirable, so what can we do about it?&lt;/p&gt;&lt;p&gt;One potential path forward is a feature known as async overloading, &lt;a href=&apos;https://blog.yoshuawuyts.com/async-overloading/&apos;&gt;previously proposed by Yoshua Wuyts&lt;/a&gt;. The idea is that synchronous functions can be overloaded by asynchronous ones, allowing &lt;code class=&apos;scode&apos;&gt;Vec::push_async&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Vec::push&lt;/code&gt; to effectively share the same namespace, and have the correct function be chosen based on context.&lt;/p&gt;&lt;p&gt;While this does solve the first problem of the doubled API surface quite neatly, it does not however solve the second problem of code duplication - one would still have to write two copies of nearly-identical code for an async and sync implementation of the same algorithm. And it comes with its own problems too, such as needing a good way to force one particular overload to be chosen of multiple possibilities.&lt;/p&gt;&lt;p&gt;My alternative idea is what I will refer to as async genericity. Unlike async overloading which has two separate functions with different bodies, under async genericity the async and sync equivalents of one function share a body that works for both. The compiler can then monomorphize this into two separate functions, just like it does for generic parameters. The correct version will be chosen at call site depending on the traits the given generic parameters implement. It is, to some extent, colourless async.&lt;/p&gt;&lt;h2 id=&apos;inspiration-from-const&apos;&gt;&lt;a href=&apos;#inspiration-from-const&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Inspiration from &lt;code class=&apos;scode&apos;&gt;const&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;I’d like to take inspiration from &lt;a href=&apos;https://github.com/rust-lang/rust/issues/67792&apos;&gt;the work on &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; which faces a similar problem to the one we’re facing now: how can one function be written that works for multiple modes (async/sync, const/non const)? A simple example of that is &lt;code class=&apos;scode&apos;&gt;drop&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Drop&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;_x&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This function can be treated as “expanding” into two separate functions:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_const&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; const Drop&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_non_const&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where the correct one will be chosen at call site depending on whether &lt;code class=&apos;scode&apos;&gt;T&lt;/code&gt; can be dropped in &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; contexts. &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Drop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is a compiler-generated &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; subtrait which has all the same methods as &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt;, but converted to &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s. This &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; modifier can actually be applied to any trait to automatically make it &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;: &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Iterator&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; Add&lt;/span&gt;&lt;/code&gt; et cetera. You can read more about this in &lt;a href=&apos;https://internals.rust-lang.org/t/pre-rfc-revamped-const-trait-impl-aka-rfc-2632/15192&apos;&gt;its pre-RFC&lt;/a&gt;, I won’t go into the details here.&lt;/p&gt;&lt;p&gt;I will use this as a starting point for the async generics design. It might look something like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code class=&apos;scode&apos;&gt;T: ~async Drop&lt;/code&gt; bound is implied, like how &lt;code class=&apos;scode&apos;&gt;T: async Drop&lt;/code&gt; would be implied in normal &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s. It “expands” to:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_sync&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In cases where there are multiple generic parameters, like for example:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_pair&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, B&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: A, &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: B&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The synchronous version is only possible when &lt;em&gt;all&lt;/em&gt; parameters implement the synchronous version of the trait.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `A: async Drop, B: async Drop`
&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_pair_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, B&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: A, &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: B&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `A: Drop, B: Drop`
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop_pair_sync&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, B&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: A, &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;: B&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the function is being called where &lt;code class=&apos;scode&apos;&gt;A: Drop&lt;/code&gt; but &lt;code class=&apos;scode&apos;&gt;B: async Drop&lt;/code&gt;, the async version will be selected since &lt;code class=&apos;scode&apos;&gt;A: Drop&lt;/code&gt; implies &lt;code class=&apos;scode&apos;&gt;A: async Drop&lt;/code&gt; already.&lt;/p&gt;&lt;p&gt;If an &lt;code class=&apos;scode&apos;&gt;~async fn&lt;/code&gt; is declared with &lt;em&gt;no&lt;/em&gt; generic parameters that have an &lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; bound, then it’s actually totally equivalent to a synchronous function and should probably be warned against by rustc.&lt;/p&gt;&lt;p&gt;One important aspect to note is that &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async&lt;/span&gt;&lt;/code&gt; is somewhat the opposite of &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;. While a non-&lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; function can always be substituted for a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; one, the inverse is true of &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt;: an &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async&lt;/span&gt;&lt;/code&gt; function can always be substituted for a sync one but not the other way around. This means that while &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; Trait&lt;/span&gt;&lt;/code&gt; is a subtrait of &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; (fewer types implement it than just &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt;), &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async Trait&lt;/span&gt;&lt;/code&gt; is a supertrait of &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; (more types implement it than just &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt;). Or in other words, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;const&lt;/span&gt; Trait&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Trait&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async Trait&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Another important impact of this system is that, unlike with &lt;code class=&apos;scode&apos;&gt;const&lt;/code&gt;, upgrading an implementation from &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; to &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; is a breaking change since the methods will now by default be synchronous instead of asynchronous, so you’ll get errors whereever you previously were using &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;. Of course, the actual number of use cases is universally increased, not reduced (passing it to a function that accepts &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; still works, and the methods will still require &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; there) but direct callers will need to modify their code to have it build. However this should not be a large problem since it’s generally well known up front whether something will need async or not.&lt;/p&gt;&lt;p&gt;Another option would be to have &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; be treated as two entirely separate traits, with no inherent connection between the two. This has the advantage of preventing mistakes like using &lt;code class=&apos;scode&apos;&gt;std::fs::File&lt;/code&gt; in an asynchronous function at compile time (since &lt;code class=&apos;scode&apos;&gt;std::fs::File&lt;/code&gt; would &lt;em&gt;not&lt;/em&gt; implement &lt;code class=&apos;scode&apos;&gt;async Read&lt;/code&gt;), but overall I do not think that to be worth it:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Users can end up making the mistake anyway, just by calling a concrete blocking function like &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; on a &lt;code class=&apos;scode&apos;&gt;Path&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;std&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;thread&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;sleep&lt;/span&gt;&lt;/code&gt;. It would only help prevent a small number of cases.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is not always a mistake; sometimes it &lt;em&gt;is&lt;/em&gt; useful to run blocking code in an asynchronous context, if for example one wants to mix asynchronous and blocking function calls on a blocking worker thread.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Sometimes whether an operation will &lt;em&gt;actually&lt;/em&gt; block is only known dynamically, for example reading from a TCP stream - if it the stream is in &lt;a href=&apos;https://doc.rust-lang.org/stable/std/net/struct.TcpStream.html#method.set_nonblocking&apos;&gt;non-blocking mode&lt;/a&gt; (which is explicitly a supported use case by the standard library) it should be fine to call it from &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; code.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;By default types like &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Vec&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; (whose &lt;code class=&apos;scode&apos;&gt;Write&lt;/code&gt; implementation is neither asynchronous nor blocking, and thus can be used in both contexts) would end up being exclusively synchronous. To support both, it would have to write out boilerplate code to implement both &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; separately, or we’d have to introduce &lt;em&gt;another&lt;/em&gt; new piece of syntax to share an implementation.&lt;/p&gt;&lt;p&gt;It gets worse when considering &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; - every non-generic type implementing that trait would have to migrate to this new syntax to even be usable at all in asynchronous contexts (or we could special-case &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; to have shared implementations, but I can’t think of a strong reason why &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; should be treated so differently from everything else).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Having the traits be separate rather increases the complexity of the system overall.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&apos;relaxed-drop-bounds&apos;&gt;&lt;a href=&apos;#relaxed-drop-bounds&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Relaxed drop bounds&lt;/h2&gt;&lt;p&gt;We introduced implicit default &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; bounds in a &lt;a href=&apos;#function-implicit-bounds&apos;&gt;previous section&lt;/a&gt;; now that we have some actual syntax for async drop (&lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;) the question is how those bounds can be relaxed for functions that allow it.&lt;/p&gt;&lt;p&gt;I’d first like to introduce a new concept in this section: the &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; bound. This bound can be considered the initial one before implicit bounds are added, and it imposes absolutely no requirements on to what extent the type supports being dropped. There would not be any situation in which this bound is necessary over &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;, since the least “droppable” a type can be is &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; - applying it only takes abilities away from the implementor while giving none to the caller. But it is still important to have because it avoids panic-check-passing synchronous functions that don’t care at all about &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; (&lt;code class=&apos;scode&apos;&gt;mem::replace&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;any::type_name&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Option::map&lt;/code&gt; etc) from having to write &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; in their signature to be general. It would feel rather strange for them to declare &lt;code class=&apos;scode&apos;&gt;&amp;lt;T: async Drop&amp;gt;&lt;/code&gt; or something when they actually don’t drop the type asynchronously at all. It also enables future extensions into more kinds of drop which &lt;a href=&apos;#linear-types&apos;&gt;may be useful&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;All functions have a stronger default bound for generic parameters than &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt;, and that can be relaxed to &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; in much the same way as the other implied bound in Rust, &lt;code class=&apos;scode&apos;&gt;Sized&lt;/code&gt;: by adding &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; as a trait bound in the parameter list or in the where clause. Like with &lt;code class=&apos;scode&apos;&gt;Sized&lt;/code&gt; it only accepts the simple cases, so &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; cannot be used as a supertrait (it is &lt;a href=&apos;#drop-supertrait&apos;&gt;the default anyway&lt;/a&gt;) or as a bound on types other than a literal type parameter. There is a slight inconsistency here in that &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; is used even when the implied bound isn’t actually &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt;, because it could be in reality &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;; so in a way it should really be &lt;code class=&apos;scode&apos;&gt;?async Drop&lt;/code&gt; if the outer function is &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async&lt;/span&gt;&lt;/code&gt; and only &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; if the outer function is sync. But since &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; is shorter, more consistent and unambiguous anyway there’s no strong reason not to use it.&lt;/p&gt;&lt;p&gt;When relaxing bounds to something weaker than the default but stronger than &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt;, (particularly, setting them to &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; in a synchronous function) the most obvious option is to support the trait name directly - use &lt;code class=&apos;scode&apos;&gt;T: async Drop&lt;/code&gt; to support &lt;code class=&apos;scode&apos;&gt;T&lt;/code&gt; not implementing any of the &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; subtraits (&lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;const Drop&lt;/code&gt;), but requiring it to implement &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;. However this approach ends up being quite problematic because unlike &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; whose unique syntax excuses it from only supporting a few special cases, &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; is also a trait like any other and so must be supported in the general case like any other.&lt;/p&gt;&lt;p&gt;What this means is that having &lt;code class=&apos;scode&apos;&gt;T: async Drop&lt;/code&gt; implicitly also relax a &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; bound breaks down in more complex cases (such as when it’s implied through a supertrait, or transitively via a bound in the &lt;code class=&apos;scode&apos;&gt;where&lt;/code&gt; clause applied to another type) leading to inconsistent behaviour and confusing semantics.&lt;/p&gt;&lt;p&gt;Instead, Rust should take the consistent approach of &lt;em&gt;allowing&lt;/em&gt; (but potentially warning against) bounds like &lt;code class=&apos;scode&apos;&gt;T: async Drop&lt;/code&gt; on a synchronous function, but not giving them any effect unless they’re &lt;em&gt;also&lt;/em&gt; paired with &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt;. Since &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; implies &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;, adding &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; in a synchronous function is a tautology and only by taking away the initial &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; bound does it have a meaning.&lt;/p&gt;&lt;p&gt;The only problem with this approach is its verbosity: &lt;code class=&apos;scode&apos;&gt;T: ?Drop + async Drop&lt;/code&gt; is quite the mouthful to express one concept. It’s possible that Rust could introduce some syntax sugar to make it shorter, the only difficulty is what the actual syntax of that would be while remaining clear and unambiguous. I’m very much open to suggestions here.&lt;/p&gt;&lt;h2 id=&apos;synchronous-opt-out&apos;&gt;&lt;a href=&apos;#synchronous-opt-out&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Synchronous opt-out&lt;/h2&gt;&lt;p&gt;While blindly turning every method in the trait &lt;code class=&apos;scode&apos;&gt;const&lt;/code&gt; works most of the time for &lt;code class=&apos;scode&apos;&gt;const Trait&lt;/code&gt;s, it doesn’t end up working so well for &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt;s. In particular, there are quite a few methods that would benefit from always being synchronous whether the outer trait is considered asynchronous or not, for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Iterator::size_hint&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;ExactSizeIterator::len&lt;/code&gt;: These methods should be O(1) and not perform I/O, so there’s no reason to have them be &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Iterator::{step_by, chain, zip, map, filter, enumerate, ...}&lt;/code&gt;: These functions just construct a type and return it, no asynchronity here.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;Read::{by_ref, bytes, chain, take}&lt;/code&gt;: More trivial functions that just construct a type.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;BufRead::consume&lt;/code&gt;: Any I/O done by the &lt;code class=&apos;scode&apos;&gt;BufRead&lt;/code&gt; should occur in &lt;code class=&apos;scode&apos;&gt;fill_buf&lt;/code&gt; and all &lt;code class=&apos;scode&apos;&gt;consume&lt;/code&gt; should do is move around a couple numbers. Hence, it should be always synchronous.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So evidently trait definitions need to be able to control what their &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; form would look like. Having any kind of default chosen by the Rust compiler would be a bad idea, because even without thinking about &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; code, just by writing a single trait you’d have already chosen and stabilized an &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; API. Plus, it’s not like many traits need to have async equivalents - it’s mostly just &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt;, I/O traits, functions and &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; that matter. Therefore I think it is best to have &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; support be an opt-in by the trait declarer.&lt;/p&gt;&lt;p&gt;The syntax to declare one of these traits can be something along the lines of &lt;code class=&apos;scode&apos;&gt;trait ~async Foo&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;~async trait Foo&lt;/code&gt;, or &lt;code class=&apos;scode&apos;&gt;async trait Foo&lt;/code&gt; - I don’t have a strong preference and will use the first for now. In order to declare the methods of these traits as being conditionally async, the same &lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; syntax can actually be borrowed over from generic async functions - &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt; will just be treated as another generic parameter with an &lt;code class=&apos;scode&apos;&gt;~async Trait&lt;/code&gt; bound. This produces a nice parallel between functions and traits, as demonstrated below:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; What you write
&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;async Trait&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async Trait &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; What it &amp;quot;expands&amp;quot; to
&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async Trait&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f_sync&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Trait&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;async&lt;/span&gt; Trait &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Trait&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And since those functions are actually just regular &lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; functions, they also interact with generic parameters:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async Trait &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;async Read&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; What it &amp;quot;expands&amp;quot; to
&lt;/span&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;async&lt;/span&gt; Trait &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async Read&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Trait&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async Read&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f_sync&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Read&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; A synchronous implementation
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Trait &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;async Read&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; An asynchronous implementation
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Trait&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;u32&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async Read&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; A generic implementation
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Trait&lt;/span&gt;&amp;gt; ~&lt;span class=&quot;sentity sname simpl srust&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Trait&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;T&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;async Read&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Just like with regular &lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; functions, the synchronous version only exists when &lt;em&gt;all&lt;/em&gt; generic parameters (here, both &lt;code class=&apos;scode&apos;&gt;T&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Self&lt;/code&gt;) implement the trait synchronously.&lt;/p&gt;&lt;p&gt;The last thing to note is that associated types in &lt;code class=&apos;scode&apos;&gt;~async Trait&lt;/code&gt;s would have the implicit bound &lt;code class=&apos;scode&apos;&gt;~async Drop&lt;/code&gt;: when the trait is an &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; they’re allowed to be &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; but when it’s a synchronous &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt; they are required to be &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt;. This should follow the rules that users will want most of the time.&lt;/p&gt;&lt;p&gt;To conclude, I’ll leave you with an annotated snippet of how the &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt; trait might look with added &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; support:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;ssupport stype srust&quot;&gt;Iterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;size_hint&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;, &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fold&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; B, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; B
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Sized,
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `fold` always drops `Self` at the end so this bound is required.
&lt;/span&gt;		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ~async Drop,
		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ~async FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;B, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; We can&amp;#39;t relax B&amp;#39;s bound because it&amp;#39;s dropped in the event that
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `self.next()` panics.
&lt;/span&gt;	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; init&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `.await` is required in both cases because it could be a cancellation
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; point.
&lt;/span&gt;		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;accum&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		accum
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;map&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Map&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Sized,
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Even a synchronous iterator&amp;#39;s `map` accepts an `async FnMut` here,
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; without the tilde. This is because every `FnMut` is also an
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; `async FnMut`, so `async FnMut` is the strictly more general bound.
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; The tilde is only necessary when the function effectively needs to
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; specialize on the synchronous case to not be async, but that&amp;#39;s not
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; necessary here since `map` isn&amp;#39;t ever async anyway.
&lt;/span&gt;		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; async FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; The default bounds are overly restrictive, so we relax them.
&lt;/span&gt;		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Drop,
		B&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Drop,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta spath srust&quot;&gt;Map&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; et cetera
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compared to the current design of adding a new &lt;code class=&apos;scode&apos;&gt;Stream&lt;/code&gt;/&lt;code class=&apos;scode&apos;&gt;AsyncIterator&lt;/code&gt; trait, this has the following advantages:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We don’t have to decide between async vs sync callbacks for functions like &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; (currently &lt;a href=&apos;https://docs.rs/futures-util/0.3/futures_util/stream/trait.StreamExt.html#method.fold&apos;&gt;futures-util&lt;/a&gt; and &lt;a href=&apos;https://docs.rs/tokio-stream/0.1/tokio_stream/trait.StreamExt.html#method.fold&apos;&gt;tokio-stream&lt;/a&gt; disagree about this).&lt;/li&gt;&lt;li&gt;We don’t have two separate functions &lt;code class=&apos;scode&apos;&gt;.map&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;.then&lt;/code&gt; for sync and async respectively.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;.map&lt;/code&gt; with an async function can be called on a synchronous iterator, automatically turning it into an async one.&lt;/li&gt;&lt;li&gt;There’s no need for additional conversion functions like &lt;code class=&apos;scode&apos;&gt;.into_stream()&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;.into_async_iter()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Existing iterators like &lt;code class=&apos;scode&apos;&gt;slice::Iter&lt;/code&gt; will automatically implement the new &lt;code class=&apos;scode&apos;&gt;async Iterator&lt;/code&gt; trait.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&apos;async-traits-and-backwards-compatibility&apos;&gt;&lt;a href=&apos;#async-traits-and-backwards-compatibility&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Async traits and backwards compatibility&lt;/h2&gt;&lt;p&gt;If you look closely at my definition of &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt; above you’ll notice that it’s actually not backward compatible with the current definition of &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt;. The problem is that today, people can override functions like &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; that are less powerful than the &lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; version. For example:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Iterator &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Example&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fold&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;accum&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; B, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; B
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;B, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;accum&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Under my definition of &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt;, that code would instead need to be rewritten like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;Iterator &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Example&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fold&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;accum&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; B, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; B
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ~async FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;B, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;accum&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The iterator itself is still not async, but this change would additionally allow calling &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; with an asynchronous callback even if the underlying iterator is still synchronous.&lt;/p&gt;&lt;p&gt;Unfortunately, we can’t just make the first version stop compiling due to Rust’s backward compatibility guarantees. And even an edition won’t be able to fix this, since the issue is greater than just a syntactical one.&lt;/p&gt;&lt;p&gt;I don’t think there is a reasonable way to somehow fix &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; itself - its signature is effectively set in stone at this point. But we &lt;em&gt;can&lt;/em&gt; add a &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Iterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Item = &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; bound to it and then have the generic version be under a new name, &lt;code class=&apos;scode&apos;&gt;fold_async&lt;/code&gt;. Since &lt;code class=&apos;scode&apos;&gt;fold_async&lt;/code&gt; would be strictly more general than &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt;, the default implementation of &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; can just forward to it. So the definition of &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt; would actually look more like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;ssupport stype srust&quot;&gt;Iterator&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;next&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fold&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; B, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; B
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Iterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Item = &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; + Sized + Drop,
		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;B, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;fold_async&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;init&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;fold_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;B, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; B, &lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; B
	&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Sized + ~async Drop,
		F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ~async FnMut&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;B, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Item&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; B,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; init&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;skeyword scontrol srust&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			accum &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;accum&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; x&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		accum
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; et cetera
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Even though it looks very similar to not having async genericity at all, it is still better than without because:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Overriding &lt;code class=&apos;scode&apos;&gt;fold_async&lt;/code&gt; also effectively overrides &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; - they’re able to share an implementation.&lt;/li&gt;&lt;li&gt;Async and sync iterators share definitions of &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;fold_async&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This makes the feature still worth it in my opinion, even if we have to insert some hacks into &lt;code class=&apos;scode&apos;&gt;Iterator&lt;/code&gt; to avoid breaking compatibility.&lt;/p&gt;&lt;p&gt;Unfortunately &lt;code class=&apos;scode&apos;&gt;fold&lt;/code&gt; isn’t the only method that would need this treatment, potentially many others would too. By my count, this includes (in the standard library alone): &lt;code class=&apos;scode&apos;&gt;chain&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;zip&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;map&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;for_each&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;filter&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;filter_map&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;skip_while&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;take_while&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;map_while&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;scan&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;flat_map&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;flatten&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;inspect&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;collect&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;partition&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;try_fold&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;try_for_each&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;reduce&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;all&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;any&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;find&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;find_map&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;position&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;rposition&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;sum&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;product&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;cmp&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;partial_cmp&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;eq&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ne&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;lt&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;le&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;gt&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ge&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::try_rfold&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::rfold&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::rfind&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Read::chain&lt;/code&gt;. If &lt;code class=&apos;scode&apos;&gt;async Clone&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;async Ord&lt;/code&gt; become things, the list would grow longer.&lt;/p&gt;&lt;p&gt;It is a bit of a shame that functions like &lt;code class=&apos;scode&apos;&gt;map&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Read::chain&lt;/code&gt; have to have async versions though, since it’s not like anyone overrides &lt;code class=&apos;scode&apos;&gt;map&lt;/code&gt; anyway. But because it’s &lt;em&gt;technically&lt;/em&gt; possible, Rust has already promised not to break that code and so now can’t relax the signature of that function. Although who knows, maybe if we got a low % regression Crater run it would convince people that’s it’s acceptable breakage and the list could be shortened to the much more manageable &lt;code class=&apos;scode&apos;&gt;for_each&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;partition&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;try_fold&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;try_for_each&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;reduce&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;all&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;any&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;find&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;find_map&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;position&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;rposition&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;cmp&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;partial_cmp&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;eq&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ne&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;lt&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;le&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;gt&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ge&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::try_rfold&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::rfold&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;DoubleEndedIterator::rfind&lt;/code&gt;. I would definitely rather do this, because frankly if you override &lt;code class=&apos;scode&apos;&gt;map&lt;/code&gt; then you deserve what you get.&lt;/p&gt;&lt;p&gt;Out of the group, &lt;code class=&apos;scode&apos;&gt;collect&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;sum&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;product&lt;/code&gt; are an especially interesting three because their &lt;code class=&apos;scode&apos;&gt;_async&lt;/code&gt; versions (and their normal versions if we accept the technically breaking change) can’t use the standard &lt;code class=&apos;scode&apos;&gt;FromIterator&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Product&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Sum&lt;/code&gt; traits since those traits are currently hardcoded to work for synchronous iterators only. So we would instead have to make new &lt;code class=&apos;scode&apos;&gt;*Async&lt;/code&gt; versions of those traits with blanket implementations of the old versions:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Not sure how useful `~async` is here; it would only be needed for collections
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; that actually perform async work themselves while collecting as opposed to
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; just potentially-asynchronously receiving the items and then synchronously
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; collecting them.
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; This is not true of any existing `FromIterator` or `FromStream`
&lt;/span&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; implementation currently, but there may still be use cases - who knows.
&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sgeneric srust&quot;&gt;FromAsyncIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Sized&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_async_iter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;~&lt;/span&gt;&lt;/span&gt;async &lt;span class=&quot;smeta sgeneric srust&quot;&gt;IntoIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Item = A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;iter&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;FromAsyncIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;FromIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;T&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;from_iter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;IntoIterator&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Item = A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from_async_iter&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;iter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With similar code for both &lt;code class=&apos;scode&apos;&gt;Sum&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Product&lt;/code&gt;. Unlike &lt;code class=&apos;scode&apos;&gt;Iterator::fold&lt;/code&gt;, since &lt;code class=&apos;scode&apos;&gt;from_iter&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;sum&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;product&lt;/code&gt; aren’t default-implemented methods we can’t just add a new &lt;code class=&apos;scode&apos;&gt;from_async_iter&lt;/code&gt; function to the &lt;code class=&apos;scode&apos;&gt;FromIterator&lt;/code&gt; trait itself; an entirely new trait is needed.&lt;/p&gt;&lt;h2 id=&apos;trait-impl-implicit-bounds&apos;&gt;&lt;a href=&apos;#trait-impl-implicit-bounds&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Trait impl implicit bounds&lt;/h2&gt;&lt;p&gt;&lt;a href=&apos;#function-implicit-bounds&apos;&gt;Before&lt;/a&gt;, I talked about how inside an inherent impl block, implicit &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; bounds to generics of the outer type would apply individually to each of the methods depending on its asynchronity, and the block itself would enforce no bounds on the type. Unfortunately, we don’t have that luxury when considering trait implementations: either the trait is implemented or it’s not and we can’t apply our own bounds to individual items.&lt;/p&gt;&lt;p&gt;However, we &lt;em&gt;do&lt;/em&gt; know whether the trait overall should be considered asynchronous or not - whether it’s being implemented as &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;Trait&lt;/code&gt;. So we can just forward that property as the default kind of &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; bound, and it should be what users want most of the time. Of course, for the (hopefully) rare case that it’s &lt;em&gt;not&lt;/em&gt; desired they can always override it. The most obvious time that crops up is when implementing a trait that isn’t an &lt;code class=&apos;scode&apos;&gt;async Trait&lt;/code&gt; but still has async methods (i.e. an async trait with no synchronous equivalent) - then the drop bounds would end up overly restrictive:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;ExampleTrait&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;foo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;V&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; V&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; ExampleTrait &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; overly-restrictive implied bound: `T: Drop`
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;foo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;V&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; V&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; implied bound: `V: async Drop` (since it&amp;#39;s declared
&lt;/span&gt;		&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; on the function and not on the impl block)
&lt;/span&gt;	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;todo!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But with any luck this kind of code won’t be too common, since users should ideally be writing most code as generic-over-async anyway.&lt;/p&gt;&lt;p&gt;An interesting side effect of the above rule is in code like below:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; implied Drop bound &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Drop &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;I am being dropped&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although it is not obvious, this code wouldn’t compile because the &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; implementation of a type has more restrictive trait bounds than the type itself, and that isn’t allowed. But since it looks like this code should compile, I find it acceptable to introduce a special case and simply have the compiler forward that implicit &lt;code class=&apos;scode&apos;&gt;T: Drop&lt;/code&gt; bound to the type itself, but only when a &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; implementation specifically is present.&lt;/p&gt;&lt;p&gt;Either way, that type does not work with &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; types and the fix is like so:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt;&amp;gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;I am being dropped&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&apos;async-closures&apos;&gt;&lt;a href=&apos;#async-closures&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Async closures&lt;/h2&gt;&lt;p&gt;Supporting async genericity with closures (as required for functions like &lt;code class=&apos;scode&apos;&gt;Option::map&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Iterator::fold&lt;/code&gt;) requires &lt;code class=&apos;scode&apos;&gt;async {Fn, FnMut, FnOnce}&lt;/code&gt; to exist as traits. It seems that this is a bit useless since we already have functions that return futures, but as it turns out there is an actual benefit to having separate &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; function traits, particularly when working with closures: it makes the lifetimes a lot easier to manage, since the returned futures will be able to borrow the closure and parameters - something impossible with the current design.&lt;/p&gt;&lt;p&gt;However in order for the &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt;-traits to be useful, they must be actually implemented by the relevant functions and closures. Currently, people support asynchronous callbacks by having closures that return futures (&lt;code class=&apos;scode&apos;&gt;|| async {}&lt;/code&gt;) - and &lt;code class=&apos;scode&apos;&gt;async fn&lt;/code&gt;s are desugared to functions of this form too. It wouldn’t be a good idea to attempt to change the behaviour of the former since that would need a hacky compiler special case for closures returning futures only, but thankfully we have reserved a bit of syntax that would be perfect for this use case: async closures (&lt;code class=&apos;scode&apos;&gt;async || {}&lt;/code&gt;). If they were to evaluate to closure types implementing &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt; instead of &lt;code class=&apos;scode&apos;&gt;Fn&lt;/code&gt;, they could be passed into async-generic functions like &lt;code class=&apos;scode&apos;&gt;Option::map&lt;/code&gt; without a problem.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Gives an `Option&amp;lt;T&amp;gt;`, since the async `map` is used.
&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; output &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; some_option.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;async &lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;value&lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Gives an `Option&amp;lt;impl Future&amp;lt;Output = T&amp;gt;&amp;gt;`, since the sync `map` is used.
&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; output &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; some_option.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;value&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The less good side of this addition is with &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s: we would have to choose between keeping the current system of desugaring to a simple &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; impl Future&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; function, and implementing the &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt; traits. The former is backwards compatible and more transparent (since those functions can be replicated entirely in userspace), but the latter has better interopability with async generic functions. I am inclined to choose the latter design, but it’s an unfortunate decision to have to make.&lt;/p&gt;&lt;p&gt;Note that it wouldn’t be possible to implement &lt;em&gt;both&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Fn&lt;/code&gt;, because implementing &lt;code class=&apos;scode&apos;&gt;Fn&lt;/code&gt; already implies implementing &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt; as an async function that never awaits; we would end up with conflicting implementations of &lt;code class=&apos;scode&apos;&gt;async Fn&lt;/code&gt;, one that asynchronously evaluates to &lt;code class=&apos;scode&apos;&gt;T&lt;/code&gt; and one that immediately evaluates to &lt;code class=&apos;scode&apos;&gt;impl Future&amp;lt;Output = T&amp;gt;&lt;/code&gt;. To avoid that compile error we would have to choose one and discard the other.&lt;/p&gt;&lt;h2 id=&apos;conclusion&apos;&gt;&lt;a href=&apos;#conclusion&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;In this post we sketched out a potential design for async drop, figuring out many details and intricacies along the way. The resulting proposal is unfortunately not a small one, however it does have much general usefulness outside of async destructors (&lt;code class=&apos;scode&apos;&gt;~async&lt;/code&gt; in particular would be excellent to have for so much code) and lots of it is necessary if we are to minimize footguns.&lt;/p&gt;&lt;p&gt;As a summary of everything we’ve explored thus far:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;We figured out the desired edge case semantics of async drop during cancellation, panics and assignments, in synchronous functions and with generics.&lt;/li&gt;&lt;li&gt;We explored a system for async destructors based on destructor futures instead of &lt;code class=&apos;scode&apos;&gt;poll_drop_ready&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;We explored a mechanism for supporting code that is generic over whether it is &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; or not.&lt;/li&gt;&lt;li&gt;We hypothesized what is best to apply as the default generic drop bounds in functions, as well as how to relax and strengthen them if necessary.&lt;/li&gt;&lt;li&gt;We considered how async genericity would impact functions and closures.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This post doesn’t attempt to provide a final design for async drop - there are still many open questions (e.g. &lt;code class=&apos;scode&apos;&gt;UnwindSafe&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; syntax, &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;no_std&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; support) and likely unknown unknowns. But it does attempt to properly explore one particular design to evaluate its complexity, feasability and usefulness. Out of all possible options, I think it to be quite a promising one and definitely possible to implement in some form.&lt;/p&gt;&lt;p&gt;Many thanks to Yoshua Wuyts for proofreading this for me!&lt;/p&gt;&lt;h2 id=&apos;completion-futures&apos;&gt;&lt;a href=&apos;#completion-futures&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Appendix A: Completion futures&lt;/h2&gt;&lt;p&gt;Completion futures are a concept for a special type of future that is guaranteed at compile-time to not be prematurely dropped or leaked, in contrast to regular futures which can be stopped without warning at any time. It doesn’t sound like much, but completion futures are actually incredibly useful:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;They enable &lt;code class=&apos;scode&apos;&gt;spawn&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;spawn_blocking&lt;/code&gt; functions that don’t restrict the future’s lifetime to &lt;code class=&apos;scode&apos;&gt;&apos;static&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;They enable creating zero-cost wrappers around completion-based APIs like &lt;code class=&apos;scode&apos;&gt;io_uring&lt;/code&gt;, IOCP and libusb.&lt;/li&gt;&lt;li&gt;They enables better interopability with C++ futures, which have this guarantee by default.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I have previously written &lt;a href=&apos;https://github.com/SabrinaJewson/completion&apos;&gt;a library for this&lt;/a&gt; but it was very limited because it fundamentally needed to rely on &lt;code class=&apos;scode&apos;&gt;unsafe&lt;/code&gt;, infecting just about every use of it with &lt;code class=&apos;scode&apos;&gt;unsafe&lt;/code&gt; as well which was really not ideal. But it turns out that with an async destructor design like the one proposed by this post, it is much easier to support them in an even more powerful way and with minimal &lt;code class=&apos;scode&apos;&gt;unsafe&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The solution is to add a single new trait to the core library:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;unsafe&lt;/span&gt; auto &lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Leak&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As an auto trait, it would be implemented for every single type other than a special &lt;code class=&apos;scode&apos;&gt;core::marker::PhantomNoLeak&lt;/code&gt; marker and any type transitively containing that. What &lt;code class=&apos;scode&apos;&gt;Leak&lt;/code&gt; represents is the ability to safely leak an instance of the type, via &lt;a href=&apos;https://doc.rust-lang.org/stable/std/mem/fn.forget.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;mem::forget&lt;/code&gt;&lt;/a&gt;, reference cycles or anything similar. If a type opts out of implementing it, it is guaranteed that from creation, its &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; implementation will be run if the type’s lifetime to end.&lt;/p&gt;&lt;p&gt;The standard library would have all the “leaky” APIs like &lt;code class=&apos;scode&apos;&gt;Arc&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Rc&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ManuallyDrop&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;MaybeUninit&lt;/code&gt; require that &lt;code class=&apos;scode&apos;&gt;Leak&lt;/code&gt; be implemented on the inner type, to avoid safe code being able to circumvent the restriction. Other than that, most other APIs would support both &lt;code class=&apos;scode&apos;&gt;Leak&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;!Leak&lt;/code&gt; types, since they will run the destructor of inner values.&lt;/p&gt;&lt;p&gt;And this is all we need to support completion futures. An &lt;code class=&apos;scode&apos;&gt;io_uring&lt;/code&gt; I/O operation future can be implemented by submitting the operation on creation and waiting for it to complete on drop, and the &lt;code class=&apos;scode&apos;&gt;!Leak&lt;/code&gt; guarantee means that the &lt;a href=&apos;https://github.com/spacejam/rio/issues/30&apos;&gt;use-after-free issue&lt;/a&gt; &lt;code class=&apos;scode&apos;&gt;io_uring&lt;/code&gt; libraries currently have to work around is eliminated.&lt;/p&gt;&lt;p&gt;This is a very powerful feature, even more so than my old &lt;code class=&apos;scode&apos;&gt;unsafe&lt;/code&gt;-based implementation. Because it guarantees not leaking from creation and not just from the first poll, scoped tasks don’t even need a special scope to be defined (à la &lt;a href=&apos;https://docs.rs/crossbeam/0.8/crossbeam/fn.scope.html&apos;&gt;Crossbeam&lt;/a&gt;). Instead, an API like this just works:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;spawn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, R, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;JoinHandle&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, R&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Future&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Output = R&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; + Send + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;,
	R&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Send,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It also has impacts on synchronous code, because &lt;a href=&apos;https://doc.rust-lang.org/stable/std/thread/fn.spawn.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;thread::spawn&lt;/code&gt;&lt;/a&gt; gets to be extended in a similar way:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;spawn_scoped&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, R, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;JoinHandle&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;, R&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; FnOnce&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt; -&amp;gt; R + Send + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;a&lt;/span&gt;,
	R&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Send,
&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This would allow you to write code that borrows from the stack without problems:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; message &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;Hello World&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;to_owned&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Synchronous code
&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; thread_1 &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;thread&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn_scoped&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{message}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; thread_2 &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;thread&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn_scoped&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{message}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
thread_1.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
thread_2.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; Asynchronous code
&lt;/span&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; task_1 &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{message}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; task_2 &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ssupport smacro srust&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sconstant sother splaceholder srust&quot;&gt;{message}&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
task_1.await.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
task_2.await.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Neat, right?&lt;/p&gt;&lt;p&gt;As with many things it needs an edition boundary to implement fully: In the current edition, every generic parameter has to still imply &lt;code class=&apos;scode&apos;&gt;T: Leak&lt;/code&gt; but in future editions that can be relaxed to &lt;code class=&apos;scode&apos;&gt;T: ?Leak&lt;/code&gt;, allowing the small subset of APIs that &lt;em&gt;can&lt;/em&gt; leak values (&lt;code class=&apos;scode&apos;&gt;Arc&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Rc&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;mem::forget&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;ManuallyDrop&lt;/code&gt;, etc) to declare so in their signature and the majority of APIs to have the less restrictive bound by default.&lt;/p&gt;&lt;h2 id=&apos;weakly-async-functions&apos;&gt;&lt;a href=&apos;#weakly-async-functions&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Appendix B: Weakly async functions&lt;/h2&gt;&lt;p&gt;With the current design, there ends up being a large number of functions with the specific property that they need to be &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; async &lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;s if a type they deal with is &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt;, for the sole reason that they are able to panic while they have that type in scope. I listed a few at the start of the &lt;a href=&apos;#async-genericity&apos;&gt;async genericity&lt;/a&gt; section, including &lt;code class=&apos;scode&apos;&gt;HashMap::{insert, entry}&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Vec::push&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Box::new&lt;/code&gt;, but there’s one particularly relevant one here which is &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; (as seen in various runtimes: &lt;a href=&apos;https://docs.rs/tokio/1/tokio/task/fn.spawn.html&apos;&gt;tokio&lt;/a&gt;, &lt;a href=&apos;https://docs.rs/async-std/1/async_std/task/fn.spawn.html&apos;&gt;async-std&lt;/a&gt;, &lt;a href=&apos;https://docs.rs/glommio/0.7/glommio/fn.spawn_local.html&apos;&gt;glommio&lt;/a&gt;, &lt;a href=&apos;https://docs.rs/smol/1/smol/fn.spawn.html&apos;&gt;smol&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Across all those runtimes, &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; has the ability to panic before it spawns the future, which commonly can happen if the runtime is not running, but can also theoretically happen if allocation fails or there’s some other random system error. The problem is that just because of this one small edge case (and their presumed desire to support &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; futures), &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; is forced to be a full &lt;code class=&apos;scode&apos;&gt;async fn&lt;/code&gt; even though &lt;em&gt;in itself&lt;/em&gt; it doesn’t do any &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; work.&lt;/p&gt;&lt;p&gt;This is especially bad for &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; as a function because it can easily trip up those who are migrating code. For example, while before this code would run the task in parallel with &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;other_work&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; task &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;some_future&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;other_work&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
task.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the changes applied it would instead run &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource srust&quot;&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;other_work&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and wait for it to complete, and &lt;em&gt;then&lt;/em&gt; spawn the task and not even wait for it to finish! (Unless of course dropping a task handle would be changed to implicitly join the task, which &lt;em&gt;may&lt;/em&gt; be a better design overall - but the point still stands because it doesn’t run in parallel as people would expect.)&lt;/p&gt;&lt;p&gt;The fixed version would look like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; task &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;spawn&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;some_future&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;ssupport sfunction srust&quot;&gt;other_work&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
task.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But given that the old version doesn’t even fail to compile, it’s not an ideal situation to be in. Additionally, it does just look weird having a future that resolves to…another future.&lt;/p&gt;&lt;p&gt;My proposed solution to this problem is to add a new type of function to the language called “weakly async functions” which are in between asynchronous functions and synchronous functions. Let’s denote it here with &lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt;, but the syntax is obviously up for bikeshedding. The idea is this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt;s either complete synchronously or panic asynchronously.&lt;/li&gt;&lt;li&gt;Because they must complete synchronously, they cannot be cancelled and thus they don’t need to be &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;ed - that can be made implicit.&lt;/li&gt;&lt;li&gt;Because they panic asynchronously, they bypass the panic check and are allowed to own types with asynchronous destructors across potential panic points (but are not allowed to drop them unless via a panic).&lt;/li&gt;&lt;li&gt;They are allowed to call regular &lt;code class=&apos;scode&apos;&gt;fn&lt;/code&gt;s and other &lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt;s, but not &lt;code class=&apos;scode&apos;&gt;async fn&lt;/code&gt;s.&lt;/li&gt;&lt;li&gt;They cannot be called from within synchronous functions.&lt;/li&gt;&lt;li&gt;They are not allowed to recurse, just like &lt;code class=&apos;scode&apos;&gt;async fn&lt;/code&gt;s.&lt;/li&gt;&lt;li&gt;It is not a breaking change to convert from an &lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt; to a regular fn.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This way, &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; (and a bunch of other functions like &lt;code class=&apos;scode&apos;&gt;Box::new&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Box::pin&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Vec::push&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Result::unwrap&lt;/code&gt; etc) would avoid requiring &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt;s when being called with &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; types. This solves the above footgun while also contributing to the succintness of code. &lt;code class=&apos;scode&apos;&gt;task::spawn&lt;/code&gt; would be defined something like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;async&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;spawn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;O, F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;JoinHandle&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;O&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
	F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Future&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Output = O&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; + Send + ?Drop + async Drop + &lt;span class=&quot;sstorage smodifier slifetime srust&quot;&gt;&amp;#39;static&lt;/span&gt;,
	O&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Send,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And in asynchronous contexts would be callable with just &lt;code class=&apos;scode&apos;&gt;task::spawn(future)&lt;/code&gt;, no await necessary.&lt;/p&gt;&lt;p&gt;When inside generic code, &lt;code class=&apos;scode&apos;&gt; [async]&lt;/code&gt; would be treated as another state that &lt;code class=&apos;scode&apos;&gt;~async fn&lt;/code&gt;s can be in, meaning there are actually three ways to those functions. There would additionally be &lt;code class=&apos;scode&apos;&gt;~[async] fn&lt;/code&gt;s for functions that can be either &lt;code class=&apos;scode&apos;&gt;fn&lt;/code&gt;s or &lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt;s, but not &lt;code class=&apos;scode&apos;&gt;async fn&lt;/code&gt;s.&lt;/p&gt;&lt;p&gt;You’d also need a special kind of bound to represent “&lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; when the function is synchronous and &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; when the function is &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt;, but also &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; when the function is &lt;code class=&apos;scode&apos;&gt; [async]&lt;/code&gt;, since this function does not drop a value of this type unless it panics”. For now I will use the incredibly verbose form &lt;code class=&apos;scode&apos;&gt;~[async] async Drop&lt;/code&gt; to represent this, but if this feature is actually added a better and more bikeshedded syntax will probably have to be chosen.&lt;/p&gt;&lt;p&gt;This is the feature that allows us to define &lt;code class=&apos;scode&apos;&gt;Vec::push&lt;/code&gt; generically:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;async&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;push&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Drop + ~[async] async Drop,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;scomment sline sdouble-slash srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;//&lt;/span&gt; &amp;quot;Expanded&amp;quot; version
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;push_sync&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Drop,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;skeyword soperator srust&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;async&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;push_weak_async&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
		T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; ?Drop + async Drop,
	&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; ... &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember that this function can drop &lt;code class=&apos;scode&apos;&gt;item&lt;/code&gt; and so can’t be fully synchronous, but also doesn’t drop &lt;code class=&apos;scode&apos;&gt;item&lt;/code&gt; unless it’s panicking and so shouldn’t be made fully &lt;code class=&apos;scode&apos;&gt;async&lt;/code&gt; either. As such it uses the in-between, supporting &lt;code class=&apos;scode&apos;&gt;async Drop&lt;/code&gt; (and therefore also &lt;code class=&apos;scode&apos;&gt; [async] Drop&lt;/code&gt;) when it is an &lt;code class=&apos;scode&apos;&gt; [async] fn&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; when it is a &lt;code class=&apos;scode&apos;&gt;fn&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Unlike completion futures, I’m not so certain whether this is a good idea or not, or whether there aren’t any other simpler alternatives. But I do definitely think there is a problem here that does need to be addressed somehow, and to me this seems the best way to do it.&lt;/p&gt;&lt;h2 id=&apos;linear-types&apos;&gt;&lt;a href=&apos;#linear-types&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Appendix C: Linear types&lt;/h2&gt;&lt;p&gt;I feel that I have to mention linear types at least once, given how much discourse there has been about them. A linear type is defined as “a type that must be used exactly once”. It turns out this definition is slightly vague, because it can refer to two things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Types which do not have any kind of &lt;code class=&apos;scode&apos;&gt;Drop&lt;/code&gt; implementation and must be handled explicitly, but can be leaked with functions like &lt;a href=&apos;https://doc.rust-lang.org/stable/std/mem/fn.forget.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;mem::forget&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Types which do have destructors and so can implicitly fall out of scope, but can’t be leaked with functions like &lt;a href=&apos;https://doc.rust-lang.org/stable/std/mem/fn.forget.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;mem::forget&lt;/code&gt;&lt;/a&gt; (so they are guaranteed to be able to run code before falling out of scope).&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The former is a more common definition of linear types, and allows for types to force their users to be more explicit about what happens to them when they’re destroyed. I don’t have a proposal for this, but simply by coincidence the proposed &lt;code class=&apos;scode&apos;&gt;?Drop&lt;/code&gt; bound feature does orient itself towards supporting linear types of this sort in future and although personally I do not think they will be worth adding, their viability has been increased as a side-effect.&lt;/p&gt;&lt;p&gt;The latter definition is what is implemented by the above &lt;a href=&apos;#completion-futures&apos;&gt;completion futures&lt;/a&gt; proposal. In a way it’s not true linear types, but it’s the only one that gives the practical benefits of things like zero-cost &lt;code class=&apos;scode&apos;&gt;io_uring&lt;/code&gt; and scoped tasks. It is also a lot less difficult to integrate into existing Rust code, which tends to rely quite heavily on destructors existing but not so much on values being safely leakable.&lt;/p&gt;&lt;h2 id=&apos;uncancellable-futures&apos;&gt;&lt;a href=&apos;#uncancellable-futures&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Appendix D: Uncancellable futures&lt;/h2&gt;&lt;p&gt;I previously argued against &lt;a href=&apos;https://carllerche.netlify.app/2021/06/17/six-ways-to-make-async-rust-easier/&apos;&gt;Carl Lerche’s suggestion to make all async functions uncancellable&lt;/a&gt; in favour of defining consistent semantics for &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; rather than removing it. However, these kinds of functions not totally off the table; such a feature can still definitely exist, first of all as a userspace combinator:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;pub&lt;/span&gt; async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;must_complete&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Future&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;fut&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; F&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	MustComplete&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;fut&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;pin_project&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;PinnedDrop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sannotation sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;MustComplete&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Future&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;#[pin] F&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Future &lt;span class=&quot;skeyword soperator srust&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sinvalid sillegal srust&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt; + &lt;span class=&quot;sentity sname simpl srust&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Drop&lt;/span&gt;&amp;gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Future&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;MustComplete&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;F&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;poll&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;: &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Pin&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;svariable sparameter srust&quot;&gt;cx&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;task&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Context&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&amp;#39;&lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Poll&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;sconstant snumeric sfloat srust&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;poll&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;cx&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sannotation srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sannotation srust&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;svariable sannotation srust&quot;&gt;pinned_drop&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Future&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;PinnedDrop&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;MustComplete&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;F&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	async &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;drop&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;: &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Pin&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;sconstant snumeric sfloat srust&quot;&gt;0.&lt;/span&gt;await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Usable like so:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;must_complete&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;async &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;some_very_important_work&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;ssupport sfunction srust&quot;&gt;that_must_not_be_interrupted&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
.await&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It could also exist as a language feature, which would additionally allow removing &lt;code class=&apos;scode&apos;&gt;.await&lt;/code&gt; if that is desired. Either way, the effect is the same: this proposal easily enables writing futures that are guaranteed to not have cancellation points. Personally I do not think this use case is common enough to warrant a language feature, but it is still definitely worth considering.&lt;/p&gt;</content></entry><entry><title>Building this site</title><id>https://sabrinajewson.org/blog/building-this-site</id><updated>2022-03-09T00:00:00+00:00</updated><link href="https://sabrinajewson.org/blog/building-this-site" rel="alternate" type="text/html" title="Building this site"/><published>2022-03-09T00:00:00+00:00</published><content xml:base="https://sabrinajewson.org/blog/building-this-site" type="html">&lt;p&gt;Since I’ve spent the past few days working on creating this website, I thought I’d make good use of the effort by documenting my experiences here.&lt;/p&gt;&lt;p&gt;I got the idea to create a website from a desire to have a place to write blog posts. Initially I had plans on just making GitHub gists and sharing them on Reddit or something, but I (thankfully) decided against that since a site allows for much more flexibility.&lt;/p&gt;&lt;p&gt;To avoid having to maintain a web server myself, I’m just using GitHub Pages to host it (but on a custom domain to make the URL shorter). I also decided against using a static site generator since it’s a lot more fun to build it myself.&lt;/p&gt;&lt;h2 id=&apos;the-build-system&apos;&gt;&lt;a href=&apos;#the-build-system&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;The build system&lt;/h2&gt;&lt;p&gt;I’m not going to write the HTML for this manually, so I needed to decide on a build system to use. I briefly considered existing options like Make, &lt;a href=&apos;https://gulpjs.com/&apos;&gt;Gulp&lt;/a&gt; or &lt;a href=&apos;https://sagiegurari.github.io/cargo-make/&apos;&gt;cargo-make&lt;/a&gt; but eventually decided to write my own thing in Rust.&lt;/p&gt;&lt;p&gt;The requirements I had for it were this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Does the minimum amount of work possible between rebuilds.&lt;/li&gt;&lt;li&gt;Has a “watch mode” that can be enabled with zero extra configuration to watch the directory for changes and automatically rebuild when they happen.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;After some thinking and a few failed attempts, I had devised quite a neat solution: the &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt; trait. The core API is this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta strait srust&quot;&gt;&lt;span class=&quot;sstorage stype strait srust&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;sentity sname strait srust&quot;&gt;Asset&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta senum srust&quot;&gt;&lt;span class=&quot;sstorage stype senum srust&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;sentity sname senum srust&quot;&gt;Modified&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    Never&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
    At&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt; represents a resource in the generation process: a text file being read, a JSON file being parsed, an HTML file being generated, an image being tranformed, et cetera. It has two main capabilities: calling &lt;code class=&apos;scode&apos;&gt;generate&lt;/code&gt; to do the (potentially expensive) work to actually produce the value, and calling &lt;code class=&apos;scode&apos;&gt;modified&lt;/code&gt; to cheaply compute the time at which that value was last modified.&lt;/p&gt;&lt;p&gt;The &lt;code class=&apos;scode&apos;&gt;Modified&lt;/code&gt; enum is mostly just a &lt;code class=&apos;scode&apos;&gt;SystemTime&lt;/code&gt; but also has a special variant &lt;code class=&apos;scode&apos;&gt;Never&lt;/code&gt; to represent a time before all &lt;code class=&apos;scode&apos;&gt;SystemTime&lt;/code&gt;s, which is used for when getting the modification time fails (e.g. a deleted/non-existent file) or when the asset’s value is a constant.&lt;/p&gt;&lt;p&gt;The three most basic implementors of this trait are &lt;code class=&apos;scode&apos;&gt;Constant&lt;/code&gt;, &lt;code class=&apos;scode&apos;&gt;Dynamic&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;FsPath&lt;/code&gt;, representing a constant value, a dynamic but immutable value (typically command-line arguments) and a value sourced from a filesystem path’s modification time respectively. Their implementations are pretty much as you’d expect:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Constant&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;T&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Clone&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Asset &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Constant&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; T&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Never &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;sconstant snumeric sfloat srust&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Dynamic&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;created&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; SystemTime,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Dynamic&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; T&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; created &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;SystemTime&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;now&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; created&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; value &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Clone&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Asset &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Dynamic&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; T&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;At&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.created&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.value.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;FsPath&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;P&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Asset &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;FsPath&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;P&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;symlink_metadata&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;and_then&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;metadata.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Never&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;At&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code class=&apos;scode&apos;&gt;FsPath&lt;/code&gt; is intentionally agnostic over how the actual path is read, allowing you to many different functions depending on the actual nature of the path (whether it’s a binary file, text file, JSON file, directory, et cetera).&lt;/p&gt;&lt;p&gt;With these base types there are then many combinators you can apply. One basic one is &lt;code class=&apos;scode&apos;&gt;all&lt;/code&gt;, which combines multiple &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt;s into one for when a resulting asset is generated from more than one input file (such as this HTML file, which is generated from the source markdown and a template). It works on all kinds of containers of multiple assets including tuples and vectors. Example usage looks like:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;asset&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;all&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;foo_asset&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; bar_asset&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
	.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;foo_value&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable sparameter srust&quot;&gt;bar_value&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;scomment sblock srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;/*&lt;/span&gt; use both `foo_value` and `bar_value` &lt;span class=&quot;spunctuation sdefinition scomment srust&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Its &lt;code class=&apos;scode&apos;&gt;modified&lt;/code&gt; implementation takes the latest modification time of all the inner assets, and its &lt;code class=&apos;scode&apos;&gt;generate&lt;/code&gt; implementation just forwards to the generation code of each one then packages them all up together in a tuple. However, you might notice a problem here: with the code above, if &lt;code class=&apos;scode&apos;&gt;bar&lt;/code&gt; is changed but &lt;code class=&apos;scode&apos;&gt;foo&lt;/code&gt; isn’t then both &lt;code class=&apos;scode&apos;&gt;foo&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code class=&apos;scode&apos;&gt;bar&lt;/code&gt; are regenerated even if only &lt;code class=&apos;scode&apos;&gt;bar&lt;/code&gt; actually needs to be.&lt;/p&gt;&lt;p&gt;This is where another combinator comes in: &lt;code class=&apos;scode&apos;&gt;Cache&lt;/code&gt;. It provides an in-memory cache of the output’s value (as long as it is &lt;code class=&apos;scode&apos;&gt;Clone&lt;/code&gt;), allowing cases like the above to simply use the cached value of &lt;code class=&apos;scode&apos;&gt;foo&lt;/code&gt; instead of regenerating it from scratch.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Asset&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;asset&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; A,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;cached&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Cell&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;Option&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;Modified, &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Asset&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Asset &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;skeyword sother srust&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; Clone,
&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;A&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Output&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; inner_modified &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;last_modified&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; output&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;
            .cached
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;last_modified&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; _&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;last_modified &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; inner_modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap_or_else&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;inner_modified&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.cached.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport stype srust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;last_modified&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; output.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        output
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the code snippet above, the &lt;code class=&apos;scode&apos;&gt;generate&lt;/code&gt; function of &lt;code class=&apos;scode&apos;&gt;Cache&lt;/code&gt; will first attempt to use the cached value instead of regenerating the asset if the inner asset hasn’t been modified since the cache was taken.&lt;/p&gt;&lt;p&gt;Another place where &lt;code class=&apos;scode&apos;&gt;Cache&lt;/code&gt; is useful is when an asset is shared between multiple output assets (like how my “blog post template” asset is shared with every blog post), and &lt;code class=&apos;scode&apos;&gt;Cache&lt;/code&gt; can be applied to avoid regenerating the shared asset every time.&lt;/p&gt;&lt;p&gt;The last combinator I will talk about here is called &lt;code class=&apos;scode&apos;&gt;ModifiesPath&lt;/code&gt;, and it is perhaps the most important one. You can apply it to an asset that as a side-effect makes changes to a path on the filesystem, and it allows that asset to avoid rerunning itself when the asset’s age is older than the path it modifies.&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;ModifiesPath&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, P&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;asset&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; A,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; P,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;sstorage stype simpl srust&quot;&gt;impl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Asset&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Output = &lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, P&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;AsRef&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Path&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; Asset &lt;span class=&quot;skeyword sother srust&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt; &lt;span class=&quot;sentity sname simpl srust&quot;&gt;ModifiesPath&lt;/span&gt;&lt;span class=&quot;smeta sgeneric srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;A, P&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta simpl srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype stype srust&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;sentity sname stype srust&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; Modified&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;symlink_metadata&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;and_then&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;metadata.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
            .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map_or&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Never&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;At&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;&lt;span class=&quot;sstorage stype srust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Output&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; output_modified &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; output_modified
			&lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sconstant sother srust&quot;&gt;EXE_MODIFIED&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; output_modified
		&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;svariable slanguage srust&quot;&gt;self&lt;/span&gt;.asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
        &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;sstorage stype srust&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;sconstant sother srust&quot;&gt;EXE_MODIFIED&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Lazy&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Modified&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;Lazy&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; time &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;env&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;current_exe&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;and_then&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;symlink_metadata&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;and_then&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;svariable sparameter srust&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;metadata.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modified&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap_or_else&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;_&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;SystemTime&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;now&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;smeta spath srust&quot;&gt;Modified&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;At&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;time&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is this combinator that allows the Make-like behaviour of comparing ages of input and output files and only rebuilding when necessary.&lt;/p&gt;&lt;p&gt;The other thing &lt;code class=&apos;scode&apos;&gt;ModifiesPath&lt;/code&gt; does is takes into account the age of the executable it is running in, forcing a rebuild if the executable itself has been changed since the output was last generated. This is very useful during development to avoid situations where you need to manually remove the destination directory to force assets to be rebuilt.&lt;/p&gt;&lt;p&gt;The combination of all these features forms a very powerful build system implemented in simple Rust code. For example, suppose I wanted to make a build script that copies over &lt;code class=&apos;scode&apos;&gt;source.txt&lt;/code&gt; to &lt;code class=&apos;scode&apos;&gt;destination.txt&lt;/code&gt;. That would look like this:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; asset &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;source_to_dest&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;source_to_dest&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; impl &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Asset&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Output = &lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;smeta spath srust&quot;&gt;asset&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FsPath&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;source.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; res &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;fs&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;copy&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;source.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;destination.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;skeyword scontrol srust&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ssupport stype srust&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;e&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; res &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;smeta spath srust&quot;&gt;log&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;error&lt;span class=&quot;skeyword soperator srust&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;error copying files: {e}&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
			&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
		&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
		.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modifies_path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;destination.txt&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And just like that, we have automatic tracking of dependencies done for free. Now suppose I wanted to add a “watch” mode that waits for changes to &lt;code class=&apos;scode&apos;&gt;source.txt&lt;/code&gt; to happen and copies it over again. Absolutely no changes to the &lt;code class=&apos;scode&apos;&gt;source_to_dest&lt;/code&gt; function are needed, all we have to do is layer some code using &lt;a href=&apos;https://github.com/notify-rs/notify&apos;&gt;&lt;code class=&apos;scode&apos;&gt;notify&lt;/code&gt;&lt;/a&gt; on top of that:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; asset &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ssupport sfunction srust&quot;&gt;source_to_dest&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;events_sender&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; events&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;crossbeam_channel&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;bounded&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sconstant snumeric sinteger sdecimal srust&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;sstorage smodifier srust&quot;&gt;mut&lt;/span&gt; watcher &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;notify&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;recommended_watcher&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;events_sender&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	watcher.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;.&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;as_ref&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta spath srust&quot;&gt;notify&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;RecursiveMode&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Recursive&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;skeyword scontrol srust&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;sstorage stype srust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;skeyword soperator srust&quot;&gt;=&lt;/span&gt; events.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;recv&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
		asset.&lt;span class=&quot;ssupport sfunction srust&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator srust&quot;&gt;;&lt;/span&gt;
	&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And there we are, everything is handled automatically from that point onward. Due to the in-memory caching and on-disk comparison that assets usually perform it ends up being pretty efficient, doing close to the minimum amount of work necessary between rebuilds. It could theoretically be improved if the &lt;em&gt;contents&lt;/em&gt; of the &lt;code class=&apos;scode&apos;&gt;notify::Event&lt;/code&gt;s were actually paid attention to instead of having to repeatedly call &lt;code class=&apos;scode&apos;&gt;fs::symlink_metadata&lt;/code&gt; a bunch, but I haven’t had a need to implement that just yet.&lt;/p&gt;&lt;p&gt;So there it is, a powerful and flexible build system implemented and configured from just Rust code. I haven’t bothered to release it as a crate at all - if someone asks me to I might but I don’t know if it would be useful to anyone else, or if something like this already exists in the ecosystem. But I’m sharing it because I think it’s quite a neat solution to this particular problem.&lt;/p&gt;&lt;h2 id=&apos;the-markdown-renderer&apos;&gt;&lt;a href=&apos;#the-markdown-renderer&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;The Markdown renderer&lt;/h2&gt;&lt;p&gt;The heart of this ad-hoc site generator is really the Markdown renderer. It’s what converts the Markdown files that I write the posts in into the HTML being rendered right now by your web browser. So it’s fitting for us to start there.&lt;/p&gt;&lt;p&gt;A markdown renderer consists of two main parts: the first stage that parses the source strings into a more code-friendly format, and the second stage that generates the HTML from the abstract Rust representation produced by the parser.&lt;/p&gt;&lt;p&gt;I don’t enjoy writing parsers, so I decided to shell out to an external crate for that. I chose &lt;a href=&apos;https://docs.rs/pulldown_cmark&apos;&gt;&lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt;&lt;/a&gt; because it is widely used, has a flexible API and supports a bunch of features that I really like (CommonMark + tables + smart quotes + heading IDs).&lt;/p&gt;&lt;p&gt;While &lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt; does come with its own HTML generator and I could’ve just used that and called it a day, there are a bunch of features and additions I would like to implement that would be far easier if I could control generation myself rather than trying to modify the HTML AST after-the-fact.&lt;/p&gt;&lt;p&gt;So, taking inspiration from &lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt;’s HTML renderer, I resolved to write my own. It works by walking once through all the events emitted by &lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt;’s &lt;code class=&apos;scode&apos;&gt;Parser&lt;/code&gt; struct and keeping track of state along the way in a gigantic &lt;code class=&apos;scode&apos;&gt;Renderer&lt;/code&gt; type. Once the tree walk is finished, it runs a bit of finalization before dumping its relevant fields in the resulting &lt;code class=&apos;scode&apos;&gt;Markdown&lt;/code&gt; struct:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sstorage stype sstruct srust&quot;&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;sentity sname sstruct srust&quot;&gt;Markdown&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sstruct srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; String,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; String,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; String,
    &lt;span class=&quot;svariable sother smember srust&quot;&gt;outline&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;:&lt;/span&gt; String,
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Looking at these fields, you can probably tell why I didn’t just use the default HTML generator - there’s a lot of custom functionality in there not provided by plain &lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt;. &lt;code class=&apos;scode&apos;&gt;title&lt;/code&gt; contains the title of the page, &lt;code class=&apos;scode&apos;&gt;body&lt;/code&gt; contains the body HTML (but excluding the title), &lt;code class=&apos;scode&apos;&gt;summary&lt;/code&gt; contains the un-HTML-ified first paragraph of the content (this is used to put in each page’s &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;description&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; tags) and &lt;code class=&apos;scode&apos;&gt;outline&lt;/code&gt; is the automatically generated table of contents you can see at the top of this page.&lt;/p&gt;&lt;p&gt;Another reason I wanted to write my own HTML renderer is to enable syntax highlighting - by default &lt;code class=&apos;scode&apos;&gt;pulldown_cmark&lt;/code&gt; puts all code into plain &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sblock sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sblock sany shtml&quot;&gt;pre&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; elements, but I wanted to transform it with build-time syntax highlighting instead to enable the pretty colours you can see in the code I write.&lt;/p&gt;&lt;p&gt;I chose the &lt;a href=&apos;https://github.com/trishume/syntect&apos;&gt;&lt;code class=&apos;scode&apos;&gt;syntect&lt;/code&gt;&lt;/a&gt; crate to do the highlighting, since it’s widely used and has the features I need. It turned out to be pretty simple to add this functionality; I just embed the syntax definitions in the source code and load it in a lazy static, then use a &lt;a href=&apos;https://docs.rs/syntect/4/syntect/html/struct.ClassedHTMLGenerator.html&apos;&gt;&lt;code class=&apos;scode&apos;&gt;ClassedHTMLGenerator&lt;/code&gt;&lt;/a&gt; to produce the actual HTML. The themes can be loaded separately by loading them at runtime in an &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt;, converting them to CSS then concatenating with the CSS file for blog posts.&lt;/p&gt;&lt;p&gt;And that’s pretty much all there is to it: a single pure function that goes from markdown source to rendered HTML, to be later inserted into whichever document needs it. Actually, speaking of inserting it into documents, how &lt;em&gt;does&lt;/em&gt; that work?&lt;/p&gt;&lt;h2 id=&apos;templating&apos;&gt;&lt;a href=&apos;#templating&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Templating&lt;/h2&gt;&lt;p&gt;Unfortunately it’s not enough to just take rendered HTML, stick it in a &lt;code class=&apos;scode&apos;&gt;.html&lt;/code&gt; file and call it a day. I need to add an HTML skeleton around it to add the document title, &lt;a href=&apos;#adding-the-favicon&apos;&gt;favicon&lt;/a&gt;, metadata and sitewide navigation links you can see on this page.&lt;/p&gt;&lt;p&gt;Initially, I had written &lt;a href=&apos;https://github.com/SabrinaJewson/sabrinajewson.github.io/blob/2df2918523de279720a5854b658864c92fe0671a/builder/src/util/template.rs&apos;&gt;my own custom templater&lt;/a&gt; for this. It was barely even a templater really, being so ridiculously minimal: just ~100 lines of code that replaced &lt;code class=&apos;scode&apos;&gt;\{variable_name}&lt;/code&gt; with its contents. But as the project continued to grow I realized that I needed a better solution than that, so I decided to switch to a full-fledged templating library.&lt;/p&gt;&lt;p&gt;I chose &lt;a href=&apos;https://docs.rs/handlebars&apos;&gt;&lt;code class=&apos;scode&apos;&gt;handlebars&lt;/code&gt;&lt;/a&gt; for this, not for any particular reason, but I wanted to try it out since I’ve only used Tera before. I used my &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt; system to create an asset that loads all the common “fragment” templates from an &lt;code class=&apos;scode&apos;&gt;include/&lt;/code&gt; directory as well as individual &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt;s for each template per page, then I combined them together and rendered it all to produce the final pages.&lt;/p&gt;&lt;p&gt;The template system turned out to be pretty powerful and definitely worth the extra dependency. I’m able to automatically generate pretty much everything automatically, like my &lt;a href=&apos;.&apos;&gt;list of blog posts&lt;/a&gt; whose content is sourced from the Markdown files only. Additionally, all the HTML boilerplate used repeatedly in every page can be abstracted to &lt;a href=&apos;https://github.com/SabrinaJewson/sabrinajewson.github.io/blob/fa55487a0d9bd3ee46d68fa51ea32d9a2eaa2772/template/include/base.hbs&apos;&gt;a common file&lt;/a&gt; which turned out to be very useful for code reuse.&lt;/p&gt;&lt;h2 id=&apos;minification&apos;&gt;&lt;a href=&apos;#minification&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Minification&lt;/h2&gt;&lt;p&gt;To reduce page load times, I decided to minify all my HTML and CSS before writing each asset to its final file. I know that there exist minifiers for this in native Rust, but realistically all the state-of-the-art ones are in JavaScript. I ended up choosing &lt;a href=&apos;https://github.com/terser/html-minifier-terser&apos;&gt;html-minifier-terser&lt;/a&gt; and &lt;a href=&apos;https://clean-css.github.io/&apos;&gt;clean-css&lt;/a&gt; for this, which both seem to be well-maintained and have small output sizes.&lt;/p&gt;&lt;p&gt;Initially I planned on achieving maximum efficiency by using both projects as a library and starting up a single long-running Node process that I communicate with via IPC, to avoid the inefficiencies of starting up a whole new Node instance each time I wanted to minify something. But that plan ended up falling apart rather quickly, since I totally lack experience with Node and just couldn’t figure out how to get it to work. Maybe it’s just me but Node’s &lt;a href=&apos;https://nodejs.org/api/stream.html#readable-streams&apos;&gt;readable stream&lt;/a&gt; interface seems a million times more complicated and hard to use than Rust’s &lt;code class=&apos;scode&apos;&gt;AsyncRead&lt;/code&gt; - it has four (!) separate ways of using the API of which none are as simple as just &lt;code class=&apos;scode&apos;&gt;read_exact&lt;/code&gt;. And it doesn’t help that I despise writing JavaScript altogether - TypeScript makes it somewhat better but in comparison to Rust it’s just painful.&lt;/p&gt;&lt;p&gt;So with that plan scrapped, it was just a matter of calling into their CLIs each time (which luckily both libraries have). To avoid global dependencies I created a local npm package that uses both packages as a dependency. Then I could simply have a &lt;code class=&apos;scode&apos;&gt;std::process::Command&lt;/code&gt; run &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npx&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; html-minifier-terser&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; or &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npx&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; cleancss&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; in that package’s directory and pipe through my files to have them minified.&lt;/p&gt;&lt;p&gt;The one issue I encountered is that unlike Cargo, npm doesn’t automatically install required dependencies before trying to run code. This means that in order to successfully build my website from a freshly cloned repository, you would’ve had to manually &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;ssupport sfunction scd sshell&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; to the package directory and run &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npm&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; beforehand - obviously not ideal.&lt;/p&gt;&lt;p&gt;My first solution to this was just to run that command first thing whenever the building binary starts up. But since &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npm&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is slow, it ends up slowing down the whole building process quite a significant amount since I have to wait for it each time. What I really needed was a way to only run the command when it hasn’t been run yet, or when the &lt;code class=&apos;scode&apos;&gt;package.json&lt;/code&gt; changes. Lucky, my whole &lt;code class=&apos;scode&apos;&gt;Asset&lt;/code&gt; system is just perfect for that - I could simply define an asset that runs &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npm&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; with &lt;code class=&apos;scode&apos;&gt;package.json&lt;/code&gt; specified as its input file and &lt;code class=&apos;scode&apos;&gt;package-lock.json&lt;/code&gt; as the output one (since &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;npm&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; always updates its modification date). It ended up just being a couple lines of code:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;ssource srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;sstorage stype sfunction srust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;sentity sname sfunction srust&quot;&gt;asset&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt; &lt;span class=&quot;smeta sfunction sreturn-type srust&quot;&gt;&lt;span class=&quot;spunctuation sseparator srust&quot;&gt;-&amp;gt;&lt;/span&gt; impl &lt;span class=&quot;smeta sgeneric srust&quot;&gt;Asset&lt;span class=&quot;spunctuation sdefinition sgeneric sbegin srust&quot;&gt;&amp;lt;&lt;/span&gt;Output = &lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition sgeneric send srust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction srust&quot;&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock sbegin srust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;smeta spath srust&quot;&gt;asset&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta spath srust&quot;&gt;FsPath&lt;span class=&quot;spunctuation saccessor srust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;./builder/js/package.json&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
        .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sparameters sbegin srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;smeta sfunction sparameters srust&quot;&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sparameters send srust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;smeta sfunction sclosure srust&quot;&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;log_errors&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ssupport sfunction srust&quot;&gt;npm_install&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
        .&lt;span class=&quot;ssupport sfunction srust&quot;&gt;modifies_path&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin srust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble srust&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin srust&quot;&gt;&amp;quot;&lt;/span&gt;./builder/js/package-lock.json&lt;span class=&quot;spunctuation sdefinition sstring send srust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup send srust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;smeta sblock srust&quot;&gt;&lt;span class=&quot;spunctuation ssection sblock send srust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And now I have the best of both worlds: fast building as well as automatic package setup.&lt;/p&gt;&lt;h2 id=&apos;adding-a-dark-theme&apos;&gt;&lt;a href=&apos;#adding-a-dark-theme&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Adding a dark theme&lt;/h2&gt;&lt;p&gt;One specific goal I had for this site was to allow it to work in both light and dark modes, depending on the user’s chosen &lt;code class=&apos;scode&apos;&gt;prefers-color-scheme&lt;/code&gt; setting. I was mildly dreading having to write out two large stylesheets with a different colour palette for each mode, but as it turns out modern browsers have a built-in way to change the default color scheme based on the user’s current &lt;code class=&apos;scode&apos;&gt;prefers-color-scheme&lt;/code&gt; value. All I had to do was add one &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; to my &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sstructure sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sstructure sany shtml&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt;&lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;color-scheme&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;dark light&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And everything magically worked first try - if &lt;code class=&apos;scode&apos;&gt;prefers-color-scheme&lt;/code&gt; was &lt;code class=&apos;scode&apos;&gt;dark&lt;/code&gt;, the page would show a black background with consistently white text and if it was &lt;code class=&apos;scode&apos;&gt;light&lt;/code&gt; it would show a white background with consistently black text. You can try it out now - if you open developer tools and press ctrl+shift+p, you should be able to enable the “emulate CSS prefers-color-scheme: dark/light” option and see how the website changes. And all that’s done entirely by the browser’s default styles. Who knew it was so easy?&lt;/p&gt;&lt;p&gt;The only time I did have to mess with &lt;code class=&apos;scode&apos;&gt;prefers-color-scheme&lt;/code&gt; media queries was for the code blocks. That was easy though, I just wrote out the dark theme CSS then wrapped the light version in &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource scss&quot;&gt;&lt;span class=&quot;smeta sat-rule smedia scss&quot;&gt; &lt;span class=&quot;skeyword scontrol sat-rule smedia scss&quot;&gt;&lt;span class=&quot;spunctuation sdefinition skeyword scss&quot;&gt;@&lt;/span&gt;media&lt;/span&gt; &lt;span class=&quot;spunctuation sdefinition sgroup sbegin scss&quot;&gt;(&lt;/span&gt;prefers-&lt;span class=&quot;ssupport stype sproperty-name smedia scss&quot;&gt;color&lt;/span&gt;-scheme&lt;span class=&quot;spunctuation sseparator skey-value scss&quot;&gt;:&lt;/span&gt; light&lt;span class=&quot;spunctuation sdefinition sgroup send scss&quot;&gt;)&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;spunctuation ssection sproperty-list scss&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=&apos;adding-the-favicon&apos;&gt;&lt;a href=&apos;#adding-the-favicon&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Adding the favicon&lt;/h2&gt;&lt;p&gt;The favicon of this site is automatically generated by the build script from a single &lt;code class=&apos;scode&apos;&gt;.png&lt;/code&gt; file in source control. I use the &lt;a href=&apos;https://docs.rs/image&apos;&gt;&lt;code class=&apos;scode&apos;&gt;image&lt;/code&gt;&lt;/a&gt; crate to read in this source image, then resize it to generate two files:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;favicon.ico&lt;/code&gt;, which contains 16x16, 32x32 and 64x64 versions of the icon all packed into a single &lt;code class=&apos;scode&apos;&gt;.ico&lt;/code&gt; file.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;apple-touch-icon.png&lt;/code&gt;, which has been resized to 180x180 as is suitable for an apple touch icon.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The paths of these files are then passed in to the templates, which include them in &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt; &lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; tags in the head:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt;&lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;icon&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;/{{icons.favicon}}&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;smeta stag sinline sany shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sinline sany shtml&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;apple-touch-icon&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sentity sother sattribute-name shtml&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator skey-value shtml&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sattribute-with-value shtml&quot;&gt;&lt;span class=&quot;sstring squoted sdouble shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin shtml&quot;&gt;&amp;quot;&lt;/span&gt;/{{icons.apple_touch_icon}}&lt;span class=&quot;spunctuation sdefinition sstring send shtml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I’m especially proud of this part of the code because the entire thing is implemented in &amp;lt;100 lines of logic and is far, far more convenient than manually using a site like &lt;a href=&apos;https://realfavicongenerator.net/&apos;&gt;RealFaviconGenerator&lt;/a&gt; to generate each of the files. The only downside of it is that &lt;a href=&apos;https://docs.rs/image&apos;&gt;&lt;code class=&apos;scode&apos;&gt;image&lt;/code&gt;&lt;/a&gt; is ridiculously slow in debug mode, so I end up running the build process in &lt;code class=&apos;scode&apos;&gt;--release&lt;/code&gt; all the time 😄.&lt;/p&gt;&lt;h2 id=&apos;a-live-reloading-dev-server&apos;&gt;&lt;a href=&apos;#a-live-reloading-dev-server&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;A live-reloading dev server&lt;/h2&gt;&lt;p&gt;For a long time I was previewing the website by just opening the file in the browser as a &lt;code class=&apos;scode&apos;&gt;file://&lt;/code&gt; URL. But this had several disadvantages:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Paths like &lt;code class=&apos;scode&apos;&gt;/favicon.ico&lt;/code&gt; would be resolved relative to the filesystem root, rather than the website root.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;index.html&lt;/code&gt; wasn’t automatically added to the end of paths if they pointed to directories and that file existed. I’d instead see a screen showing a file listing of the directory and have to click &lt;code class=&apos;scode&apos;&gt;index.html&lt;/code&gt; manually each time.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;.html&lt;/code&gt; wasn’t automatically added to the end of paths like &lt;code class=&apos;scode&apos;&gt;/blog/foo&lt;/code&gt;, making my links broken.&lt;/li&gt;&lt;li&gt;404 links did not show my custom &lt;code class=&apos;scode&apos;&gt;404.html&lt;/code&gt; page.&lt;/li&gt;&lt;li&gt;I didn’t get live reloading.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;At some point I switched to &lt;code class=&apos;scode&apos;&gt;&lt;span class=&quot;ssource sshell sbash&quot;&gt; &lt;span class=&quot;smeta sfunction-call sshell&quot;&gt;&lt;span class=&quot;svariable sfunction sshell&quot;&gt;python&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sarguments sshell&quot;&gt;&lt;span class=&quot;svariable sparameter soption sshell&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sparameter sshell&quot;&gt; -&lt;/span&gt;m&lt;/span&gt; http.server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; and that solved issues (1) and (2) but not the others. So eventually I’d had enough and decided to write my own server with all these features, in Rust.&lt;/p&gt;&lt;p&gt;Since the server doesn’t need to be particularly complex, I decided to just use plain &lt;a href=&apos;https://docs.rs/hyper&apos;&gt;hyper&lt;/a&gt; - no higher-level framework or anything. And it doesn’t need performance, so I’m only using Tokio’s current thread runtime instead of the heavier multi-threaded scheduler.&lt;/p&gt;&lt;p&gt;The server’s main job is to take a request path and map it to a path on the filesystem, which it does just by splitting on &lt;code class=&apos;scode&apos;&gt;/&lt;/code&gt; and reconstructing a &lt;code class=&apos;scode&apos;&gt;PathBuf&lt;/code&gt;. I also have some extra logic to solve problems (2) and (3) - adding &lt;code class=&apos;scode&apos;&gt;index.html&lt;/code&gt; and &lt;code class=&apos;scode&apos;&gt;.html&lt;/code&gt; to paths as a fallback if the requested path doesn’t exist. I guess the MIME type to serve based on file extension, which works fine for me, and also set &lt;code class=&apos;scode&apos;&gt;Cache-Control: no-cache&lt;/code&gt; to avoid having the browser cache the pages.&lt;/p&gt;&lt;p&gt;To achieve live reloading, two things need to be coordinated. First, the server has to expose an endpoint that allows the browser to wait for a change to happen to any of the files it’s viewing - I do this via a &lt;code class=&apos;scode&apos;&gt;/watch&lt;/code&gt; endpoint that accepts a list of paths to watch in its query parameters (decoded with &lt;a href=&apos;https://docs.rs/form_urlencoded&apos;&gt;&lt;code class=&apos;scode&apos;&gt;form_urlencoded&lt;/code&gt;&lt;/a&gt;) and gives back an SSE stream that sends an empty event once something happens. Internally this is implemented with a Tokio &lt;code class=&apos;scode&apos;&gt;broadcast&lt;/code&gt; channel of &lt;code class=&apos;scode&apos;&gt;notify::Event&lt;/code&gt;s, and a spawned task that subscribes to the channel and checks whether any of the events apply to it, sending an SSE event if so. Secondly, the client needs to produce a list of all the files it depends on and then send that in the SSE request to the server, reloading once it receives any data over that connection.&lt;/p&gt;&lt;p&gt;I do all that by passing in a boolean property &lt;code class=&apos;scode&apos;&gt;live_reload&lt;/code&gt; to the templates, and only enable it when the server is running (this is easy since the server and build process share the same binary). The page will build up a set of dependencies in a &lt;code class=&apos;scode&apos;&gt;URLSearchParams&lt;/code&gt; object then send off the request like so:&lt;/p&gt;&lt;pre class=&apos;scode&apos;&gt;&lt;code&gt;&lt;span class=&quot;stext shtml sbasic&quot;&gt;{{#if live_reload}}
&lt;span class=&quot;smeta stag sscript sbegin shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sentity sname stag sscript shtml&quot;&gt;script&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta stag sscript sbegin shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;ssource sjs sembedded shtml&quot;&gt;&lt;span class=&quot;ssource sjs&quot;&gt;	&lt;span class=&quot;sstorage stype sjs&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;svariable sother sreadwrite sjs&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;skeyword soperator sassignment sjs&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;smeta sinstance sconstructor sjs&quot;&gt;&lt;span class=&quot;skeyword soperator sword snew sjs&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call sconstructor sjs&quot;&gt; &lt;span class=&quot;svariable stype sjs&quot;&gt;EventSource&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring stemplate sjs&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring stemplate sbegin sjs&quot;&gt;`&lt;/span&gt;/watch?&lt;/span&gt;&lt;span class=&quot;smeta stemplate sexpression sjs&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stemplate-expression sbegin sjs&quot;&gt;${&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta stemplate sexpression sjs&quot;&gt;&lt;span class=&quot;ssource sjs sembedded sexpression&quot;&gt;&lt;span class=&quot;svariable sother sreadwrite sjs&quot;&gt;params&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stemplate-expression send sjs&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sstring stemplate sjs&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring stemplate send sjs&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator sstatement sjs&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;svariable sother sobject sjs&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor sjs&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call smethod sjs&quot;&gt;&lt;span class=&quot;svariable sfunction sjs&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sstring squoted sdouble sjs&quot;&gt;&lt;span class=&quot;spunctuation sdefinition sstring sbegin sjs&quot;&gt;&amp;quot;&lt;/span&gt;message&lt;span class=&quot;spunctuation sdefinition sstring send sjs&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sseparator scomma sjs&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;smeta sfunction sdeclaration sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sbegin sjs&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;spunctuation ssection sgroup send sjs&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;smeta sfunction sdeclaration sjs&quot;&gt; &lt;/span&gt;&lt;span class=&quot;sstorage stype sfunction sarrow sjs&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;smeta sblock sjs&quot;&gt;&lt;span class=&quot;svariable sother sobject sjs&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;spunctuation saccessor sjs&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;smeta sfunction-call smethod sjs&quot;&gt;&lt;span class=&quot;svariable sfunction sjs&quot;&gt;reload&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta sgroup sjs&quot;&gt;&lt;span class=&quot;spunctuation ssection sgroup sjs&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;spunctuation sterminator sstatement sjs&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;smeta stag sscript send shtml&quot;&gt;&lt;span class=&quot;spunctuation sdefinition stag sbegin shtml&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;sentity sname stag sscript shtml&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;spunctuation sdefinition stag send shtml&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
{{/if}}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And just like that, we have live reloading. Whenever I edit one of the source files like the one I’m writing, a whole chain of automated events is set off, culminating in the reload of the page I’m viewing in-browser:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The &lt;code class=&apos;scode&apos;&gt;notify&lt;/code&gt; watcher sees the event and regenerates the main asset.&lt;/li&gt;&lt;li&gt;The main asset generates the “blog posts” asset.&lt;/li&gt;&lt;li&gt;The “blog posts” asset generates the asset for this blog post.&lt;/li&gt;&lt;li&gt;This asset compares the dates of its input and output files, and upon seeing that the input file is newer than the output file decides to regenerate itself.&lt;/li&gt;&lt;li&gt;The updated blog post HTML is written out to the &lt;code class=&apos;scode&apos;&gt;dist/&lt;/code&gt; directory.&lt;/li&gt;&lt;li&gt;The &lt;code class=&apos;scode&apos;&gt;notify&lt;/code&gt; watcher sees the event and passes it over to the server’s broadcast channel.&lt;/li&gt;&lt;li&gt;The task spawned to manage the connnection to the site receives the event from the channel, and upon checking what paths it affects decides that the web page should reload.&lt;/li&gt;&lt;li&gt;The task sends an SSE event to the website which it then receives.&lt;/li&gt;&lt;li&gt;The website reloads, sending a new request to the server and receiving the updated blog post HTML.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&apos;conclusion&apos;&gt;&lt;a href=&apos;#conclusion&apos; class=&apos;anchor&apos;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Overall, I am extremely pleased with how this whole project has turned out. I now have my own personal website, designed in exactly the way I like it able to support exactly the workflow that I like, with almost everything completely automated with the power of code.&lt;/p&gt;&lt;p&gt;Do I recommend it if you want to start your own website? Not really, unless you’d do this sort of programming project anyway. All in all it took about a week to set up, and I was working on it for several hours each day. I can probably imagine that using an existing static site generator is a thousand times easier and faster and produces just as good output. But it was an extremely fun project for me do so I can definitely recommend it in that sense.&lt;/p&gt;&lt;p&gt;If you want to check out the actual code it’s &lt;a href=&apos;https://github.com/SabrinaJewson/sabrinajewson.github.io&apos;&gt;on GitHub&lt;/a&gt; and contains all the things I talked about here, as well as some more mundane stuff I left out the article for brevity. Its file structure is located into three main folders:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;builder&lt;/code&gt;, which contains the Rust source code of the crate that builds the site and runs the server.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;template&lt;/code&gt;, which contains Handlebars templates, CSS, code themes and various other dynamic configuration parts related to the site.&lt;/li&gt;&lt;li&gt;&lt;code class=&apos;scode&apos;&gt;src&lt;/code&gt;, which contains the source Markdown of the posts I’ve written as well as the favicon of the website.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Anyway, I really hope you enjoyed reading this post and maybe learnt something you found interesting. See you next time!&lt;/p&gt;</content></entry></feed>