<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9" -->

---
title: Other ways to make object soups in Rust | daily.dev
description: A deep dive into the various approaches for modeling object graphs ("object soups") in Rust, where multiple objects hold references to each other. The post...
canonical: https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Other ways to make object soups in Rust | daily.dev
og:description: A deep dive into the various approaches for modeling object graphs ("object soups") in Rust, where multiple objects hold references to each other. The post...
og:url: https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9
og:image: https://api.daily.dev/og/posts/VjgkcvpF9.png
og:image:alt: Other ways to make object soups in Rust
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.

# Other ways to make object soups in Rust

**[Collabora Blog](https://daily.dev/sources/collabora)** · 6 min read · 0 upvotes · 0 comments

## Summary

A deep dive into the various approaches for modeling object graphs ("object soups") in Rust, where multiple objects hold references to each other. The post compares C++ shared_ptr patterns with Rust equivalents, covering: plain Arc for immutable trees, tree expansion by duplication, Arc<Mutex<T>> for fully mutable graphs (with deadlock risks), and Rc<RefCell<T>> for single-threaded interior mutability (with panic risks). Each approach's trade-offs around safety, mutability, and correctness are explained, setting up a future discussion of the persian-rug crate as an alternative solution.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.collabora.com/news-and-blog/blog/2023/09/27/persian-rug-part-2-other-ways-to-make-object-soups-in-rust>

## Questions this post answers

### What are the trade-offs of using Arc<Mutex<T>> for a mutable object graph in Rust?

Arc<Mutex<T>> enables a fully mutable collection of objects with arbitrary links and no unchecked memory errors, but introduces serious deadlock risks. During traversal, each node requires acquiring its mutex, building a chain of held locks. Visiting the same node twice causes deadlock, and two threads acquiring locks in different orders also deadlock. In a dense object graph there is no obvious lock ordering to enforce.

_Rust developers navigating these trade-offs share patterns and pitfalls on daily.dev._

### Why can't I use Arc alone to model a bidirectional object graph in Rust?

Arc alone only supports immutable shared ownership. You can build immutable trees if nodes are constructed in the right order, and mutation is possible only when a single Arc to an object exists. As soon as you introduce bidirectional links — where multiple Arcs point to the same object — mutation becomes impossible, and no ordering of construction can represent every desired link.

_Developers working through Rust ownership challenges find relevant discussions on daily.dev._

### What is the difference between Mutex and RefCell for interior mutability in Rust?

Both allow obtaining a mutable reference through a shared reference, but they enforce Rust's aliasing rules differently. Mutex blocks the calling thread when another reference exists, making it suitable for multi-threaded use but prone to deadlock in graph traversal. RefCell panics at runtime if a mutable reference is requested while other references exist, and is single-threaded only (used with Rc rather than Arc).

_Teams choosing between concurrency primitives in Rust track these comparisons on daily.dev._

## Similar posts on daily.dev

- [Yet another Rust ownership tutorial](https://daily.dev/posts/yet-another-rust-ownership-tutorial-b8mdaw6qk) · A Java geek · 4 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
- [A look at Rust from 2012](https://daily.dev/posts/a-look-at-rust-from-2012-2wlds6cew) · Lobsters · 1 upvotes · 0 comments
- [Rust Ownership Under the Hood: How Rust Manages Memory Without a Garbage Collector](https://daily.dev/posts/rust-ownership-under-the-hood-how-rust-manages-memory-without-a-garbage-collector-iwyribsvw) · Medium · 0 upvotes · 0 comments

---

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

[View this post on daily.dev](https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9)

```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":"Other ways to make object soups in Rust","url":"https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9"},"datePublished":"2026-08-11T08:53:34.109Z","dateModified":"2026-08-11T09:12:52.439Z","description":"A deep dive into the various approaches for modeling object graphs (\"object soups\") in Rust, where multiple objects hold references to each other. The post...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8769562c6dc4f4b106cd6bee73b17bfa?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8769562c6dc4f4b106cd6bee73b17bfa?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Collabora Blog","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":"Collabora Blog","logo":"https://media.daily.dev/image/upload/s--ZGZ0FjqS--/f_auto,q_auto/v1786438306/logos/collabora?_a=BAMAMicg0","url":"https://daily.dev/sources/collabora"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"rust","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collabora Blog","item":"https://daily.dev/sources/collabora"},{"@type":"ListItem","position":3,"name":"Other ways to make object soups in Rust"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/other-ways-to-make-object-soups-in-rust-vjgkcvpf9#faq","mainEntity":[{"@type":"Question","name":"What are the trade-offs of using Arc<Mutex<T>> for a mutable object graph in Rust?","acceptedAnswer":{"@type":"Answer","text":"Arc<Mutex<T>> enables a fully mutable collection of objects with arbitrary links and no unchecked memory errors, but introduces serious deadlock risks. During traversal, each node requires acquiring its mutex, building a chain of held locks. Visiting the same node twice causes deadlock, and two threads acquiring locks in different orders also deadlock. In a dense object graph there is no obvious lock ordering to enforce. Rust developers navigating these trade-offs share patterns and pitfalls on daily.dev."}},{"@type":"Question","name":"Why can't I use Arc alone to model a bidirectional object graph in Rust?","acceptedAnswer":{"@type":"Answer","text":"Arc alone only supports immutable shared ownership. You can build immutable trees if nodes are constructed in the right order, and mutation is possible only when a single Arc to an object exists. As soon as you introduce bidirectional links — where multiple Arcs point to the same object — mutation becomes impossible, and no ordering of construction can represent every desired link. Developers working through Rust ownership challenges find relevant discussions on daily.dev."}},{"@type":"Question","name":"What is the difference between Mutex and RefCell for interior mutability in Rust?","acceptedAnswer":{"@type":"Answer","text":"Both allow obtaining a mutable reference through a shared reference, but they enforce Rust's aliasing rules differently. Mutex blocks the calling thread when another reference exists, making it suitable for multi-threaded use but prone to deadlock in graph traversal. RefCell panics at runtime if a mutable reference is requested while other references exist, and is single-threaded only (used with Rc rather than Arc). Teams choosing between concurrency primitives in Rust track these comparisons on daily.dev."}}]}
```

