<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Creusot Devlog</title>
    <link rel="self" type="application/atom+xml" href="https://devlog.creusot.rs/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://devlog.creusot.rs/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-02-24T00:00:00+00:00</updated>
    <id>https://devlog.creusot.rs/atom.xml</id>
    <entry xml:lang="en">
        <title>Creusot 0.10.0: February update</title>
        <published>2026-02-24T00:00:00+00:00</published>
        <updated>2026-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://devlog.creusot.rs/2026-02-24/"/>
        <id>https://devlog.creusot.rs/2026-02-24/</id>
        
        <content type="html" xml:base="https://devlog.creusot.rs/2026-02-24/">&lt;h2 id=&quot;what-s-new-in-creusot&quot;&gt;What&#x27;s new in Creusot?&lt;&#x2F;h2&gt;
&lt;p&gt;This February&#x27;s release brings a couple of QOL improvements.
For the rest, see the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;creusot&#x2F;blob&#x2F;master&#x2F;CHANGELOG.md#0100---2026-02-24&quot;&gt;Changelog&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;assume-trusted-asserts&quot;&gt;Assume (trusted asserts)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;proof_assert!&lt;&#x2F;code&gt; macro now supports the &lt;code&gt;#[trusted]&lt;&#x2F;code&gt; attribute.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;trusted&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;proof_assert!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; answer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It removes the proof obligation that would come from the assertion,
so it effectively becomes an &lt;em&gt;assumption&lt;&#x2F;em&gt; available to
the rest of the program after it.&lt;&#x2F;p&gt;
&lt;p&gt;We could have called it &lt;code&gt;assume!&lt;&#x2F;code&gt; or &lt;code&gt;proof_assume!&lt;&#x2F;code&gt;,
but reusing &lt;code&gt;#[trusted]&lt;&#x2F;code&gt; makes it convenient to grep for all
assumptions in a project.&lt;&#x2F;p&gt;
&lt;p&gt;This is useful as a placeholder à la &lt;code&gt;todo!()&lt;&#x2F;code&gt;, letting you
stub out parts of a proof while you&#x27;re focusing on other aspects
of it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wildcard-patterns-on-integers&quot;&gt;Wildcard patterns on integers&lt;&#x2F;h3&gt;
&lt;p&gt;In &lt;code&gt;match&lt;&#x2F;code&gt; expressions with integer patterns,
the wildcard branch now remembers the values that
the integer does &lt;strong&gt;not&lt;&#x2F;strong&gt; equal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;    42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; proof_assert!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; proof_assert!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; },&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F; FIXED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Thanks to Eric Jackson for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;creusot&#x2F;pull&#x2F;1899&quot;&gt;the contribution&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multi-package-workspaces&quot;&gt;Multi-package workspaces&lt;&#x2F;h3&gt;
&lt;p&gt;We added options to select packages in workspaces.&lt;&#x2F;p&gt;
&lt;p&gt;The command line option &lt;code&gt;-p&lt;&#x2F;code&gt; (or &lt;code&gt;--package&lt;&#x2F;code&gt;) selects a package to build
with &lt;code&gt;cargo creusot&lt;&#x2F;code&gt; and to run provers on with &lt;code&gt;cargo creusot prove&lt;&#x2F;code&gt;.
This is basically the same option as in &lt;code&gt;cargo build&lt;&#x2F;code&gt;, but to call &lt;code&gt;why3find&lt;&#x2F;code&gt;
and run provers, we must additionally find the output Coma files corresponding
to these packages.&lt;&#x2F;p&gt;
&lt;p&gt;As the Creusot compiler is basically a modified &lt;code&gt;rustc&lt;&#x2F;code&gt;, the unit of compilation is a crate.
A package defines multiple crates, and &lt;code&gt;cargo&lt;&#x2F;code&gt; does not build all of them by default:
only libraries and binaries, excluding tests, examples, and benches.
Creusot only supports that default target selection for now (that is libraries and binaries),
until the need for others arises.&lt;&#x2F;p&gt;
&lt;p&gt;You can also choose a default set of packages to build with &lt;code&gt;cargo creusot&lt;&#x2F;code&gt;,
using the &lt;code&gt;default-member&lt;&#x2F;code&gt; field in the &lt;code&gt;[workspace.metadata.creusot]&lt;&#x2F;code&gt;
section of your workspace &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;workspace.metadata.creusot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;default-members&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;PKG1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;PKG2&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This falls back to the existing &lt;code&gt;default-member&lt;&#x2F;code&gt; field in &lt;code&gt;[workspace]&lt;&#x2F;code&gt;
for regular &lt;code&gt;cargo build&lt;&#x2F;code&gt;. Having a separate field for Creusot lets you
designate packages specifically as targets for formal verification,
next to other buildable but unverified packages.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;story-of-a-toolchain-update&quot;&gt;Story of a toolchain update&lt;&#x2F;h3&gt;
&lt;p&gt;Creusot depends on a nightly Rust toolchain. With this release,
we upgraded our toolchain from nightly-2025-11-13 to nightly-2026-01-29.&lt;&#x2F;p&gt;
&lt;p&gt;We do toolchain upgrades regularly to keep up with the fast-moving
&lt;code&gt;rustc&lt;&#x2F;code&gt; API. Ideally we do this at the beginning of each release cycle
to give time to potentially subtle issues to surface by the next release.&lt;&#x2F;p&gt;
&lt;p&gt;This time, there was one change that required a bit of thinking to deal with:
the orphan check now panics when it encounters an unnameable type
(typically, a function type).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-orphan-check-and-unnameable-types&quot;&gt;The orphan check and unnameable types&lt;&#x2F;h4&gt;
&lt;p&gt;The orphan check is what enforces &quot;trait coherence&quot; in Rust: that there is at most
one implementation of a trait for any given type. The orphan check basically answers
the question &quot;might another crate implement this trait &lt;code&gt;Tr&lt;&#x2F;code&gt; for this type &lt;code&gt;Ty&lt;&#x2F;code&gt;?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;code&gt;rustc&lt;&#x2F;code&gt;, this check is performed whenever you implement a trait.
Since you must spell out the type for the &lt;code&gt;impl&lt;&#x2F;code&gt; block,
there is normally no way to encounter an unnameable type there
(unnameable types are types of functions, closures, and coroutines).
However &lt;code&gt;rustc&lt;&#x2F;code&gt; did have an experimental feature &quot;&lt;code&gt;typeof&lt;&#x2F;code&gt;&quot; which could
cause the orphan check to encounter unnameable types, allegedly
(I&#x27;m not familiar with the details).
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;148256&quot;&gt;That feature was removed&lt;&#x2F;a&gt;
in late November, and the now unreachable code in the orphan check
that dealt with unnameable types was replaced with panics.&lt;&#x2F;p&gt;
&lt;p&gt;In Creusot, we use the orphan check in the implementation of &lt;em&gt;type invariants&lt;&#x2F;em&gt;.
This feature lets you specify a property that should be satisfied by all values of a type.
For example, you can define a type of integers bounded by 42 as a &lt;code&gt;struct&lt;&#x2F;code&gt; with
an &lt;code&gt;Invariant&lt;&#x2F;code&gt; impl:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Bounded42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Bounded42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;logic&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;        pearlite!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; }&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All functions that take a &lt;code&gt;Bounded42&lt;&#x2F;code&gt; argument can assume the type invariant,
and all functions that return a &lt;code&gt;Bounded42&lt;&#x2F;code&gt; must prove the type invariant.&lt;&#x2F;p&gt;
&lt;p&gt;Any type &lt;code&gt;Ty&lt;&#x2F;code&gt; has a type invariant, which we determine as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if there is an instance &lt;code&gt;Ty: Invariant&lt;&#x2F;code&gt;, that is a &lt;em&gt;user-provided&lt;&#x2F;em&gt; type invariant;&lt;&#x2F;li&gt;
&lt;li&gt;if there is definitely no such instance, then we fall back to a &lt;em&gt;structural&lt;&#x2F;em&gt; type invariant
derived from the type definition (it basically says that all fields satisfy
their type invariant);&lt;&#x2F;li&gt;
&lt;li&gt;if there is no instance &lt;code&gt;Ty: Invariant&lt;&#x2F;code&gt; in this context,
but we cannot rule it out definitely
(an instance may appear after instantiating some type variables,
possibly using implementations provided by an unknown crate),
then the type invariant is an undefined predicate.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The orphan check is what distinguishes between the last two cases.
Furthermore, because type invariants apply to all types, this also concerns
unnameable types: for example if you pass a closure as an argument to a function,
then Creusot will look for its type invariant, involving an orphan check.&lt;&#x2F;p&gt;
&lt;p&gt;The update to the orphan check caused it to panic in this case.&lt;&#x2F;p&gt;
&lt;p&gt;The fix is simple in hindsight: we replace unnameable types (function types)
with the unit type &lt;code&gt;()&lt;&#x2F;code&gt; before invoking the orphan check.
Indeed, these types should behave the same as far as the orphan check
is concerned: both the unit type and function types from the current crate
or its dependencies are &quot;external types&quot; from the point of view of a
sibling or descendant crate.&lt;&#x2F;p&gt;
&lt;p&gt;It is also possible to fix the orphan check in &lt;code&gt;rustc&lt;&#x2F;code&gt; itself to not
panic in those cases even though they don&#x27;t happen within &lt;code&gt;rustc&lt;&#x2F;code&gt;.
But our workaround works and we just don&#x27;t have an incentive to tinker
with it further, at least until that becomes a bigger issue.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creusot 0.9.0: Launching the Creusot Devlog</title>
        <published>2026-01-19T00:00:00+00:00</published>
        <updated>2026-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://devlog.creusot.rs/2026-01-19/"/>
        <id>https://devlog.creusot.rs/2026-01-19/</id>
        
        <content type="html" xml:base="https://devlog.creusot.rs/2026-01-19/">&lt;h2 id=&quot;begin-devlog&quot;&gt;Begin Devlog&lt;&#x2F;h2&gt;
&lt;p&gt;Welcome to the Creusot Devlog, where we blog about the development of Creusot project,
a deductive verifier for Rust.
Creusot helps you verify that your code is safe from panics,
overflows, and assertion failures, and also that it correctly implements
its formal specification (pre- and post-conditions).&lt;&#x2F;p&gt;
&lt;p&gt;The plan is to have posts accompany our &lt;strong&gt;monthly releases&lt;&#x2F;strong&gt;, highlighting key features
and writing about happenings in and around Creusot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creusot-at-popl&quot;&gt;Creusot at POPL&lt;&#x2F;h2&gt;
&lt;p&gt;Last week, the Creusot Team went to POPL 2026, a major academic PL conference.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We presented a tutorial on Creusot. &lt;a href=&quot;https:&#x2F;&#x2F;devlog.creusot.rs&#x2F;2026-01-19&#x2F;#creusot-tutorial&quot;&gt;More details below.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Arnaud Golfouse gave a talk at the CPP workshop (Certified Programs and Proofs):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Using Ghost Ownership to Verify Union-Find and Persistent Arrays in Rust&lt;&#x2F;em&gt;,
by Arnaud Golfouse, Armaël Guéneau, Jacques-Henri Jourdan
(&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal.science&#x2F;hal-05396946v1&#x2F;&quot;&gt;paper on HAL&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;live&#x2F;EkLFghhbRjg?t=29000s&quot;&gt;talk on Youtube (at 8h03m)&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;upcoming-events&quot;&gt;Upcoming events&lt;&#x2F;h3&gt;
&lt;p&gt;One more Creusot paper will appear in JFLA 2026, a French-speaking academic conference taking place next week. This paper is about verifying an implementation of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;abs&#x2F;pii&#x2F;0020019079900681&quot;&gt;a tricky tree traversal algorithm&lt;&#x2F;a&gt; (see also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Threaded_binary_tree&quot;&gt;&lt;em&gt;Threaded binary tree&lt;&#x2F;em&gt; on Wikipedia&lt;&#x2F;a&gt;) using Creusot:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Boucler la boucle du parcours de Morris&lt;&#x2F;em&gt;, by Arnaud Golfouse and Paul Patault (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cnrs.hal.science&#x2F;LMF&#x2F;hal-05428049v1&quot;&gt;paper on HAL&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenodo.org&#x2F;records&#x2F;17914344&quot;&gt;code on Zenodo&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also next week, Li-yao Xia will give another presentation of Creusot at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rust-formal-methods.github.io&#x2F;&quot;&gt;RFMIG meeting
(Rust Formal Methods Interest Group)&lt;&#x2F;a&gt;, online, on Monday, January 26 at 18:00 GMT (19:00 in France). It will focus on a work-in-progress case study:
verifying slice methods in Rust&#x27;s core library.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-new-in-creusot&quot;&gt;What&#x27;s new in Creusot?&lt;&#x2F;h2&gt;
&lt;p&gt;Creusot 0.9.0 was released earlier this month, right before the start of POPL.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creusot-tutorial&quot;&gt;Creusot Tutorial&lt;&#x2F;h3&gt;
&lt;p&gt;The Creusot tutorial walks you through the process of verifying a Rust program with Creusot.
The tutorial is available in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial&quot;&gt;the &lt;code&gt;creusot-rs&#x2F;tutorial&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;.
You don&#x27;t even need to install anything: you can try Creusot online in your browser! See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial#readme&quot;&gt;README&lt;&#x2F;a&gt; for more details.&lt;&#x2F;p&gt;
&lt;p&gt;This uses a DevContainer, made possible by recently added support for installing Creusot with Nix.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contents-of-the-tutorial&quot;&gt;Contents of the tutorial&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial&#x2F;blob&#x2F;main&#x2F;src&#x2F;ex0_examples.rs&quot;&gt;A gallery of small examples&lt;&#x2F;a&gt; illustrating Creusot&#x27;s main features.&lt;&#x2F;li&gt;
&lt;li&gt;Exercise 1: Gnome sort (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;guide.creusot.rs&#x2F;tutorial&#x2F;gnome_sort.html&quot;&gt;exercise&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial&#x2F;blob&#x2F;main&#x2F;src&#x2F;ex1_gnome_sort.rs&quot;&gt;code&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Exercise 2: Linked lists (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;guide.creusot.rs&#x2F;tutorial&#x2F;linked_list.html&quot;&gt;exercise&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial&#x2F;blob&#x2F;main&#x2F;src&#x2F;ex2_linked_list.rs&quot;&gt;code&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;infer-trivial-loop-invariants&quot;&gt;Infer trivial loop invariants&lt;&#x2F;h3&gt;
&lt;p&gt;This is a convenience enhancement for type invariants.&lt;&#x2F;p&gt;
&lt;p&gt;A type invariant is a property that all values of a type should satisfy.
This is a natural way to encode well-formedness conditions of many data structures.&lt;&#x2F;p&gt;
&lt;p&gt;For example, below is a type of &quot;ordered pairs&quot;, &lt;code&gt;OPair&lt;&#x2F;code&gt;,
with the type invariant that its fields are indeed ordered.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;&#x2F;&#x2F; Ordered pairs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; OPair&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;pub u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; pub u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; OPair&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;logic&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;        pearlite!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By equipping a type with a type invariant,
every function whose interface involves that type will implicitly assert its type invariant
in the function&#x27;s preconditions and postconditions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;requires&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Implicit:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F; #[requires(inv(*self))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F; #[ensures(inv(^self))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; bump&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem arises when we use such a type in a loop. For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; bump_loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;bump&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In that loop, we call &lt;code&gt;self.bump&lt;&#x2F;code&gt;, which requires &lt;code&gt;self&lt;&#x2F;code&gt; to satisfy its type invariant.&lt;&#x2F;p&gt;
&lt;p&gt;Previously, we had to explicitly state the loop invariant, that the type invariant is preserved by each iteration of the loop body:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; bump_loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;inv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;bump&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This kind of condition easy to forget for newcomers,
and becomes quite cumbersome as more type invariants are involved.&lt;&#x2F;p&gt;
&lt;p&gt;Now this invariant is automatically inserted by Creusot.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s not all. It may still be desirable to write loops
that don&#x27;t preserve the type invariant—for example, in the initialization
of a complex data structure.&lt;&#x2F;p&gt;
&lt;p&gt;Although one might imagine a flag to toggle this behavior, we propose an
automatic but conservative solution that guesses right in most cases:
a type invariant is inserted in a loop invariant only if the last
write to a given variable before (re)entering the loop comes from
a function boundary.&lt;&#x2F;p&gt;
&lt;p&gt;For the example above,
&lt;code&gt;self&lt;&#x2F;code&gt; is written to by the caller of the function first, and then
by the &lt;code&gt;bump&lt;&#x2F;code&gt; method in the loop, both of which involve a type invariant assertion,
so we can safely insert that type invariant as a loop invariant.&lt;&#x2F;p&gt;
&lt;p&gt;For a counterexample, below we replaced the &lt;code&gt;bump&lt;&#x2F;code&gt; call with a direct
assignment to a field of &lt;code&gt;self&lt;&#x2F;code&gt;. Such assignments are not required to
preserve the type invariant of &lt;code&gt;self&lt;&#x2F;code&gt; in general (even though in this case it does).
Indeed, we expect field assignments to occur as part of the implementation
of a data structure, temporarily breaking type invariants.
Consequently, Creusot does not insert the type invariant implicitly in this case.
The user can still provide it if necessary.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; bump_loop_raw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;invariant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;inv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F; Must be explicit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creusot decides whether to insert such type invariants by performing
a little static analysis, a standard exercise in compiler writing.&lt;&#x2F;p&gt;
&lt;p&gt;This analysis also detects mutable variables that are not actually written to,
so that Creusot can also insert invariants that say &quot;this value hasn&#x27;t changed
since the beginning of the loop&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;renamed-creusot-std&quot;&gt;Renamed &lt;code&gt;creusot_std&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Creusot&#x27;s standard library has been renamed from &lt;code&gt;creusot_contracts&lt;&#x2F;code&gt;
to &lt;code&gt;creusot_std&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This library provides macros to enable writing contracts (&lt;code&gt;requires&lt;&#x2F;code&gt;, etc.),
and it also contains contracts for the Rust standard library, hence the
old name &lt;code&gt;creusot_contracts&lt;&#x2F;code&gt;. The new name &lt;code&gt;creusot_std&lt;&#x2F;code&gt; better conveys the
idea that it&#x27;s a fundamental library to be imported by all Creusot users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compatibility-with-no-std&quot;&gt;Compatibility with &lt;code&gt;no_std&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;creusot_std&lt;&#x2F;code&gt; library now features a flag &lt;code&gt;std&lt;&#x2F;code&gt; which can be disabled
for &lt;code&gt;no_std&lt;&#x2F;code&gt; projects. This is part of ongoing work to support the verification
of low-level embedded code.&lt;&#x2F;p&gt;
&lt;p&gt;Disabling &lt;code&gt;std&lt;&#x2F;code&gt; reduces the dependencies of &lt;code&gt;creusot_std&lt;&#x2F;code&gt; to &lt;code&gt;core&lt;&#x2F;code&gt; and &lt;code&gt;alloc&lt;&#x2F;code&gt;.
This removes contracts for a few data structures such as hashmaps.
In the future, it may be possible to avoid the dependency on &lt;code&gt;alloc&lt;&#x2F;code&gt; as well,
but it seems that most &lt;code&gt;no_std&lt;&#x2F;code&gt; projects also depend on &lt;code&gt;alloc&lt;&#x2F;code&gt; anyway.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;concurrency-atomic-invariants&quot;&gt;Concurrency: atomic invariants&lt;&#x2F;h3&gt;
&lt;p&gt;Creusot takes its first step in the formal verification of concurrent programs.
Our first working example is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;creusot&#x2F;blob&#x2F;6c46bc958029c2185e136ed7de15610ff69d027e&#x2F;tests&#x2F;should_succeed&#x2F;atomics&#x2F;parallel_add.rs&quot;&gt;&lt;code&gt;parallel_add&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
(for comparison, here is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;creusot-rs&#x2F;tutorial&#x2F;blob&#x2F;fe0cfc1691621f22d59a48ff357ff385a3689d34&#x2F;src&#x2F;ex3_parallel_add.rs#L29-L49&quot;&gt;the equivalent Rust code&lt;&#x2F;a&gt; without ghost annotations).&lt;&#x2F;p&gt;
&lt;p&gt;This builds on top of the aforementioned work on ghost ownership presented at CPP 2026.
For concurrency, this release makes two key additions to the &lt;code&gt;creusot_std&lt;&#x2F;code&gt; library:
the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.creusot.rs&#x2F;creusot_std&#x2F;std&#x2F;sync&#x2F;struct.AtomicI32.html&quot;&gt;&lt;code&gt;AtomicI32&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
type—a ghost-aware wrapper around &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;sync&#x2F;atomic&#x2F;struct.AtomicI32.html&quot;&gt;&lt;code&gt;std::sync::atomic::AtomicI32&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;—and
a notion of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.creusot.rs&#x2F;creusot_std&#x2F;ghost&#x2F;invariant&#x2F;struct.AtomicInvariant.html&quot;&gt;&lt;code&gt;AtomicInvariant&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iris-project.org&#x2F;&quot;&gt;Iris&lt;&#x2F;a&gt;, a separation logic framework in Rocq.
For now, this only supports sequential consistency. There is ongoing
work to also provide support for relaxed memory models.&lt;&#x2F;p&gt;
&lt;p&gt;Stay tuned for future updates on Creusot!&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
