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

Compiler unable to apply trait bound #57905

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

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) 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