Why this fires¶
Postfix ? and ?> return the matching nil, Option.None, or Result.Err
from the enclosing function. That failure must be compatible with the
function's declared return type. Inside attempt, Result failures instead exit
the nearest local boundary and must match its inferred or annotated error type.
Optional-only failures cannot cross that boundary because they have no error
payload; construct an explicit Result before propagating them.
fn parse() -> Result<int, str> { Result.Err("invalid") }
fn invalid() -> int {
parse()? // error[TE833]: `Result.Err` cannot be returned as `int`
}Option.None is not interchangeable with Result.Err, and a nilable failure
is not silently boxed into either enum.
Fix it¶
Return a compatible fallible type, or handle the failure explicitly:
fn valid() -> Result<int, str> {
Result.Ok(parse()? * 2)
}Use match when translating between different failure representations.
Handle a Result locally¶
Use attempt when a Result failure should end a local operation and the caller
should continue. The outer function can retain an ordinary return type:
fn local() -> int {
let result: Result<int, str> = attempt { parse()? * 2 }
match result {
Result::Ok(value) => value,
Result::Err(error) => 0,
}
}An int? or Option<int> operand still needs an explicit conversion to
Result with an error payload before using ? inside attempt. Panics and
explicit return keep their normal outer control flow.