Skip to content
TE147 · Type · error

Fallible tail returns an unwrapped value

`?` propagates failure but unwraps success. A function returning `Result` or `Option` must wrap that success explicitly with `.Ok(...)` or `.Some(...)`.

The postfix ? operator has two jobs: it propagates the failure branch and unwraps the success branch. Therefore operation()? has the success payload type, not the wrapper type returned by operation().

fn insert() -> Result<int, DbError> { ... }

fn add() -> Result<int, DbError> {
  insert()?
  //       ^ error[TE147]: expected `Result<int, DbError>`, found `int`
}

The final expression is a real return, so this is not a missing-return error. It is a type mismatch: on success the function would return a raw int, while its signature promises a Result<int, DbError>.

Fix it

Wrap the successful value explicitly:

fn add() -> Result<int, DbError> {
  .Ok(insert()?)
}

When the function has no return annotation, qualify the constructor because there is no source-level expected type for the leading-dot shorthand:

fn add() {
  Result.Ok(insert()?)
}

The same rule applies to Option:

fn find() -> Option<User> {
  .Some(load_user()?)
}

Keeping the wrapper visible makes ? predictable in every expression position and ensures the runtime value agrees with the declared type.

See also

See also

Search Zolo

9 results

en