diff --git a/.idea/misc.xml b/.idea/misc.xml
index 98a09f5..55c8377 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -27,6 +27,7 @@
+
diff --git a/.idea/rust.iml b/.idea/rust.iml
index c67cafa..8165c4c 100644
--- a/.idea/rust.iml
+++ b/.idea/rust.iml
@@ -110,6 +110,10 @@
+
+
+
+
@@ -130,6 +134,7 @@
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 1799341..c6ba616 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,7 +5,6 @@
-
@@ -15,24 +14,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
@@ -108,6 +94,7 @@
+
@@ -141,12 +128,12 @@
-
+
-
+
@@ -180,7 +167,7 @@
-
+
@@ -208,7 +195,7 @@
-
+
@@ -237,6 +224,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -247,16 +244,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -286,11 +273,11 @@
+
-
@@ -330,8 +317,8 @@
-
-
+
+
@@ -339,7 +326,7 @@
-
+
@@ -749,9 +736,16 @@
+
+
+
+
+
+
+
-
+
@@ -760,10 +754,10 @@
-
+
-
-
+
+
diff --git a/reference_cycles/Cargo.toml b/reference_cycles/Cargo.toml
new file mode 100644
index 0000000..47ce1bc
--- /dev/null
+++ b/reference_cycles/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "reference_cycles"
+version = "0.1.0"
+authors = ["Timothy Warren "]
+edition = "2018"
+
+[dependencies]
diff --git a/reference_cycles/src/main.rs b/reference_cycles/src/main.rs
new file mode 100644
index 0000000..be8ce31
--- /dev/null
+++ b/reference_cycles/src/main.rs
@@ -0,0 +1,98 @@
+use std::rc::{Rc, Weak};
+use std::cell::RefCell;
+use List::{Cons, Nil};
+
+#[derive(Debug)]
+enum List {
+ Cons(i32, RefCell>),
+ Nil,
+}
+
+impl List {
+ fn tail(&self) -> Option<&RefCell>> {
+ match self {
+ Cons(_, item) => Some(item),
+ Nil => None,
+ }
+ }
+}
+
+fn cycle_example() {
+ let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
+
+ println!("a initial rc count = {}", Rc::strong_count(&a));
+ println!("a next item = {:?}", a.tail());
+
+ let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
+
+ println!("a rc count after b creation = {}", Rc::strong_count(&a));
+ println!("b initial rc count = {}", Rc::strong_count(&b));
+ println!("b next item = {:?}", b.tail());
+
+ if let Some(link) = a.tail() {
+ *link.borrow_mut() = Rc::clone(&b);
+ }
+
+ println!("b rc count after changing a = {}", Rc::strong_count(&b));
+ println!("a rc count after changing a = {}", Rc::strong_count(&a));
+
+ // Uncomment the next line to see that we have a cycle;
+ // it will overflow the stack
+ // println!("a next item = {:?}", a.tail());
+}
+
+#[derive(Debug)]
+struct Node {
+ value: i32,
+ parent: RefCell>,
+ children: RefCell>>,
+}
+
+fn weakref_example() {
+ let leaf = Rc::new(Node {
+ value: 3,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![]),
+ });
+
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+
+ {
+ let branch = Rc::new(Node {
+ value: 5,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![Rc::clone(&leaf)]),
+ });
+
+ *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
+
+ println!(
+ "branch strong = {}, weak = {}",
+ Rc::strong_count(&branch),
+ Rc::weak_count(&branch),
+ );
+
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+ }
+
+ println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+}
+
+fn main() {
+ cycle_example();
+
+ weakref_example();
+}