#Cannot replicate implementation of FromResidual from stdlib

15 messages · Page 1 of 1 (latest)

static sundial
#
pub struct ParserResult<'a, T, E> {
    pub source: &'a str,
    pub typ: ParserResultType<T, E>,
}

pub enum ParserResultType<T, E> {
    Ok(T),
    Err(E),
    Incomplete,
}

impl<'a, T, E> Try for ParserResult<'a, T, E> {
    type Output = (&'a str, T);

    type Residual = ParserResult<'a, Infallible, E>;

    fn from_output(output: Self::Output) -> Self {
        Self::from_val(output.0, output.1)
    }

    fn branch(self) -> std::ops::ControlFlow<Self::Residual, Self::Output> {
        match self.typ {
            ParserResultType::Ok(v) => ControlFlow::Continue((self.source, v)),
            ParserResultType::Err(e) => ControlFlow::Break(ParserResult::from_err(self.source, e)),
            ParserResultType::Incomplete => {
                ControlFlow::Break(ParserResult::incomplete(self.source))
            }
        }
    }
}

impl<'a, T, E, F: From<E>> FromResidual<ParserResult<'a, Infallible, F>>
    for ParserResult<'a, T, F>
{
    fn from_residual(residual: <Self as Try>::Residual) -> Self {
        Self {
            source: residual.source,
            typ: match residual.typ {
                ParserResultType::Ok(v) => ParserResultType::Ok(v),
                ParserResultType::Err(e) => ParserResultType::Err(e.into()),
                ParserResultType::Incomplete => ParserResultType::Incomplete,
            },
        }
    }
}

I'm trying to implement the try trait (using the unstable feature try_trait_v2) for my ParserResult type, but I'm getting this error:

#

it makes sense why this error would happen, but... how does the standard library do it?

#

they have something nearly identical

#

and it works fine

#

is this just an exception made by the compiler for the standard library? and if so, should I just make my ParserResult type just a type alias for something like Result<(&'a str, T), (&'a str, Option<E>)>?

grizzled drum
#

The thing you want to do is say that a Result<T, F> can be constructed from a Result<Infallible, E> where F: From<E>

#

The idea being that you will use the From bound to convert E into F

#

The From bound is useless if the result you start from is already a Result<Infallible, F> (or ParserResult<'a, Infallible, F>, as it were)

static sundial
#

I've tried various permutations of these values so I guess it makes sense I made a mistake

#

ah

#

the actual issue

#

was residual: <Self as Try>::Residual

#

if I change that to residual: ParserResult<'a, Infallible, E> it works

#

thank you!