Thank you for explaining - now that you've pointed it out, I can see that this is just another form of the "graphs are hard in Rust" problem that I've encountered before.
However, I still stand by my point - Rust might be bad at graphs, but I believe that a well-designed language with a borrow checker (maybe something closer to Lobster, which automatically inserts RC cells when you try to multiply mutable borrow[1] - something obviously more correct than what Rust does, I'm not sure how they messed that one up) wouldn't necessarily have to be.
The problem is that Rc<> is not replacement for GC, in GC language you just don't care about having multiple mutable references at all because it's mem-safe (so you don't need to panic). The only thing you can get is concurrency issue but that's often fine for isolated algorithms (where you do mutex at the top and don't care from there or you just send the whole thing to the worker using channel). Rust is placing restrictions on your code not because it's bad code but because it cannot prove it's safe. Yeah so you can mark it as unsafe but you can also switch to a different language and have a happy rest of life.
Do you mean a Rust Rc<> or a generic "borrow-checked language" Rc<>? In the former case, yes, I absolutely agree that Rust is not ideal. However, my argument is about a theoretical language with a borrow-checker, in which case - why isn't something like Lobster sufficient, which automatically detects when you have multiple owners and inserts reference counting under the hood?
Among other things, the article you linked explicitly mentions that it does not solve one of the major problems with using Rc<T>, which is that it does not handle cycles.
It sounds like a more ergonomic system that has the same technical shortcomings.
Ah, ok, having cycles is another problem, also hard, but my point was about multiple mutable references which is not a safety problem if you have GC. You only get race conditions.
And I think it could/should work also with Rc<> but for some reason, rust authors decided it's important to write everything as if it was multi-threaded even if it's single-threaded now (so it can be easily turned to multi-threaded later).
And that's cool but it adds a lot of burden to developers. I am probably missing something, there is likely a good reason for this, as always, but it doesn't change the point, rust is super-complicated for hobby stuff and you have to think about irrelevant things, hence for me, it is low-level language (with generics and macros and very cool builtin unit testing but it's still low-level)
And by irrelevant I don't mean mem-safety, that IS important for me, I rather mean worrying about race-conditions in a single-threaded code :)
However, I still stand by my point - Rust might be bad at graphs, but I believe that a well-designed language with a borrow checker (maybe something closer to Lobster, which automatically inserts RC cells when you try to multiply mutable borrow[1] - something obviously more correct than what Rust does, I'm not sure how they messed that one up) wouldn't necessarily have to be.
[1] https://aardappel.github.io/lobster/memory_management.html