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

Associated type bound isn't always present for checking #43475

Closed
Twey opened this issue Jul 25, 2017 · 3 comments · Fixed by #81485
Closed

Associated type bound isn't always present for checking #43475

Twey opened this issue Jul 25, 2017 · 3 comments · Fixed by #81485
Labels
A-associated-items Area: Associated items (types, constants & functions) C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Twey
Copy link

Twey commented Jul 25, 2017

Trait bounds on associated types seem to be required, not implied, when the trait in question mentions an associated type on a type parameter.

Concretely, this code (or playground) produces an error:

trait Foo { type FooT: Foo; }
impl Foo for () { type FooT = (); }
trait Bar<T: Foo> { type BarT: Bar<T::FooT>; }
impl Bar<()> for () { type BarT = (); }

fn test<C: Bar<()>>() { }
error[E0277]: the trait bound `<C as Bar<()>>::BarT: Bar<()>` is not satisfied
 --> src/main.rs:6:1
  |
6 | fn test<C: Bar<()>>() { }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar<()>` is not implemented for `<C as Bar<()>>::BarT`
  |
  = help: consider adding a `where <C as Bar<()>>::BarT: Bar<()>` bound
  = note: required by `Bar`

despite the C::BarT: Bar<()> bound being required by the definition of Bar itself, and in fact this means that the trait Bar<T> can never be mentioned.

This similar example (playground) that doesn't use an associated type in the trait parameter compiles:

trait Foo { type FooT: Foo; }
impl Foo for () { type FooT = (); }
trait Bar<T: Foo> { type BarT: Bar<T>; }
impl Bar<()> for () { type BarT = (); }

fn test<C: Bar<()>>() { }

while this version (playground), which uses a third trait to avoid the self-reference, does not:

trait Foo { type FooT: Foo; }
impl Foo for () { type FooT = (); }
trait Bar<T: Foo> { type BarT: Baz<T::FooT>; }
impl Bar<()> for () { type BarT = (); }
trait Baz<T: Foo> { }
impl Baz<()> for () { }

fn test<C: Bar<()>>() { }

Is this just a missing normalization step?

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 26, 2017
@Marwes
Copy link
Contributor

Marwes commented Aug 1, 2017

Pretty sure I encountered the same bug when specifying an associated type explicitly in a signature.

pub trait Param<P> {
    fn param(p: P) -> Self;
}

pub trait Test: Sized {
    type T: Param<Self::Item>;
    type Item;
}

// Compiles
fn test<T: Test>(p: T::Item) -> T::T {
    T::T::param(p)
}

// Does not compile
fn test2<T: Test<Item = u8>>(p: T::Item) -> T::T {
    T::T::param(p)
}

fn main() {
}
Compiling playground v0.0.1 (file:///playground)
error[E0277]: the trait bound `<T as Test>::T: Param<u8>` is not satisfied
  --> src/main.rs:15:1
   |
15 | / fn test2<T: Test<Item = u8>>(p: T::Item) -> T::T {
16 | |     T::T::param(p)
17 | | }
   | |_^ the trait `Param<u8>` is not implemented for `<T as Test>::T`
   |
   = help: consider adding a `where <T as Test>::T: Param<u8>` bound
   = note: required by `Test`

error: aborting due to previous error

error: Could not compile `playground`.

To learn more, run the command again with --verbose.

https://play.rust-lang.org/?gist=20c9d87e34aecc76754bc687734e00c5&version=nightly

Twey added a commit to Twey/rust that referenced this issue Aug 4, 2017
@shepmaster
Copy link
Member

/cc @arielb1 you wanted to ensure this test case fell into the trait system rewrite.

@rkarp
Copy link
Contributor

rkarp commented Dec 10, 2017

I've just run into this as well, it seems. Here's a very simple example:

trait Foo {
    type Item;
    type FnOfItem: Fn(Self::Item);
}

fn test<T>()
where
    T: Foo<Item = usize>,
    //T::FnOfItem: Fn(T::Item), // <-- Compile error without this
{}

fn main() {}
error[E0277]: the trait bound `<T as Foo>::FnOfItem: std::ops::Fn<(usize,)>` is not satisfied
  --> src/main.rs:6:1
   |
6  | / fn test<T>()
7  | | where
8  | |     T: Foo<Item = usize>,
9  | |     //T::FnOfItem: Fn(T::Item), // <-- Compile error without this
10 | | {}
   | |__^ the trait `std::ops::Fn<(usize,)>` is not implemented for `<T as Foo>::FnOfItem`
   |
   = help: consider adding a `where <T as Foo>::FnOfItem: std::ops::Fn<(usize,)>` bound
   = note: required by `Foo`

https://play.rust-lang.org/?gist=add5141b26dc781bd27c5b09c8c14f2d&version=nightly

@estebank estebank added A-associated-items Area: Associated items (types, constants & functions) F-associated_type_bounds `#![feature(associated_type_bounds)]` T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Nov 5, 2019
yvt added a commit to r3-os/r3 that referenced this issue Jun 9, 2020
The modification to `constance_port_std` in this commit is a work-around
for <rust-lang/rust#43475>.
@jonas-schievink jonas-schievink removed the F-associated_type_bounds `#![feature(associated_type_bounds)]` label Jan 28, 2021
JohnTitor added a commit to JohnTitor/rust that referenced this issue Feb 2, 2021
Add some tests for associated-type-bounds issues

Closes rust-lang#38917
Closes rust-lang#40093
Closes rust-lang#43475
Closes rust-lang#63591

rust-lang#47897 is likely closable too, but it needs an MCVE
~~rust-lang#38917, rust-lang#40093, rust-lang#43475, rust-lang#47897 all are mislabeled and shouldn't have the `F-associated-type-bounds` label~~

~~rust-lang#71685 is also mislabeled as commented on in that thread~~
@bors bors closed this as completed in a61e6ab Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants