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

Nested associated type projection is overly conservative #38078

Open
aturon opened this Issue Nov 29, 2016 · 14 comments

Comments

Projects
None yet
@aturon
Copy link
Member

aturon commented Nov 29, 2016

The following setup

trait OneTrait {
    type Ty: AnotherTrait;
    fn project() -> Self::Ty::Out;
}

trait AnotherTrait {
    type Out;
}

produces the error

rustc 1.13.0 (2c6933acc 2016-11-07)
error[E0223]: ambiguous associated type
 --> <anon>:3:17
  |
3 |     fn bar() -> Self::Bar::Out;
  |                 ^^^^^^^^^^^^^^ ambiguous associated type
  |
  = note: specify the type using the syntax `<<Self as Foo>::Bar as Trait>::Out`

It would be great for the less explicit projection to work here.

cc @nikomatsakis

@aturon aturon added the A-traits label Nov 29, 2016

@aturon

This comment has been minimized.

Copy link
Member Author

aturon commented Nov 29, 2016

Note that the issue title may be overly specific; I haven't deeply investigated the cases where this kind of projection fails.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Nov 29, 2016

In my experience at least A::B::C never works, although maybe bugs have been fixed that enables that recnetly?

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Nov 29, 2016

FWIW, <<Self as Foo>::Bar as Trait>::Out can be shortened to <Self::Ty as AnotherTrait>::Out.
A::B for associated types currently works only if A is a type parameter (including Self) that is known to have a trait with associated type B as a bound.

@malbarbo

This comment has been minimized.

Copy link
Contributor

malbarbo commented Nov 30, 2016

Possible duplicates: #31372 and #35711

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Dec 20, 2016

In terms of the compiler's implementation, this isn't really about projection. It's not actually getting that far. Rather, it fails when lowering the AST into types, which is the point where we have to pick a trait. @eddyb has been doing a lot of heroic work refactoring the type-end to remove that limitation, which is fairly tricky -- the problem is that to do it properly, one must reason about the where-clauses that are in scope and do trait selection, but to know what where-clauses are in scope, one must lower them, and that is what we are trying to do. To resolve this, @eddyb has been refactoring the compiler to cope with partially lowered sets of where-clauses, basically.

@neuronsguy

This comment has been minimized.

Copy link

neuronsguy commented Mar 15, 2017

So, is @eddyb's fix for this being developed openly somewhere it's possible to track progress (or help?) This issue is causing me some frustration, so I'd love to know what I could do to help resolve it.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Mar 16, 2017

I think he wound up taking another approach. I'm not sure what's the shortest path here just now.

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Mar 16, 2017

Perhaps keying the type_param_predicates requests on a type instead of just type parameters specifically, and treating failure to convert some types in bounds as an ambiguity, may work.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Oct 25, 2017

This is a huge paper cut for me: I have a lot of code of the form <<<<F as E>::E as D>::D as C>::C as B>::B as A>::A> and it is completely unreadable to write methods on traits while having to skim through that.

There are two cases where this cuts me:

  • when I know that there isn't an ambiguity yet I have to disambiguate
  • when I doubt if there is an ambiguity and might not want one, in which case I need to go through the whole trait hierarchy looking for it because... even though the error says "ambiguous" it doesn't bother telling me where the ambiguities are...

Having to disambiguate is the smaller paper cut. It would already be infinitely helpful if the error message would tell me if there is an actual ambiguity and where, or if it would tell me that there isn't an ambiguity.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Oct 25, 2017

Maybe the problem is that what I understand by ambiguous (e.g. that two associated types are named equal) and what the compiler understands by ambiguous are different things.

@zesterer

This comment has been minimized.

Copy link
Contributor

zesterer commented Mar 22, 2018

I've tried using syntax, that one would expect to work just fine, and have wound up with this issue. It's quite clear to any human that there exist no ambiguities in this code, yet the compiler unnecessarily requires extra (and ugly) syntax to accept the code. This is extremely inconvenient.

@alexlitty

This comment has been minimized.

Copy link

alexlitty commented Apr 17, 2018

I'm not sure if chiming in and saying "me too" at this point is more annoying than helpful, but me too :)

I think this one's hard on novice Rustaceans because we're interpreting the situation as human error, as if we've unintentionally made the situation ambiguous and there's something we can do to correct it.

@tiby312

This comment has been minimized.

Copy link

tiby312 commented May 5, 2018

I would also love this. I've been "shortening" it like this, but this way there is an extra associated type that structs have to implement for no reason:

trait OneTrait {
    type Ty: AnotherTrait<Out=Self::Oy>;
    type Oy;
    fn project() -> Self::Oy;
}

trait AnotherTrait {
    type Out;
}
@purpleposeidon

This comment has been minimized.

Copy link

purpleposeidon commented Jun 28, 2018

At the very least, the error message should be improved; it gives bad advice:
[Playground]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.