Abstract

In this post I explain why Rust's borrow checker is not a garbage collector.

Rust's Borrow Checker Is Not a Garbage Collector

It is a commonly heard proposition that "Rust's Borrow Checker is like/plainly a Garbage Collector". Although Rust has some things close to a garbage collector, the borrow checker is not one of them.

The Borrow Checker Just Checks

A garbage collector keeps track of resources at runtime and reclaims what is unreachable. Even if we remove the "runtime" word from this definition, the borrow checker is not a garbage collector because:

  1. It does not reclaim anything.
  2. It does not keep track of what is unreachable.
  3. The borrow checker just checks if your code is following the borrowing rules estabilished by the language.

Drop Rules and Semi-Automatic Resource Management

Although the borrow checker is not a garbage collector, resource management is not completely manual in Rust. We have Drop which automatically run some deinitialization function at the end of the scope. But here is the gotcha: it is not a garbage collector because drop rules are deterministic and it will always run at the end of the scope. If the resource is moved, so does the dropping. The programmer is the one who specifies when resource will be deallocated, although some help is given.

This is what allows us, for instance, to rely on Drop to close resources like file handles. Some garbage collected languages (such as J@va) cannot rely on destructors for resource reclamation. Their garbage collector only helps with memory reclamation. Despite all of this, there is something in Rust close to a garbage collector.

Reference Counters

In Rust we have the reference counters Rc and Arc. Just like garbage collectors, they keep track of data at runtime and in most cases resource reclamation is non-deterministic. We continue to be able of relying on them to close file handles, but it is not easy to predict exactly when resource reclamation will happen (specially for Arc). Some people consider reference counting a kind of garbage collector and some not (because of stuff like unresolved cyclic references). In any case they have some relation to garbage collection.

The beauty of Rc and Arc in Rust is that they are plain library types, there is no compiler magic. They interact with the borrow checker gracefully, but still the borrow checker does not say anything about the resource reclamation. It just checks if your clone of Rc lives long enough. In fact, it is what it does for anything: it just checks!