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

E0277 incorrect suggested where bound when type is impl Trait argument #86488

Open
delan opened this issue Jun 20, 2021 · 7 comments
Open

E0277 incorrect suggested where bound when type is impl Trait argument #86488

delan opened this issue Jun 20, 2021 · 7 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-trait-system Area: Trait system D-lack-of-suggestion Diagnostics: Adding a (structured) suggestion would increase the quality of the diagnostic. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@delan
Copy link
Contributor

delan commented Jun 20, 2021

Given the following code (playground):

trait Foo: Copy {
    type Result;
    fn foo(self) -> Self::Result;
}

fn bar(foo: impl Foo) {
    let _: () = foo.into();
    let _: () = foo.foo().into();
}

The current output is:

error[E0277]: the trait bound `(): From<impl Foo>` is not satisfied
 --> src/lib.rs:7:21
  |
7 |     let _: () = foo.into();
  |                     ^^^^ the trait `From<impl Foo>` is not implemented for `()`
  |
  = note: required because of the requirements on the impl of `Into<()>` for `impl Foo`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar(foo: impl Foo) where (): From<impl Foo> {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `(): From<<impl Foo as Foo>::Result>` is not satisfied
 --> src/lib.rs:8:27
  |
8 |     let _: () = foo.foo().into();
  |                           ^^^^ the trait `From<<impl Foo as Foo>::Result>` is not implemented for `()`
  |
  = note: required because of the requirements on the impl of `Into<()>` for `<impl Foo as Foo>::Result`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar(foo: impl Foo) where (): From<<impl Foo as Foo>::Result> {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

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

Following either of those suggestions yields code that doesn’t compile, because impl Trait isn’t allowed in that position. Even if it becomes allowed someday, I feel like they would still be incorrect, since each impl Trait need not refer to the same type?

Ideally the output should look like:

[...]
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
6 | fn bar<F: Foo>(foo: F) where (): From<F> + From<<F as Foo>::Result> {
  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Examples are on stable (1.53.0), but this also affects 1.54.0-nightly (44456677b 2021-06-12).

@delan delan 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 Jun 20, 2021
@fmease fmease added the D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. label Feb 11, 2025
@fmease
Copy link
Member

fmease commented Feb 11, 2025

Current output:

error[E0277]: the trait bound `(): From<impl Foo>` is not satisfied
 --> src/lib.rs:7:21
  |
7 |     let _: () = foo.into();
  |                     ^^^^ the trait `From<impl Foo>` is not implemented for `()`
  |
  = note: required for `impl Foo` to implement `Into<()>`

error[E0277]: the trait bound `(): From<<impl Foo as Foo>::Result>` is not satisfied
 --> src/lib.rs:8:27
  |
8 |     let _: () = foo.foo().into();
  |                           ^^^^ the trait `From<<impl Foo as Foo>::Result>` is not implemented for `()`
  |
  = note: required for `<impl Foo as Foo>::Result` to implement `Into<()>`

@fmease
Copy link
Member

fmease commented Feb 11, 2025

We might want to bisect the reprogression to find the PR which fixed this in order to check if this should be added as a regression test or if this edge is sufficiently covered already (since it's kinda hard to grep for this in the test suite (ehh, maybe it's not too bad, not sure)).

@fmease fmease added E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc labels Feb 11, 2025
@moxian
Copy link
Contributor

moxian commented Mar 19, 2025

The diagnostic was introduced in #82194

cargo-rustc-bisect
********************************************************************************
Regression in nightly-2021-02-19
********************************************************************************

fetching https://static.rust-lang.org/dist/2021-02-18/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-02-18: 40 B / 40 B [=======================================================] 100.00 % 61.90 KB/s converted 2021-02-18 to 152f6609246558be5e2582e67376194815e6ba0d
fetching https://static.rust-lang.org/dist/2021-02-19/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-02-19: 40 B / 40 B [=======================================================] 100.00 % 67.91 KB/s converted 2021-02-19 to 0148b971c921a0831fbf3357e5936eec724e3566
looking for regression commit between 2021-02-18 and 2021-02-19
fetching (via remote github) commits from max(152f6609246558be5e2582e67376194815e6ba0d, 2021-02-16) to 0148b971c921a0831fbf3357e5936eec724e3566
ending github query because we found starting sha: 152f6609246558be5e2582e67376194815e6ba0d
get_commits_between returning commits, len: 7
  commit[0] 2021-02-17: Auto merge of #82235 - GuillaumeGomez:rollup-oflxc08, r=GuillaumeGomez
  commit[1] 2021-02-17: Auto merge of #81993 - flip1995:clippyup, r=Manishearth
  commit[2] 2021-02-18: Auto merge of #82241 - Dylan-DPC:rollup-munmzg5, r=Dylan-DPC
  commit[3] 2021-02-18: Auto merge of #81172 - SimonSapin:ptr-metadata, r=oli-obk
  commit[4] 2021-02-18: Auto merge of #82249 - JohnTitor:rollup-3jbqija, r=JohnTitor
  commit[5] 2021-02-18: Auto merge of #81574 - tmiasko:p, r=oli-obk
  commit[6] 2021-02-18: Auto merge of #82263 - Dylan-DPC:rollup-cypm2uw, r=Dylan-DPC
ERROR: no CI builds available between 152f6609246558be5e2582e67376194815e6ba0d and 0148b971c921a0831fbf3357e5936eec724e3566 within last 167 days

Which was later removed and "progressed" in #97778

cargo-bisect-rustc
********************************************************************************
Regression in nightly-2022-06-13
********************************************************************************

fetching https://static.rust-lang.org/dist/2022-06-12/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2022-06-12: 40 B / 40 B [=======================================================] 100.00 % 92.61 KB/s converted 2022-06-12 to 99930ac7f8cbb5d9b319b2e2e92794fd6f24f556
fetching https://static.rust-lang.org/dist/2022-06-13/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2022-06-13: 40 B / 40 B [=======================================================] 100.00 % 63.54 KB/s converted 2022-06-13 to 546c826f0ccaab36e897860205281f490db274e6
looking for regression commit between 2022-06-12 and 2022-06-13
fetching (via remote github) commits from max(99930ac7f8cbb5d9b319b2e2e92794fd6f24f556, 2022-06-10) to 546c826f0ccaab36e897860205281f490db274e6
ending github query because we found starting sha: 99930ac7f8cbb5d9b319b2e2e92794fd6f24f556
get_commits_between returning commits, len: 7
  commit[0] 2022-06-11: Auto merge of #95880 - cjgillot:def-ident-span, r=petrochenkov
  commit[1] 2022-06-11: Auto merge of #97705 - compiler-errors:guide-inference, r=lcnr
  commit[2] 2022-06-12: Auto merge of #97778 - compiler-errors:misc-diagnostics-tidy, r=cjgillot
  commit[3] 2022-06-12: Auto merge of #97993 - lengyijun:clean-variance, r=compiler-errors
  commit[4] 2022-06-12: Auto merge of #98025 - Dylan-DPC:rollup-cwt2hb7, r=Dylan-DPC
  commit[5] 2022-06-12: Auto merge of #97833 - tmiasko:borrowed-locals, r=nagisa
  commit[6] 2022-06-12: Auto merge of #98018 - scottmcm:miri-yeet, r=RalfJung
ERROR: no CI builds available between 99930ac7f8cbb5d9b319b2e2e92794fd6f24f556 and 546c826f0ccaab36e897860205281f490db274e6 within last 167 days

The fix did not add the test for this case as far as I see

@rustbot label: -E-needs-bisection +A-trait-system

@rustbot rustbot added A-trait-system Area: Trait system and removed E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc labels Mar 19, 2025
@fmease
Copy link
Member

fmease commented Mar 19, 2025

Thanks for the bisection!

I've checked PR #97778 and found tests/ui/suggestions/issue-97760.rs which checks exactly this case (I've manually verified it by running rustc 1.52). Closing as fixed by #97778.

@fmease fmease closed this as completed Mar 19, 2025
@fmease fmease removed the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Mar 19, 2025
@moxian
Copy link
Contributor

moxian commented Mar 20, 2025

My reading is that tests/ui/suggestions/issue-97760.rs is a different issue. The error therein on 1.52 is

error[E0277]: `<impl IntoIterator as IntoIterator>::Item` doesn't implement `std::fmt::Display`
 --> <source>:4:24
  |
4 |         println!("{}", x);
  |                        ^ `<impl IntoIterator as IntoIterator>::Item` cannot be formatted with the default formatter
  |
  = help: the trait `std::fmt::Display` is not implemented for `<impl IntoIterator as IntoIterator>::Item`
  = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
  = note: required by `std::fmt::Display::fmt`
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: introduce a type parameter with a trait bound instead of using `impl Trait`
  |
1 | pub fn print_values<I: IntoIterator>(values: &impl IntoIterator)
2 | where where <I as IntoIterator>::Item: std::fmt::Display {
  |

which is syntaxically incorrect (where where), not semantically (where (): Trait). This suggestion is also seemingly emitted in a different place - this current issue happens at rustc_middle::ty::diagnostics::suggest_arbitrary_trait_bound whereas #97760 is in rustc_trait_selection::traits::error_reporting::suggest_restriction

That said, I'm by no means an expert, so if it's obvious to you that the two issues are actually closely enough related and that there's no need for an extra regression test - then I would trust you on that.

@fmease
Copy link
Member

fmease commented Mar 20, 2025

Ah no, you're absolutely right, I was tired and misread the output

@fmease fmease reopened this Mar 20, 2025
@fmease fmease added D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. D-lack-of-suggestion Diagnostics: Adding a (structured) suggestion would increase the quality of the diagnostic. and removed D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. labels Mar 20, 2025
@fmease
Copy link
Member

fmease commented Mar 20, 2025

I've now also relabeled this issue: While we're no longer emitting an invalid suggestion, I guess it would be nice if it could suggest replying the APIT with a type parameter in addition to introducing new bounds (tho converting APITs is not always possible and can be a breaking change).

Free to add a regression test for the original issue (we should probably open a new issue for the above and keep this one E-needs-test).

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 A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-trait-system Area: Trait system D-lack-of-suggestion Diagnostics: Adding a (structured) suggestion would increase the quality of the diagnostic. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants