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

Disambiguating associated types from super traits in a trait object #48285

Open
vitalyd opened this issue Feb 17, 2018 · 7 comments
Open

Disambiguating associated types from super traits in a trait object #48285

vitalyd opened this issue Feb 17, 2018 · 7 comments
Labels
A-traits Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@vitalyd
Copy link

vitalyd commented Feb 17, 2018

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.

@pietroalbini pietroalbini added A-traits Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Feb 20, 2018
@0b01

This comment was marked as off-topic.

@steveklabnik
Copy link
Member

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

@oli-obk
Copy link
Contributor

oli-obk commented May 2, 2020

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() {}

@lily-commure
Copy link
Contributor

lily-commure commented May 5, 2020

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-commure
Copy link
Contributor

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>,
}

@estebank
Copy link
Contributor

estebank commented May 5, 2020

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> {}

@jendrikw
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants