This is tedious, though, and we would like the borrow checker to recognize patterns like this automatically. Luckily, Rust implements an improved borrow checker since version 1.31. Because it is not based on lexical scope for lifetime analysis anymore, these new lifetimes are called \acfi{NLL}. We will take a closer look at them in \autoref{subsec:non-lexical-lifetimes}.
\subsubsection{Access Guards}\todo{Put this in an info box?}
\subsubsection{Interior Mutability and Access Guards}
Sometimes we need access to a resource from multiple places at the same time, for example when sharing data between threads. For this, Rust provides the \inline{Mutex} container type. References to a mutex can be shared freely, but to change the value in the container, one has to acquire a lock, therefore making the access \emph{guarded}.\todo{Add example} While the mutex is locked, no other thread can access the data at all, a mutex lock is therefore similar to a \inline{&mut} but its guarantees are enforced at runtime. The\inline{RwLock}type can give out both read and write locks which have behavior analogous to \inline{&} and \inline{&mut}, respectively. There are more constructs for similar use cases in the standard library, like \inline{Arc} and \inline{Cow}.
The borrow rules are enforced at compile time, but sometimes the compiler can’t know if a piece of code follows the rules. Because of this, there is a runtime-checked version of reference with \inline{RefCell} which causes a panic if the borrow rules are broken. Also, sometimes we need access to a resource from multiple places at the same time, for example when sharing data between threads. For this, Rust provides the \inline{Mutex} container type. References to a mutex can be shared freely, but to change the value in the container, one has to acquire a lock, therefore making the access \emph{guarded}. While the mutex is locked, no other thread can access the data at all, as if the thread held a \inline{&mut}. Alternatively,\inline{RwLock} can give out both read and write locks which have behavior analogous to \inline{&} and \inline{&mut}, respectively. There are more constructs for similar use cases in the standard library, like \inline{Arc} and \inline{Cow}.
\todo[inline]{Cell, RefCell}
These data structures are implemented by using a superset of Rust, \emph{unsafe Rust}. The main feature of unsafe Rust is access to so-called \emph{raw pointers}. Raw pointers are, like pointers in C, not borrow checked by the compiler. Since borrow checking is undecidable, the compiler sometimes can’t prove that, for example, two references don’t alias. In these cases, the programmer can step in, prove the non-aliasing manually, implement a feature using raw pointers and provide a safe abstraction for consumers of the code.\todo{Pointers to Strict Provenance, Miri, …?}
These types are implemented using the \inline{Cell} type which can change a value even if it is not marked as mutable. This is called \emph{interior mutability} and uses \emph{unsafe Rust} internally, a superset of standard, safe Rust. The main feature of unsafe Rust is access to so-called \emph{raw pointers}. Raw pointers are, like pointers in C, not borrow checked by the compiler. Since borrow checking is undecidable, the compiler sometimes can’t prove that, for example, two references don’t alias. In these cases, the programmer can step in, prove the non-aliasing manually, implement a feature using raw pointers and provide a safe abstraction for consumers of the code.\todo{Pointers to Strict Provenance, Miri, …?}
\subsubsection{Returning references and Borrow-through}