Petri Net Model Synthesizes Provably Safe Rust Code From Formal Constraints
Researchers encode Rust's borrow-checker rules into a Petri net model that synthesizes call sequences guaranteed to compile without manual lifetime fixes.

Every Rust developer who has asked an LLM to write a function with non-trivial lifetime constraints knows the result: code that looks plausible until `rustc` disagrees, loudly, about every borrow. A preprint posted to arXiv this week targets that exact frustration with a formal answer: a model called Pushdown Colored Petri Nets, or PCPN, that encodes Rust's ownership and lifetime rules so thoroughly that any code it synthesizes satisfies the borrow checker by construction, not by iteration.
The PCPN model fuses two existing formalisms. Colored Petri nets attach "token colors" to represent data types and resource states, while a pushdown stack layer handles the entry and exit of lexical lifetime scopes, which are inherently nested in Rust. Transitions in the net fire only when both type compatibility and resource availability are satisfied, directly mirroring `rustc`'s compile-time checks: no borrow can outlive its owner, and exclusive mutable access cannot coexist with any other reference. The authors supply a bisimulation-style proof connecting PCPN firing rules to Rust's actual static checker, providing a theoretical guarantee rather than an empirical one.
The synthesis engine produces call sequences and small code fragments that traverse a provided API surface while satisfying those constraints. The authors' implementation, released alongside the preprint, demonstrated successful synthesis across a set of public APIs, and reported experiments found that every generated snippet compiled and type-checked without manual intervention. Not "compiled after minor fixes," but compiled, clean.
The model fits most naturally for patterns where resource ownership changes hands in well-defined sequences: state machines that acquire and release handles, protocol handlers that must consume a request before producing a response, and parser combinators where input lifetimes constrain output references. These are precisely the Rust patterns most likely to produce borrow-checker rejections in generated code, because they involve lifetime dependencies that span multiple call sites.

What the approach does not yet cover is where the practical interest lies for working developers. Generics add complexity the pushdown stack must track per instantiation, and higher-order lifetimes multiply the state space rapidly. The authors are explicit that scalability to large codebases is an open question: Petri nets are known to grow large when modeling many interacting resources simultaneously, and the pushdown component compounds that for heavily parameterized APIs. Industrial Rust code, with its trait objects, async lifetimes, and complex generic bounds, sits well outside what the current implementation targets.
That framing matters when comparing PCPN to the verification tools Rust developers already reach for. AWS's Kani verifier uses bounded model checking (via CBMC) to prove that existing Rust functions satisfy assertions for all valid inputs. Prusti, developed at ETH Zurich, and Creusot are deductive verifiers that require developers to annotate functions with preconditions and postconditions before checking them against a proof engine. Prusti uses separation logic while Creusot uses its prophecy model. All three tools are post-hoc: they analyze code you have already written. PCPN inverts that relationship, generating code that is safe before it ever reaches the compiler. For security-critical systems work, synthesis-by-construction is a meaningfully different guarantee.
The authors identify language server integration as the next target for the research, envisioning PCPN-powered suggestions that deliver compile-ready, borrow-checked completions rather than plausible-looking fragments that require manual triage. Whether the model's current state-space characteristics allow that at the scale of real-world crates is the question the Rust community will be watching.
Know something we missed? Have a correction or additional information?
Submit a Tip
