Earlier quoted context omitted.
This doesn't have anything to do with ADTs. It's because Rust has both in-place variables and references. You aren't changing the variant of an existing ADT, you're replacing the entire ADT value with a new one. That replacement is visible in multiple places because the language allows you to take references to variables (the `&mut ex` expression). You can accomplish the same thing in C and C++ because they also have…
> You aren't changing the variant of an existing ADT, you're replacing the entire ADT value with a new one. 'Values' in Rust have no identity, except for their address. They're just a bunch of bytes in a row. What could it mean for a value to exist, except for it to be present at a set place in memory? If I have an instance of a Java class, and I change all the fields, I'd hardly say the instance has been replaced wi…
Pointers and value semantics are nice, but have nothing to do with ADTs. For example, in Rust, you can also do:
let mut ex: i32 = 42;
println!("{ex:?}"); // 42
let ex_ref: &mut i32 = &mut ex;
*ex_ref = 53;
println!("{ex:?}"); // 53
And in C: int x = 42;
printf("%d\n", x); // 42
int* x_ref = &x;
*x_ref = 53;
printf("%d\n", x); // 53
In these examples, we haven't mutated the number 42 into the number 53. We've simply stored an entirely new value in the location of `x`. In your Rust example, you're doing the exact same thing with an ADT. The variant case isn't being changed. You're creating a new value and storing it in an existing storage location. Every pointer pointing to that storage location sees the update because they all point to the same storage.