shepmaster / snafu

Easily assign underlying errors into domain-specific errors while adding context
https://docs.rs/snafu/
Apache License 2.0
1.4k stars 60 forks source link

Why this code cannot infer context? #362

Closed caibirdme closed 1 year ago

caibirdme commented 1 year ago
use std::net::{Ipv4Addr};
use snafu::prelude::*;

#[derive(Debug, Snafu)]
enum ConvertErr {
    #[snafu(display("invalid ip addr: {val}"))]
    IPAddrErr{ source: std::net::AddrParseError, val: String },
    #[snafu(context(false))]
    InvalidUTF8{ source: std::str::Utf8Error }
}

type Result = std::result::Result<(), ConvertErr>;

fn conv_ipv4(s: Vec<u8>) -> Result {
    let s = std::str::from_utf8(&s)?;
    let res = s.parse::<Ipv4Addr>();
    let w = res.context(IPAddrErrSnafu{val: s.into()})?;
    println!("{:?}", w);
    Ok(())
}

error:

type annotations needed
cannot infer type of the type parameter `__T0` declared on the struct `IPAddrErrSnafu`rustc[E0282](https://doc.rust-lang.org/error-index.html#E0282)
main.rs(17, 39): consider specifying the generic arguments: `::<__T0>`

snafu version = 0.7.2 rust version 1.63.0

How could I fix it?

Enet4 commented 1 year ago

Replace s.into() with just s. SNAFU should already call a conversion for context values, so an additional conversion interferes with inference.

caibirdme commented 1 year ago

Thx very much

shepmaster commented 1 year ago

This has come up once or twice before; we should think about adding it to the troubleshooting guide