Comment by Animats
Actual paper: [1]
This could be useful. I've been plugging away, on and off, on the concept of statically checked back-references for Rust. This is one of the biggest complaints that C/C++ people have about Rust - if A points to B, it's really hard to have a pointer from B to A. This leads to unsafe workarounds.
You can do it safely with Rc, RefCell, Weak, borrow(), borrow_mut(), upgrade(), and downgrade(). It's verbose, adds run-time overhead, and there's the potential of panicking at run time on a double borrow. But the expressive power is there. This is work in progress, and I have some notes here.[2]
The thing that's hard to check statically that borrows are disjoint as to scope. Borrows have lifetime scopes. If those lifetime scopes do not overlap, the borrows do not clash. Checking this across function calls is hard. (Checking across generic function calls is worse.) The Flowistry approach might help. The note that "Flowistry does not completely handle interior mutability" is a concern, because we're analyzing things that use RefCell.
The practical problem is to come up with a set of restrictions that are 1) sound, 2) checkable at compile time without too much compute effort, 3) allow programmers to do most of the legit things people want to do with back pointers, such as have a reference to the parent node in a tree, and 4) lead to usable diagnostic messages for problems.
[1] https://arxiv.org/abs/2111.13662
[2] https://github.com/John-Nagle/technotes/blob/main/docs/rust/...