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 in higher-rank trait bounds cause unexpected E0227 and useless help #94160

Closed
Toru3 opened this issue Feb 19, 2022 · 9 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Toru3
Copy link

Toru3 commented Feb 19, 2022

Given the following code: code in playground

use std::ops::Add;

fn add<T>(a: T, b: T) -> T
where
    T: for<'x> From<<&'x T as Add>::Output>,
    for<'x> &'x T: Add,
{
    T::from(&a + &b)
}

fn main() {
    add(1i32, 2i32); // E0227 with useless help
    //add::<i32>(1i32, 2i32); // works
}

The current output is:

error[E0277]: the trait bound `for<'x> i32: From<<&'x i32 as Add>::Output>` is not satisfied
  --> src/main.rs:12:5
   |
12 |     add(1i32, 2i32); // E0227 with useless help
   |     ^^^ the trait `for<'x> From<<&'x i32 as Add>::Output>` is not implemented for `i32`
   |
note: required by a bound in `add`
  --> src/main.rs:5:8
   |
3  | fn add<T>(a: T, b: T) -> T
   |    --- required by a bound in this
4  | where
5  |     T: for<'x> From<<&'x T as Add>::Output>,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `add`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
   |
11 | fn main() where i32: for<'x> From<<&'x i32 as Add>::Output> {
   |           +++++++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

Ideally the help should look like:

help: consider introducing the explicit type `::<i32>`
   |
12 |     add::<i32>(1i32, 2i32); // E0227 with useless help
   |        +++++++

Not higher-rank trait bounds (below code) is compiled successfully.

use std::ops::Add;

fn add<T>(a: T, b: T) -> T
where
    T: From<<T as Add>::Output> + Add,
{
    T::from(a + b)
}

fn main() {
    add(1i32, 2i32); // works
}
@Toru3 Toru3 added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 19, 2022
@compiler-errors
Copy link
Member

compiler-errors commented Feb 19, 2022

This is fixed by #94070, and thus (likely but not checked) also fixed by #90887 (since those are basically equivalent).

Ideally the help should look like: [...]

While this does fix the compiler error here, I am somewhat doubtful that we could make the compiler give this feedback in general. This issue is really just because the compiler has troubles with associated types that have higher-ranked lifetimes in them, which the two PRs mentioned above alleviate a bit.

@Toru3
Copy link
Author

Toru3 commented Feb 20, 2022

If this compiles successfully, that's good enough for me. (There is no need to display help.)

@Toru3
Copy link
Author

Toru3 commented Feb 20, 2022

This issue seems same as #90729. Should I close this issue?

@compiler-errors
Copy link
Member

I would argue that this is sufficiently different from #90729, since it doesn't require #![feature(generic_associated_types)]. Feel free to keep it open.

@Toru3
Copy link
Author

Toru3 commented Feb 20, 2022

I understand.

@Toru3
Copy link
Author

Toru3 commented Feb 20, 2022

FYI

use std::ops::Add;

fn ref_add<'a, T>(a: &'a T, b: &'a T) -> T
where
    T: From<<&'a T as Add>::Output>,
    &'a T: Add,
{
    T::from(a + b)
}

fn ref_add_hrtb<T>(a: &T, b: &T) -> T
where
    T: for<'x> From<<&'x T as Add>::Output>,
    for<'x> &'x T: Add,
{
    T::from(a + b)
}

fn main() {
    let a = 2i32;
    let b = 3i32;
    assert_eq!(ref_add(&a, &b), 5i32); // pass
    assert_eq!(ref_add_hrtb(&a, &b), 5i32); // E0277
}

above code generate below output.

error[E0277]: the trait bound `for<'x> i32: From<<&'x i32 as Add>::Output>` is not satisfied
  --> src/main.rs:23:16
   |
23 |     assert_eq!(ref_add_hrtb(&a, &b), 5i32); // E0277
   |                ^^^^^^^^^^^^ the trait `for<'x> From<<&'x i32 as Add>::Output>` is not implemented for `i32`
   |
note: required by a bound in `ref_add_hrtb`
  --> src/main.rs:13:8
   |
11 | fn ref_add_hrtb<T>(a: &T, b: &T) -> T
   |    ------------ required by a bound in this
12 | where
13 |     T: for<'x> From<<&'x T as Add>::Output>,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ref_add_hrtb`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
   |
19 | fn main() where i32: for<'x> From<<&'x i32 as Add>::Output> {
   |           +++++++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

@jackh726
Copy link
Member

jackh726 commented Mar 8, 2022

I think this was fixed in #90887, but needs to be confirmed.

@compiler-errors
Copy link
Member

@jackh726, confirmed fixed on master.

@Toru3
Copy link
Author

Toru3 commented Mar 9, 2022

I confirmed fixed on nightly(1eb7258 2022-03-08). 🎉

@Toru3 Toru3 closed this as completed Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants