I have always used Pascal for memory safe strings. Reference counted, mutable xor aliased, bound checked: their safety is perfect.
Unfortunately there is no string view, so you need to copy the substrings or use pointers/indices. I tried to build a string view, but the freepascal compiler is not smart enough to keep a struct of 2 elements in registers.
You don't infer potential ownership from a C++ ref. Likewise for char* strings unless it is to interface with a C api, in which case you will keep it anyway.
Sure C++ doesnt have a borrow checker but these types encourage the idea of "reifying" lack of ownership rather than keeping it ad hoc