If your language has a garbage collector, it may mean tiny substrings keep huge strings alive. Java moved away from using slices (https://dzone.com/articles/changes-stringsubstring-java-7), I think for that reason.
If your language isn’t garbage collected, it can cause problems if the substring must outlive the string it was extracted from. That means that, for some functions, you’ll have to decide whether to return the slice or make the copy.
(In Rust, that means the slice has a different ‘type’ (not sure what they call it), that of a string whose lifetime is bound to the original string, and the compiler will check that you won’t make the mistake of having the slice outlive it’s source)
Also, using slices doesn’t come for free; it makes all String objects larger because, apart from the reference to the underlying character array, an offset and length must be kept around.
(And yeah, you're right about Rust too; string slices are a different type than owned strings.)