Skip to content

Cannot implement trait for generic struct where types are also generic #28271

@fuchsnj

Description

@fuchsnj

In this example code, I want to implement the trait Convert for the struct Combine (which combines 2 Converts)
(code in playground)

pub trait Convert<D1, D2>{
    fn convert(&self, data: D1) -> D2;
}
impl<D1, D2, T> Convert<D1, D2> for T
where T: Fn(D1) -> D2{
    fn convert(&self, data:D1) -> D2{
        (*self)(data)
    }
}

//combines 2 Converts into 1
pub struct Combine<C1, C2>{
    a: C1,
    b: C2
}

impl<C1, C2, D1, D2, D3> Convert<D1, D3> for Combine<C1, C2> where
C1: Convert<D1, D2>,
C2: Convert<D2, D3>{
    fn convert(&self, data: D1) -> D3{
        let value: D2 = self.a.convert(data);
        self.b.convert(value)
    }
}

fn main(){
    let converter = Combine{
        a: |d|{"".to_string()},
        b: |d|{true}
    };
    let value:bool = converter.convert(4);
    println!("value: {:?}", value);
}

but this gets

<anon>:17:18: 17:20 error: the type parameter `D2` is not constrained by the impl trait, self type, or predicates [E0207]
<anon>:17 impl<C1, C2, D1, D2, D3> Convert<D1, D3> for Combine<C1, C2> where
                           ^~
<anon>:17:18: 17:20 help: see the detailed explanation for E0207
error: aborting due to previous error

I have seen a few ugly solutions, such as putting D2 into the struct as PhantomData but this doesn't work if for example the Combine struct were required to be Send + Sync and D2 could not be Send + Sync.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions