Errors are valid values, handling them is as normal as handling other values you get from functions.
let foo = try!(something_that_might_error())
// or soon...
let foo = something_that_might_error()?
The try!() macro or the ? operator unwrap a Result<T, E> value, which is basically "either the return value or an error value". If it's a return value (T), the macro/operator just gets the value out of it - but if it's an error (E), it will convert the error into your own function's Result<T, E> return type using the From trait, and return that from your own function immediately.The practical result? When I'm parsing input or doing other things that are heavy on errors, I can split it out into another function, wrap every call that might fail in try!(), and only have to actually handle the error once. This allows me to see my code clearer - I can see the success case very clearly, but I'm still forced to decide whether to handle or return errors by the compiler, because there's no other way to get the T out of a Result<T, E>.
There's a few other languages which implement this, though they lean towards the functional side a lot more than Rust does.
Experience: I'm writing a small internal certificate authority in Go because it has x.509 and signing support in the standard library. I'm no safer by having roughly 3/5 of my lines be if err != nil { return err; }.
Go already has plenty of complicated language primitives with complex behaviour.
What sorts of things fall into this category, and what tradeoffs you're willing to make to have the computer do things for you, is a matter of application (and taste), and so we reasonably have many different programming languages. But it's entirely defensible to want, in the abstract, your language to do repetitive and important work for you. That's what computers are good at.