How does ok_or and question mark convert &str into an Error?

This works:

use std::error::Error;

fn main() {
    foo().unwrap();
}

fn foo() -> Result<(), Box<dyn Error>> {
    let none = Option::None;
    none.ok_or("nothing here")?;
    Ok(())
}

How is the string transformed into an error?

It only seems to work with both ok_or() and the question mark. This doesn't work:

fn foo() -> Result<(), Box<dyn Error>> {
    "nothing here"?
}

Neither does this:

fn foo() -> Result<(), Box<dyn Error>> {
    let none = Option::None;
    return none.ok_or("nothing here");
}

Could I somehow convert a string into an Error manually, using the same transformation?

The ? Operator needs to be called on a Result:

fn foo() -> Result<(), Box<dyn std::error::Error>> {
    Err("nothing here")?
}
1 Like

There's two parts here:

Box<dyn Error> implements From<&'static str>. This means that you can do something like:

let e: Box<dyn Error> = From::from("nothing here");  // or "nothing here".into();

? turns something that implements std::ops::Try into its Ok type (or returns it if it's the Err variant) - this is basically Options and Results. This does some coercion to make it easier to return multiple return types; specifically, when it gets an error and needs to return , it calls From::from on it. That's why you can use the ? on a result with an Err type of &'static str and it'll be automatically turned into a Box<dyn Error>.

1 Like