Disambiguating associated types from super traits in a trait object

c1a2027
Opened by vitalyd at 2024-12-21 05:39:42

Suppose you have a trait:

trait Foo: std::ops::Index<usize> + std::ops::Index<isize> {}

How do you declare a Foo trait object, say a Box? The Output associated types need to be specified but they need to be disambiguated between the two super traits. Projections that I’ve tried don’t seem to work but it’s possible I didn’t try the right incarnation.

This stems from the https://users.rust-lang.org/t/how-to-specify-associated-types-with-same-name-in-generics/15677 post.

  1. The trait system is pretty broken on all fronts. I hope it gets overhauled completely when HKT comes along.

    Ricky Han at 2018-03-23 09:44:16

  2. Triage: I'm not aware of a way to do this.

    Steve Klabnik at 2019-12-05 13:32:07

  3. Repro from a duplicate issue:

    trait Foo {
        type Error;
    }
    
    trait Bar {
        type Error;
    }
    
    trait Cake : Foo + Bar {}
    
    struct S {
        f: Box<Cake<Error = i32>>,
    }
    
    fn main() {}
    

    Oli Scherer at 2020-05-02 06:28:38

  4. There's a similar disambiguation problem here:

    trait A {
      type C;
    }
    
    trait B: A {
      type C;
    }
    
    struct S(Box<dyn B<C=()>>);
    

    though this is less of an issue because it's unlikely B would be defined this way in practice.

    Lily Chung at 2020-05-05 22:48:18

  5. It's possible to work around this by defining an intermediate trait (thanks @estebank):

    trait Foo {
        type Error;
    }
    
    trait Bar {
        type Error;
    }
    
    trait Cake : Foo + Bar {}
    
    trait Cake2 : Cake where Self : Foo<Error = i32>, Self : Bar<Error = u64> {}
    
    struct S {
        f: Box<dyn Cake2>,
    }
    

    Lily Chung at 2020-05-05 23:22:31

  6. Here's a somewhat complete example of how the above could work (without having to add implementations for Cake2 for every relevant type):

    impl<T> Cake2 for T where T: Cake + Foo<Error = i32> + Bar<Error = u64> {}
    

    Esteban Kuber at 2020-05-05 23:35:39

  7. The error messages about these kind of things are also pretty bad: #100109

    Jendrik at 2023-03-20 07:47:18