Special-casing type inference of ? operator

Type ambiguity caused by implied From in Try is quite annoying:

vec!["1", "2"].into_iter().map(|s| {
    let x: u32 = s.parse()?;
    Ok(x + 1)
});

cannot infer type of error for ? operator

This comes up quite often in fallible iterators as well as async {} blocks, and I need to write ugly syntax like Ok::<_, Error>().

Would it be terrible to let the compiler assume no error conversion in such case, as if From wasn't used in the ? desugaring? Perhaps the blanket impl From<T> for T could be tagged as a magic preferred default in case of ambiguities.

5 Likes

Resolving `Ok`-wrapping for `try` blocks · Issue #70941 · rust-lang/rust · GitHub is relevant here. The

Address issues with type inference ( try { expr? }? currently requires an explicit type annotation somewhere).

Unresolved problem is exactly the same issue I think.

EDIT: originally meat to link Tracking issue for `?` operator and `try` blocks (RFC 243, `question_mark` & `try_blocks` features) · Issue #31436 · rust-lang/rust · GitHub

1 Like

My not-written-into-an-RFC-yet vision for that would be for normal try blocks to stop this, as sketched in https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#possibilities-for-try.

So you could write that as

vec!["1", "2"].into_iter().map(|s| try {
    let x: u32 = s.parse()?;
    x + 1
});

and it would just work.

Note also that with the new desugaring (as of RFC 3058) the From is Result-specific, so this problem doesn't exist for Option -- and if the traits stabilize, it could allow using new result-like types that would have the conversion as an extra opt-in step instead of always.

1 Like