-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Unrecognized associated type bound on another associated type #24159
Comments
This may be related to #23481. |
Edited original post to remove
|
A lot of related issues for this have been opened over time. Duplicates: #37808, #39532, #40093, #48674, #54375, #54844 Probably same underlying cause: #32722, #37883, #38917, #43475, #47897, #54149 There's also a related discussion on the Rust forums: https://users.rust-lang.org/t/bounds-on-associated-types-enforced-too-soon/12948 |
Mildly simplified: trait Bar<T> { fn dummy(&self); }
trait Foo {
type A;
type B: Bar<Self::A>;
fn get_b(&self) -> &Self::B;
}
fn test_bar<A, B: Bar<A>>(_: &B) {}
fn test<A, F: Foo<A=A>>(f: &F) {
test_bar(f.get_b());
}
fn main() { } So, probably the fix is "just" that we need to do some normalization somewhere or other. My preference is to fix this by moving over to lazy normalization and chalk, which will do away with these sorts of shortcomings for good. But it's probably worth looking to see if this can be fixed a touch more rapidly by adding a normalization in the right place. I'll try to do that in a bit and mentor/open a fix if it seems reasonable. |
Any progress here @nikomatsakis? |
Looks like the issue is known and mentioned at this line: https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/check/compare_method.rs#L252 This indicates this may be the area to check in when working on this? Still working on understanding a lot of this code, so I'm not sure. |
Ran into this as well. Here's my minimal test case: trait Bar<T> {}
trait Caz {
type A;
type B: Bar<Self::A>;
}
fn test<T, U>() where T: Caz, U: Caz<A = T::A> {}
|
I've just run into this issue in one of my own projects, and reduced it to a test case that's even simpler than the last one: trait Bar<T> {}
trait Caz {
type A;
type B: Bar<Self::A>;
}
fn test<T: Caz<A = ()>>() {} Although it compiles successfully if you add the bizarrely-tautological-looking For now, I'm stuck with adding the where clause, but that's putting a LOT of boilerplate in my code (the actual where clause is 71 characters long and appears in dozens of places, including being de-facto required in code that uses my library, not just inside the library itself). Is there any progress on this? |
…asper Use structured suggestion for restricting bounds When a trait bound is not met and restricting a type parameter would make the restriction hold, use a structured suggestion pointing at an appropriate place (type param in param list or `where` clause). Account for opaque parameters where instead of suggesting extending the `where` clause, we suggest appending the new restriction: `fn foo(impl Trait + UnmetTrait)`. Fix rust-lang#64565, fix rust-lang#41817, fix rust-lang#24354, cc rust-lang#26026, cc rust-lang#37808, cc rust-lang#24159, fix rust-lang#37138, fix rust-lang#24354, cc rust-lang#20671.
…asper Use structured suggestion for restricting bounds When a trait bound is not met and restricting a type parameter would make the restriction hold, use a structured suggestion pointing at an appropriate place (type param in param list or `where` clause). Account for opaque parameters where instead of suggesting extending the `where` clause, we suggest appending the new restriction: `fn foo(impl Trait + UnmetTrait)`. Fix rust-lang#64565, fix rust-lang#41817, fix rust-lang#24354, cc rust-lang#26026, cc rust-lang#37808, cc rust-lang#24159, fix rust-lang#37138, fix rust-lang#24354, cc rust-lang#20671.
Applying the suggestions makes the code compile. Edit: updated output:
Update: this case now compiles. In call cases applying the suggestions fulfill the requirements. |
@nikomatsakis any update on this? Is there anything I can do help with this? I'd be happy and try to help where I can, as this is blocking a lot of nice usages of |
It looks like this compiles under Given that, the solution might just be fully stable chalk integration. If it is, then this issue would fall into the same bucket as features like implied bounds, where there isn't a lot we can do outside of just pushing chalk integration. |
I think my original analysis is still correct. I think the normalizing is missing here:
After we invoke rust/src/librustc_trait_selection/traits/select/mod.rs Lines 1855 to 1863 in ff4a253
If Chalk solves this, it is probably because of lazy normalization. |
All of the cases I mentioned now compile. I believe this can be closed by adding tests. |
Add more associated type tests Closes rust-lang#24159 Closes rust-lang#37808 Closes rust-lang#39532 Closes rust-lang#37883 r? `@estebank`
This removes a workaround for rust-lang#24159, which has been fixed.
…fJung Remove unneeded workaround This removes a workaround for rust-lang#24159, which has been fixed.
…fJung Remove unneeded workaround This removes a workaround for rust-lang#24159, which has been fixed.
…fJung Remove unneeded workaround This removes a workaround for rust-lang#24159, which has been fixed.
Gives me:
There is a workaround:
But it's ugly and should not be necessary.
We hit this problem a lot with gfx::Device, and I'd like to see cleaner use of it without explicit
CommandBuffer
bounds that we use as a workaround.The text was updated successfully, but these errors were encountered: