|
|
|
|
|
by vlovich123
1463 days ago
|
|
How is this solved in Rust though? The only thing Rust solves is that you don't accidentally hang onto a bad reference, but I'm failing to see how &str/String is meaningfully different from char/string since the same issue applies (char = borrowed, string = owned). My Rust is rusty so apologies for the pun & any syntax errors. Let's say you have the following: // some process managed by team a
fn caller1(...) {
String s;
level1Callee(&s);
}
// some process managed by team b
fn caller2(s: &str) {
level1Callee(s);
}
// library 1 by team c
fn level1Callee(iDontNeedOwnershipOrDoI: &str) {
level2Callee(iDontNeedOwnershipOrDoI.to_owned())
}
// library 1 by team d
fn level2Callee(iNeedStrongOwnershipBecauseIMutateTheStringAnyway: String) {
level3Callee(&iNeedStrongOwnershipBecauseIMutateTheStringAnyway)
}
This is roughly what happened in Chrome as I understand it (except multiple times because of independent libraries that didn't notice that they probably should have just made a copy to begin with). Let's pretend the codebase had been written originally in Rust. How does Rust avoid this problem from coming up? This didn't happen in Chrome because of ownership. It came up organically because of years of refactoring obfuscated things. For example, level2Callee started out not needing strong ownership but then started calling a library that did (refactoring a complex codebase is very hard & time consuming). Rinse & repeat after many years. Now maybe Rust tooling is better able to point out the unnecessary acquiring/dropping of the strings but that seems unlikely - the problem is statically very difficult to lint around. |
|
In a lot of places in Chromium the impedance choices are arbitrary. You have a raw pointer but need a string or vice versa. Ownership isn't the problem, so in Rust you literally just always choose &str for these APIs and pay nothing. A team who design their API taking &String in this situation get the same treatment as a team who name all their types Data1, Data2, Data3 and so on. Somebody senior fetches the water spray, "No. Bad programmer".
You might be outraged, surely C++ programmers also never get this wrong. But nope, happens all the time as Chromium illustrates.
Added: One cause that shows up in my review is this:
C++ strings know how long they are. The raw pointer does not. As a result if we have lots of people asking if their thing is "some text" it's tempting to demand they give us a string, since if the string's length isn't 9 we don't need to look at the text itself. It's an optimisation! Rust's &str knows how long it is.