Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate switching IntoError from an associated type to generics #399

Open
shepmaster opened this issue Aug 20, 2023 · 2 comments
Open
Labels
enhancement New feature or request feedback requested User feedback desired on a design decision

Comments

@shepmaster
Copy link
Owner

In #398, we discussed the possibility of changing IntoError to look something like

trait IntoError<S, C> {
    fn into_error(source: S, context: C) -> Self;
}

I think this would be needed to support having multiple #[snafu(from)] attributes.

@shepmaster shepmaster added enhancement New feature or request feedback requested User feedback desired on a design decision labels Aug 20, 2023
@shepmaster
Copy link
Owner Author

As more-or-less expected, with the increased flexibility of the generics, certain pieces of code now become ambigous. For example, this code is no longer valid because nothing constrains e to a specific type:

let e = trigger().context(SomeSnafu).unwrap_err();
ErrorCompat::backtrace(&e)

@shepmaster
Copy link
Owner Author

As another attempt, I looked at making the trait closer in concept to std::ops::Add, where we take in a source error, add context to it, then get an output error:

// Library code

pub trait IntoError<C> {
    type Error;

    fn into_error(self, context: C) -> Self::Error;
}

struct NoneError;

// User code

#[derive(Debug)]
struct GenericError<T> {
    value: T,
}

// Generated code

struct GenericSnafu<__T0> {
    value: __T0,
}

impl<T, __T0> IntoError<GenericSnafu<__T0>> for NoneError
where
    __T0: ::core::convert::Into<T>,
{
    type Error = GenericError<T>;

    #[track_caller]
    fn into_error(self, context: GenericSnafu<__T0>) -> Self::Error {
        GenericError {
            value: ::core::convert::Into::into(context.value),
        }
    }
}

Unfortunately, that runs into a compiler error:

error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
  --> src/lib.rs:24:6
   |
24 | impl<T, __T0> IntoError<GenericSnafu<__T0>> for NoneError
   |      ^ unconstrained type parameter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feedback requested User feedback desired on a design decision
Projects
None yet
Development

No branches or pull requests

1 participant