Second, most of the time you can use the ? operator to greatly simplify error handling. Any code path that shares the same error type can just pass through errors as if they were an exception. The ? operator is also aware of Into/From trait implementations so in many (or even majority of) cases you can use the ? operator even if the function you're calling has a different error type! If I remember correctly, you can even exploit the module system to provide a per-file Into/From implementation for your custom error type if it doesn't map cleanly across use cases (they just have to be in the same module as the type). Rust's zero cost abstractions and trait system make it really easy to reduce boilerplate without compromising on readibility or discoverability.
Third, the Result type has a number of functional operators for responding to and combining results. You can do Result.and_then(...) with a closure or function call to do something when there is no error and Result.or_else(...) to do something when there is an error. You can use the and or or operators to combine multiple results and there are many other utility functions that are universal to Rust error handling that make the entire experience very pleasant, composable, and readable with a little experience.
This is a highly contentious assertion, and I don't think it's true for most programs, at least not in the way you're suggesting.
Most of the point of exceptions is that errors don't have to be handled; or rather, in most application software, almost all errors should be handled high up in the stack, near the event loop or server request / response dispatcher.
The kind of error that you'd handle high up the stack is, say, a general I/O error reading a file.
But when you look up an item in a collection (or a node in a DOM tree), and it is not found, the only place where you can sensibly handle that is right where the lookup happens, usually.
In a language that doesn't follow this philosophy, what you get instead are random NullPointerExceptions etc. If you go and look at a random C# or Java project on GitHub and check its tracker, you will see that - surprise, surprise! - that is exactly the type of error that shows up most.
An item not found in a collection or tree is not an error.
Null pointer exceptions are little different.