If I may make a suggestion, really try to avoid going the constraint route as in Rust's lifetime tracking.
It is a pain to ensure it works as intended. A simple syntax directed algorithm (even in reverse ;) ) is preferable if you can get away with it. I guess the compatibility with Rust will end up forcing you into the constraint route though.
Big props to the group borrowing idea. It is similar to my own attempts (including the use of an explicit path rather then some generic lifetime parameter), but I never got the rules quite this clear.
In the other article you mentioned stability. That's one part of the design I never quite figured out in a way I was happy with. It's not really mutation that matters, it is (potential) freeing.
If I have a very large struct made up of substructs, none of which is stored through a pointer, then mutating any part of this struct invalidates no references, it is the same as if each individual field was mutated. But I wanted to avoid needing an "invalidates" annotation of some sort...
It is a pain to ensure it works as intended. A simple syntax directed algorithm (even in reverse ;) ) is preferable if you can get away with it. I guess the compatibility with Rust will end up forcing you into the constraint route though.
Big props to the group borrowing idea. It is similar to my own attempts (including the use of an explicit path rather then some generic lifetime parameter), but I never got the rules quite this clear.
In the other article you mentioned stability. That's one part of the design I never quite figured out in a way I was happy with. It's not really mutation that matters, it is (potential) freeing.
If I have a very large struct made up of substructs, none of which is stored through a pointer, then mutating any part of this struct invalidates no references, it is the same as if each individual field was mutated. But I wanted to avoid needing an "invalidates" annotation of some sort...