But under the hood it's all the same https://doc.rust-lang.org/stable/src/core/bool.rs.html#157-1...
pub const fn toggle(&mut self)
The "&mut" says that toggle takes a mutable reference to the instance it is called off of. This is also called a mutable borrow. You might think that would get buried in the program because you don't always check the type signature of every method you call, but there are a few reasons that muts really jump out in rust. The languages immutable by default nature is one and the other is that several IDE have features to specifically draw attention to mutable instances/references. It's a fairly common pattern in rust to have helper methods on a type that take a mutable reference or ownership of self.
TL;DR: Rust's ownership model is very unique. Once it clicks its the cat's pajamas, but experience in other languages don't map well to this part of the language.
In effect, if x is a bool, doing x.toggle() is rewritten by the compiler as bool::toggle(&mut x), which can of course modify x.
It’s only weird if you come from languages like Java where “primitives” are distinct from “objects”, which is a self-imposed limitation the language imposes.
Otherwise agreed, methods like this can be mutable in any language that doesn't heavily specialize primitives.
foo.bar().baz[expensive()].qux.toggle();Looks like part of the motivation was for things with long names like `some_struct_a.some_field_b.some_subfield_c`, where needing to name the field twice would have pushed people to using `^= true` instead, which is a bit more roundabout to decipher and risks people forgetting the idiom and writing `^= false` by accident. Not necessarily the most useful API, but not unmotivated and harmless to add.