How do I fix this code?

  1. I have the following code:
use super::*;

#[derive(Debug, Clone)]
pub enum ForestAuxErr<NodeID: Clone + Eq + Hash, AuxErr: Clone> {
    ForestErr(ForestErr<NodeID>),
    AuxErr(AuxErr),
}

pub trait ForestAuxErrT<NodeID> {
    fn missing_child(node_id: NodeID) -> Self;
}

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From<AuxErr> for ForestAuxErr<NodeID, AuxErr> {
    fn from(aux_error: AuxErr) -> ForestAuxErr<NodeID, AuxErr> {
        ForestAuxErr::AuxErr(aux_error)
    }
}

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From<ForestErr<NodeID>>
    for ForestAuxErr<NodeID, AuxErr>
{
    fn from(forest_error: ForestErr<NodeID>) -> ForestAuxErr<NodeID, AuxErr> {
        ForestAuxErr::ForestErr(forest_error)
    }
}
  1. I get an error of:
13 |   impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From<AuxErr> for ForestAuxErr<NodeID, AuxErr> {
   |   -------------------------------------------------------------------------------------------- first implementation here
...
19 | / impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From<ForestErr<NodeID>>
20 | |     for ForestAuxErr<NodeID, AuxErr>
21 | | {
22 | |     fn from(forest_error: ForestErr<NodeID>) -> ForestAuxErr<NodeID, AuxErr> {
23 | |         ForestAuxErr::ForestErr(forest_error)
24 | |     }
25 | | }
   | |_^ conflicting implementation for `forest::forest_aux_error::ForestAuxErr<_, forest::forest_error::ForestErr<_>>`
  1. I am not sure how to fix this.

  2. The XY problem is that I have a number of functions that return Result<_, Error> and I want auto conversion of errors on ?

Between

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From for ForestAuxErr<NodeID, AuxErr> {

and

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone> From<ForestErr>

there is nothing that tells the compiler that AuxErr, which is a type parameter,
won’t be ForestErr.

To demonstrate this, I defined a trait bound, MyTrait, and constrained AuxErr
type parameter with MyTrait. That way ForestErr, which does not implement
MyTrait, will never be considered as concrete type for AuxErr.

trait MyTrait {
    fn handle();
}

#[derive(Debug, Clone)]
enum ForestAuxErr<NodeID: Clone + Eq + Hash, AuxErr: Clone + MyTrait> {
    ForestErr(ForestErr<NodeID>),
    AuxErr(AuxErr),
}

trait ForestAuxErrT<NodeID> {
    fn missing_child(node_id: NodeID) -> Self;
}

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone + MyTrait> From<AuxErr>
    for ForestAuxErr<NodeID, AuxErr>
{
    fn from(aux_error: AuxErr) -> ForestAuxErr<NodeID, AuxErr> {
        ForestAuxErr::AuxErr(aux_error)
    }
}

impl<NodeID: Clone + Eq + Hash, AuxErr: Clone + MyTrait> From<ForestErr<NodeID>>
    for ForestAuxErr<NodeID, AuxErr>
{
    fn from(forest_error: ForestErr<NodeID>) -> ForestAuxErr<NodeID, AuxErr> {
        ForestAuxErr::ForestErr(forest_error)
    }
}
1 Like