Skip to content

Compiler unable to apply trait bound #57905

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
grantslatton opened this issue Jan 25, 2019 · 4 comments
Open

Compiler unable to apply trait bound #57905

grantslatton opened this issue Jan 25, 2019 · 4 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-trait-system Area: Trait system A-type-system Area: Type system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@grantslatton
Copy link

Sorry for the vague title, please change. I have found a strange bug that is at the intersection of associated types, trait type parameters, and method type parameters.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=8584b2c75acb51a8c6082b668649ad29

trait Example {
    type Foo;
    
    fn foo<T: AsRef<Self::Foo>>(&self, t: T);
}

impl <A, B> Example for (A, B) where
    A: Iterator<Item = u32>,
    B: AsRef<A::Item>,
{
    type Foo = ();
    
    fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}

}

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `B: std::convert::AsRef<u32>` is not satisfied
  --> src/main.rs:14:5
   |
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::AsRef<u32>` is not implemented for `B`
   |
   = help: consider adding a `where B: std::convert::AsRef<u32>` bound
   = note: required because of the requirements on the impl of `Example` for `(A, B)`

error[E0277]: the trait bound `T: std::convert::AsRef<()>` is not satisfied
  --> src/main.rs:14:5
   |
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::AsRef<()>` is not implemented for `T`
   |
   = help: consider adding a `where T: std::convert::AsRef<()>` bound
   = note: required by `std::convert::AsRef`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `playground`.

Commenting out line 10 B: AsRef<A::Item> makes the program compile, or changing it to B: AsRef<u32> makes it compile (even though A::Item is a u32).

@Centril Centril added A-type-system Area: Type system A-trait-system Area: Trait system A-associated-items Area: Associated items (types, constants & functions) labels Jan 25, 2019
@TommasoBianchi
Copy link
Contributor

As a side note, the following variation of the code does not compile (with the same errors):

trait Example {
    type Foo;
    
    fn foo<T: AsRef<()>>(&self, t: T);
}

impl <A, B> Example for (A, B) where
    A: Iterator<Item = u32>,
    B: AsRef<A::Item>,
{
    type Foo = ();
    
    fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
}

while the following compiles with no problems:

trait Example {
    type Foo;
    
    fn foo<T: AsRef<()>>(&self, t: T);
}

impl <A, B> Example for (A, B) where
    A: Iterator<Item = u32>,
    B: AsRef<A::Item>,
{
    type Foo = ();
    
    fn foo<T: AsRef<()>>(&self, t: T) {}
}

It almost seems that the compiler is not able to manage two associate types substitutions at the same time. I might try to give a look at the internals in the next days and see if I can find the actual problem.

@estebank
Copy link
Contributor

Current output:

error[E0277]: the trait bound `B: std::convert::AsRef<u32>` is not satisfied
  --> src/main.rs:14:5
   |
10 |     B: AsRef<A::Item>,
   |                       - help: consider further restricting type parameter `B`: `, B: std::convert::AsRef<u32>`
...
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::AsRef<u32>` is not implemented for `B`
   |
   = note: required because of the requirements on the impl of `Example` for `(A, B)`

error[E0277]: the trait bound `T: std::convert::AsRef<()>` is not satisfied
  --> src/main.rs:14:5
   |
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |     ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |     |      |
   |     |      help: consider further restricting this bound: `T: std::convert::AsRef<()> +`
   |     the trait `std::convert::AsRef<()>` is not implemented for `T`
   |
   = note: required by `std::convert::AsRef`

@estebank estebank added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Dec 13, 2019
@Trolldemorted
Copy link
Contributor

It has been over a year, can you estimate when this will be fixed?

@estebank
Copy link
Contributor

estebank commented Feb 9, 2021

Triage: current output:

error[E0277]: the trait bound `B: AsRef<u32>` is not satisfied
  --> src/main.rs:14:5
   |
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<u32>` is not implemented for `B`
   |
   = note: required because of the requirements on the impl of `Example` for `(A, B)`
help: consider further restricting this bound
   |
10 |     B: AsRef<A::Item> + AsRef<u32>,
   |                       ^^^^^^^^^^^^

error[E0277]: the trait bound `B: AsRef<u32>` is not satisfied
  --> src/main.rs:14:8
   |
14 |     fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
   |        ^^^ the trait `AsRef<u32>` is not implemented for `B`
   |
   = note: required because of the requirements on the impl of `Example` for `(A, B)`
help: consider further restricting this bound
   |
10 |     B: AsRef<A::Item> + AsRef<u32>,
   |                       ^^^^^^^^^^^^

error[E0277]: the trait bound `T: AsRef<()>` is not satisfied
   --> src/main.rs:14:15
    |
14  |       fn foo<T: AsRef<Self::Foo>>(&self, t: T) {}
    |                 ^^^^^^^^^^^^^^^^ the trait `AsRef<()>` is not implemented for `T`
    |
help: consider further restricting this bound
    |
14  |     fn foo<T: AsRef<Self::Foo> + AsRef<()>>(&self, t: T) {}
    |                                ^^^^^^^^^^^

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-trait-system Area: Trait system A-type-system Area: Type system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants