The thing is that mutability is a useful and common property used by most programmers. It takes a bit of buy in to be convinced immutability is a good thing that solves bugs. For example:
Here's a reasonable program to write in Python (wave hands here, my python is rusty)
queue = [root]
for node in queue:
if !node.visited:
# ... visit the node ...
node.visited = True
for child in node.children:
queue.insert(child)
Here's that in Rust.
let mut queue = VecDeque::new();
queue.push_back(root);
for node in &mut queue {
if !node.visited {
// ... visit the node ...
node.visited = true;
for child in &mut node.children {
queue.push_back(child);
}
}
}
This will not compile, at all. You need to do a lot of work to restructure the data structures in Rust to get that reasonable program to run soundly. Now that's a good thing, because this would be invalid in C/C++ too due to iterator invalidation and lifetime issues, but it's the kind of thing that people who haven't seen a block of code segfault due to a `push_back` before would be confused by.
It's rather rare for a programmer to need to learn about memory safety when compilers in managed languages just solve it for you, and in other systems languages they assume you already know it (or don't care that you can write unsafe programs).
There's just that additional conceptual burden when learning Rust and why programs that seem syntactically correct and safe are forbidden.