> Unless you meant that new functions could be annotated as pure in order to avoid future errors in code not yet written?
Precisely. New functions can be written to treat all pre-existing memory as immutable, and we can be confident that that data won't change.
For example, if the pure function sees a unique_ptr<MyThing> somewhere in pre-existing memory, we'll know that that MyThing existed at the time of the pure function call, and will keep existing until the end of the pure function call; nobody can destroy it in-between.
Also, it's surprising how many functions in C++ are already effectively pure, and can add the annotation with little (or zero) refactoring. But we don't have to do this, the benefit for new code is enough.
> I'm not so sure a mandatory system would go over well for C++ since many who use it want shared mutability
This is opt-in; we don't have to annotate all our functions as pure, and we can still use shared mutability freely outside of pure functions. We can then hand a shared-mutable blob of data to a pure function, which will then treat it as a shared-immutable blob of data.
That's why I like this approach: one can write an entire program without it, and one can start using it whenever they want. It composes well like that.
Also, if one wants to leverage the region borrow checker outside of pure functions, that's possible too. In Vale, even when not in pure functions, one would make use of `iso` objects (little isolated sub-regions in an otherwise shared-mutable region, similar to Pony's `iso`) and treat those as immutable or mutable as one desires. I suspect it could work in C++ too, but nobody's tried it so I can't say for certain.