let f = Some(get_a_u16());
foo(f);
...
func foo(f: u16) -> u16 {
match f {
None => 0,
Some(f) => f * 1234
}
}
I'd expect any reasonable compiler to include enough link time optimization and dead code elimination to compile the whole mess down to a single multiply instruction.
I don't see what you're tying to show with your example? The typical case is, you start with a raw type in the caller (u16), and then you create a derived type (Option<MultipliedU16>) as a result of validation. Also, you'd ideally want to handle overflow errors in the multiplication, especially with something as small as a u16.
(And in case it helps anyone, for a trivial function to be inlined across crates in Rust, either the function must be marked with #[inline], or a special LTO option must be explicitly set in the Cargo profile. So often it's a good idea to mark all public trivial utility functions in a crate with #[inline].)
In my example, passing in none returns a value, not an error, so the intent is that it makes sense for that API to handle the None case in normal operation. However, in situations where the compiler can infer the argument is never None, it can remove the branch.
(Yes, that function should probably handle overflow explicitly, but that wasn't the point.)