<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h" -->

---
title: Why 'externalized' proofs of cyclic trait impls does not...
description: A Rust language design post examines two theoretical approaches for how the compiler verifies that supertrait obligations hold: 'modular' proofs, where an impl...
canonical: https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Why 'externalized' proofs of cyclic trait impls does not work · baby steps | daily.dev
og:description: A Rust language design post examines two theoretical approaches for how the compiler verifies that supertrait obligations hold: 'modular' proofs, where an impl...
og:url: https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h
og:image: https://api.daily.dev/og/posts/tn1hJ5I9h.png
og:image:alt: Why 'externalized' proofs of cyclic trait impls does not work · baby steps
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Why 'externalized' proofs of cyclic trait impls does not work · baby steps

**[Niko Matsakis - baby steps](https://daily.dev/sources/babysteps)** · 8 min read · 0 upvotes · 0 comments

## Summary

A Rust language design post examines two theoretical approaches for how the compiler verifies that supertrait obligations hold: 'modular' proofs, where an impl itself must prove its supertraits are satisfied, versus 'external' proofs, where the caller of the impl bears that responsibility. The author, previously favoring external proofs for their expressiveness, explains why they ultimately fail: they are incompatible with how unsafe impls work in Rust, since unsafe impls are trusted to prove their own safety conditions, creating an inconsistency if ordinary impls aren't trusted to prove supertrait conditions. The conclusion is that modular proofs, despite requiring careful handling of cyclic/recursive proof issues, are the only viable path forward, with coinductive modular proofs to be covered in a future post.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://smallcultfollowing.com/babysteps/blog/2026/10/10/modular-vs-external-proofs>

## Questions this post answers

### What is the difference between modular proofs and external proofs for supertrait obligations in Rust's trait system?

Modular proofs require an impl itself to prove its supertrait obligations hold, so other code can trust the impl without re-checking; external proofs instead require the caller of the impl to separately verify that supertraits are satisfied, treating the impl's claim as only a shallow fact. External proofs seemed more expressive initially but were found incompatible with Rust's unsafe trait design, since unsafe impls are trusted to prove their own safety conditions.

_Rust contributors tracking trait system design debates can follow this reasoning on daily.dev._

### Why can't external proofs of supertrait obligations work in Rust's trait system?

External proofs break down because they conflict with how unsafe impls function in Rust: an unsafe impl is trusted to prove its own safety conditions hold, so other code relies on it without re-verification. If ordinary impls cannot be trusted to establish their supertrait obligations under an external proof system, that creates an inconsistency with the trust already placed in unsafe impls, which is why modular proofs are concluded to be the only viable option.

_Developers following Rust's internal design decisions can track this kind of language-soundness discussion on daily.dev._

## Similar posts on daily.dev

- [Cylic trait implementations: motivation · baby steps](https://daily.dev/posts/cylic-trait-implementations-motivation-baby-steps-l7pv7oob0) · Niko Matsakis - baby steps · 2 upvotes · 0 comments
- [Rust's next-generation trait solver](https://daily.dev/posts/rust-s-next-generation-trait-solver-nvu0dw5xn) · Lobsters · 0 upvotes · 0 comments
- [Torturing rustc by Emulating HKTs, Causing an Inductive Cycle and Borking the Compiler — ramblings of @harudagondi](https://daily.dev/posts/torturing-rustc-by-emulating-hkts-causing-an-inductive-cycle-and-borking-the-compiler-ramblings-o-suhn8dtob) · Lobsters · 2 upvotes · 1 comments
- [Practical Rust API Design](https://daily.dev/posts/practical-rust-api-design-qwmqrnfyi) · corrode · 51 upvotes · 7 comments
- [Memory Safety Absolutists](https://daily.dev/posts/memory-safety-absolutists-sufigv3zl) · Hacker News · 1 upvotes · 0 comments

---

Tags: [#rust](https://daily.dev/tags/rust)

[View this post on daily.dev](https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Why 'externalized' proofs of cyclic trait impls does not work · baby steps","url":"https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h"},"datePublished":"2026-10-10T15:36:48.133Z","dateModified":"2026-10-10T15:37:09.711Z","description":"A Rust language design post examines two theoretical approaches for how the compiler verifies that supertrait obligations hold: 'modular' proofs, where an impl...","image":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","thumbnailUrl":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","isAccessibleForFree":true,"articleSection":"Niko Matsakis - baby steps","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Niko Matsakis - baby steps","logo":"https://media.daily.dev/image/upload/logos/placeholder.jpg","url":"https://daily.dev/sources/babysteps"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"rust","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Niko Matsakis - baby steps","item":"https://daily.dev/sources/babysteps"},{"@type":"ListItem","position":3,"name":"Why 'externalized' proofs of cyclic trait impls does not work · baby steps"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/why-externalized-proofs-of-cyclic-trait-impls-does-not-work-baby-steps-tn1hj5i9h#faq","mainEntity":[{"@type":"Question","name":"What is the difference between modular proofs and external proofs for supertrait obligations in Rust's trait system?","acceptedAnswer":{"@type":"Answer","text":"Modular proofs require an impl itself to prove its supertrait obligations hold, so other code can trust the impl without re-checking; external proofs instead require the caller of the impl to separately verify that supertraits are satisfied, treating the impl's claim as only a shallow fact. External proofs seemed more expressive initially but were found incompatible with Rust's unsafe trait design, since unsafe impls are trusted to prove their own safety conditions. Rust contributors tracking trait system design debates can follow this reasoning on daily.dev."}},{"@type":"Question","name":"Why can't external proofs of supertrait obligations work in Rust's trait system?","acceptedAnswer":{"@type":"Answer","text":"External proofs break down because they conflict with how unsafe impls function in Rust: an unsafe impl is trusted to prove its own safety conditions hold, so other code relies on it without re-verification. If ordinary impls cannot be trusted to establish their supertrait obligations under an external proof system, that creates an inconsistency with the trust already placed in unsafe impls, which is why modular proofs are concluded to be the only viable option. Developers following Rust's internal design decisions can track this kind of language-soundness discussion on daily.dev."}}]}
```

