<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq" -->

---
title: 11 year old unsoundness bugs found in Rust borrow checker
description: A long-standing soundness bug in the Rust compiler allows a struct's lifetime requirements to be bypassed through covariant field assignment combined with a...
canonical: https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: 11 year old unsoundness bugs found in Rust borrow checker | daily.dev
og:description: A long-standing soundness bug in the Rust compiler allows a struct's lifetime requirements to be bypassed through covariant field assignment combined with a...
og:url: https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq
og:image: https://api.daily.dev/og/posts/lhmasseTq.png
og:image:alt: 11 year old unsoundness bugs found in Rust borrow checker
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.

# 11 year old unsoundness bugs found in Rust borrow checker

**[Hacker News](https://daily.dev/sources/hn)** · 2 min read · 0 upvotes · 0 comments

## Summary

A long-standing soundness bug in the Rust compiler allows a struct's lifetime requirements to be bypassed through covariant field assignment combined with a custom Drop implementation, enabling a value to outlive its actual lifetime. The minimal reproduction uses a static Mutex storing a Box<dyn Any + Send> and a struct with a 'static + Send bound; assigning a short-lived reference into the struct's field and letting Drop capture it smuggles the reference out, causing a use-after-scope bug confirmed by AddressSanitizer. Comment discussion traces the bug back as far as Rust 1.4 (2015) and 1.18.0 (2017), with the type system team flagging it as high priority (P-high) because it is an unsound hole that lets safe code trigger memory corruption without any unsafe blocks.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://github.com/rust-lang/rust/issues/164250>

## Questions this post answers

### What is the covariant field assignment soundness bug in the Rust compiler?

Assigning a short-lived reference into a generic struct field whose type parameter is bounded by 'static + Send, combined with a custom Drop implementation that moves the field's value into a static container, lets a reference escape its actual lifetime. The compiler accepts the code due to covariant variance not properly checking lifetime bounds during field assignment, producing a use-after-scope bug confirmed with AddressSanitizer. It has been reproducible since Rust 1.4.

_Rust developers relying on lifetime guarantees for memory safety can track how this compiler issue gets resolved via daily.dev._

## Community take

How the wider developer community reacted, aggregated from 1 discussion and 122 comments across hackernews (as of 2026-10-13).

**TL;DR:** The discussion turns into a long-running debate over whether this 11-year-old soundness bug means Rust isn't truly memory-safe, with most agreeing the bug is real and concerning but splitting sharply on whether it undermines Rust's safety claims or is just an expected, fixable implementation bug.

**Sentiment:** 15% positive · 35% mixed · 50% skeptical

**The case for**

- Some note that such a deeply-nested, rare bug going undetected for 11 years shows how uncommon it is to hit in practice.
- Several point out that soundness bugs are implementation defects that can and do get fixed, unlike fundamental language flaws.
- A few highlight that the type system team treats these issues seriously and actively works through a backlog of known soundness bugs.

**The pushback**

- Many argue the bug undermines claims that safe Rust code (without unsafe blocks) guarantees memory safety.
- Some dispute the framing that this is 'just a compiler bug' since Rust has no formal specification separate from the compiler, making the distinction meaningless.
- Commenters disagree on whether custom Drop implementations tied to generic lifetimes are common enough in real code to make this bug practically dangerous.
- Some worry that once documented, the bug pattern could be deliberately exploited by malicious actors in seemingly innocent code.

**By community**

- hackernews (heated): A large, contentious thread argues over whether this soundness bug invalidates Rust's memory-safety claims, with heavy back-and-forth between skeptics and defenders.

**Hottest debate:** Whether an unsoundness bug in the compiler counts as a flaw in 'the Rust language' versus merely a bug in its implementation that doesn't undermine the language's safety guarantees.

**Open questions**

- How many other undiscovered soundness bugs remain in the compiler, and how many affect real-world code?
- Is it feasible to fully formally verify Rust's type system and borrow checker given their complexity?
- How common are conditional Drop implementations tied to generic lifetime parameters in production code?

**Highlights**

> The heart of the matter:   struct Q<T: 'static>(Option<T>);   impl<T: 'static> Drop for Q<T> {     fn drop(&mut self) {         // Code in here has access to a non-'static &String         // but assumes that it's a &'static String     }   }   fn main() {     let l = String::new();     let mut q = Q(None);     q.0 = Some(&l);   } I wonder if the certified compiler for safety critical uses has the same issue.
> — [MrBuddyCasino on hackernews · 4 comments](https://news.ycombinator.com/item?id=50069796)

> Lifetimes can be effectively erased via covariant assignment.  It's in the title. Even a beginner could understand these assignments are not in spec? Are you just being contrary to be contrary?
> — [lkey on hackernews · 2 comments](https://news.ycombinator.com/item?id=50070137)

> No we're in a situation where a bug in the type checker was found and will be fixed and a new release will be made. That it took 11 years for someone to come across this is a fairly intense counterargument to your attempt to paint this as a language with dangerous footguns.
> — [cmrdporcupine on hackernews](https://news.ycombinator.com/item?id=50070644)

> I think the difference is here: - If a compiled C++ program has unsound behavior, the program needs to be fixed - If a compiled safe Rust program has unsound behavior, the compiler needs to be fixed
> — [\_flux on hackernews](https://news.ycombinator.com/item?id=50070927)

> This is not the first soundness bug. Some bugs aren't fixed for years. The Rust community is well aware that such bugs exist, will be found, and address them just like other high impact bugs. In other words, if you paid the slightest attention to the development of Rust language, you would know this is surprising but not unexpected, and has happened many times.
> — [fg137 on hackernews · 1 comments](https://news.ycombinator.com/item?id=50070385)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=50069499) · 223 points · 122 comments

## Similar posts on daily.dev

- [Move, Destruct, Forget, and Rust · baby steps](https://daily.dev/posts/move-destruct-forget-and-rust-baby-steps-xwxiulp3v) · Lobsters · 14 upvotes · 1 comments
- [Beyond Memory Safety: What Makes Rust Different – Lessons from Autonomous Robotics](https://daily.dev/posts/beyond-memory-safety-what-makes-rust-different-lessons-from-autonomous-robotics-ivljxogzh) · InfoQ · 0 upvotes · 0 comments
- [Async Rust: Pinning demystified](https://daily.dev/posts/async-rust-pinning-demystified-rfgkmdeya) · The New Stack · 2 upvotes · 0 comments
- [Yet another Rust ownership tutorial](https://daily.dev/posts/yet-another-rust-ownership-tutorial-b8mdaw6qk) · A Java geek · 4 upvotes · 1 comments

---

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

[View this post on daily.dev](https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq)

```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":"11 year old unsoundness bugs found in Rust borrow checker","url":"https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq"},"datePublished":"2026-10-13T11:44:45.672Z","dateModified":"2026-10-13T13:00:53.331Z","description":"A long-standing soundness bug in the Rust compiler allows a struct's lifetime requirements to be bypassed through covariant field assignment combined with a...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a0f1b078cbe08d322705540864b2085f?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a0f1b078cbe08d322705540864b2085f?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Hacker News","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":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"rust","timeRequired":"PT2M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"11 year old unsoundness bugs found in Rust borrow checker"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/11-year-old-unsoundness-bugs-found-in-rust-borrow-checker-lhmassetq#faq","mainEntity":[{"@type":"Question","name":"What is the covariant field assignment soundness bug in the Rust compiler?","acceptedAnswer":{"@type":"Answer","text":"Assigning a short-lived reference into a generic struct field whose type parameter is bounded by 'static + Send, combined with a custom Drop implementation that moves the field's value into a static container, lets a reference escape its actual lifetime. The compiler accepts the code due to covariant variance not properly checking lifetime bounds during field assignment, producing a use-after-scope bug confirmed with AddressSanitizer. It has been reproducible since Rust 1.4. Rust developers relying on lifetime guarantees for memory safety can track how this compiler issue gets resolved via daily.dev."}}]}
```

