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

help clause points to adding where clause on impl when it should be on function #104089

Open
OneRaynyDay opened this issue Nov 7, 2022 · 0 comments · May be fixed by #134937
Open

help clause points to adding where clause on impl when it should be on function #104089

OneRaynyDay opened this issue Nov 7, 2022 · 0 comments · May be fixed by #134937
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@OneRaynyDay
Copy link

OneRaynyDay commented Nov 7, 2022

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e5d9c21342f0c0824ddba9445daf7cb1

struct A {
    x: String
}

struct B {
    x: String
}

impl From<A> for B {
    fn from(a: A) -> Self {
        B { x: a.x }
    }
}

impl B {
    pub fn from_many<T: Into<B> + Clone>(v: Vec<T>) -> Self {
        B { x: v.iter().map(|e| B::from(e.clone()).x).collect::<Vec<String>>().join(" ") }
    }
}

fn main() {
    let b: B = B { x: "foobar".to_string() };
    let a: A = A { x: "frob".to_string() };
    let ab: B = a.into();
    println!("Hello, {}!", ab.x);
}

The current output is:

error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the trait bound `B: From<T>` is not satisfied
  --> src/main.rs:17:41
   |
17 |         B { x: v.iter().map(|e| B::from(e.clone()).x).collect::<Vec<String>>().join(" ") }
   |                                 ------- ^^^^^^^^^ the trait `From<T>` is not implemented for `B`
   |                                 |
   |                                 required by a bound introduced by this call
   |
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
15 | impl B where B: From<T> {
   |        ++++++++++++++++

Ideally the output should look like:

...
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
pub fn from_many<T: Into<B> + Clone>(v: Vec<T>) -> Self
where B: From<T> {
...
}

link to stack overflow: https://stackoverflow.com/questions/74342563/convert-vector-of-type-a-to-type-b-where-a-is-convertible-to-b?noredirect=1#comment131245422_74342563

@OneRaynyDay OneRaynyDay 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 Nov 7, 2022
@estebank estebank added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-papercut Diagnostics: An error or lint that needs small tweaks. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels Nov 8, 2022
estebank added a commit to estebank/rust that referenced this issue Dec 30, 2024
When encountering a missing bound that involves a type parameter, on associated functions we look at the generics to see if the type parameter is present. If so, we suggest the bound on the associated function instead of on the impl/trait. At the impl/trait doesn't have another type parameter of that name, then we don't suggest the bound at that item level.

```
error[E0277]: the trait bound `B: From<T>` is not satisfied
  --> $DIR/suggest-restriction-involving-type-param.rs:20:33
   |
LL |         B { x: v.iter().map(|e| B::from(e.clone()).x).collect::<Vec<String>>().join(" ") }
   |                                 ^ the trait `From<T>` is not implemented for `B`
   |
help: consider further restricting the type
   |
LL |     pub fn from_many<T: Into<B> + Clone>(v: Vec<T>) -> Self where B: From<T> {
   |                                                             ++++++++++++++++
```

Fix rust-lang#104089.
@estebank estebank linked a pull request Dec 30, 2024 that will close this issue
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-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-papercut Diagnostics: An error or lint that needs small tweaks. 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.

2 participants