Is there a good writeup somewhere about building intuition for which functions a trait sees, esp if it has conflicts with the native functions on the struct?
If the concrete type is known (or inferred), i.e. Option<i32> then methods on that type will be preferred. If not, like in a generic function, you can only use methods from trait.
If I am doing something like this, I think it would be a good idea to differentiate by provide a prefix/suffix to make it clearer which version is being called, yeah?
Note that the trait's versions of unwrap and is_some will only be called if your Foo trait is in scope. If this were in a different module, you would need to import Foo to get this behavior, otherwise the intrinsic implementations will be used.
Rust doesn't have classes with inheritance, so overriding a function is not possible.
handle_foo is generic over T, which must implement Foo, so Foo::is_some is called instead of Option::is_some. But if you write Some(42u32).is_some(), then Option::is_some is called.
If you also had a trait Bar : Foo with the same methods and implementations, and changed the signature to fn handle_bar<T: Bar>(foo: T), then Rust would complain: