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

Calling and_then on Option<String> with a function that takes &str could provide a more helpful diagnostic #106342

Closed
Kampfkarren opened this issue Jan 1, 2023 · 1 comment · Fixed by #111659
Assignees
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

@Kampfkarren
Copy link
Contributor

Kampfkarren commented Jan 1, 2023

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

fn produces_string() -> Option<String> {
    Some("my cool string".to_owned())
}

fn takes_str(x: &str) -> Option<()> {
    Some(())
}

fn main() {
    let x = produces_string().and_then(takes_str);
}

The current output is:

error[[E0631]](https://doc.rust-lang.org/stable/error-index.html#E0631): type mismatch in function arguments
  --> src/main.rs:10:40
   |
5  | fn takes_str(x: &str) -> Option<()> {
   | ----------------------------------- found signature defined here
...
10 |     let x = produces_string().and_then(takes_str);
   |                               -------- ^^^^^^^^^ expected due to this
   |                               |
   |                               required by a bound introduced by this call
   |
   = note: expected function signature `fn(String) -> _`
              found function signature `for<'a> fn(&'a str) -> _`
note: required by a bound in `Option::<T>::and_then`

The solution is to change:

-let x = produces_string().and_then(takes_str);
+let x = produces_string().as_deref().and_then(takes_str);

It would be nice if rustc told me this.

@Kampfkarren Kampfkarren 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 Jan 1, 2023
@y21
Copy link
Member

y21 commented May 14, 2023

@rustbot claim

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 3, 2023
suggest `Option::as_deref(_mut)` on type mismatch in option combinator if it passes typeck

Fixes rust-lang#106342.
This adds a suggestion to call `.as_deref()` (or `.as_deref_mut()` resp.) if typeck fails due to a type mismatch in the function passed to an `Option` combinator such as `.map()` or `.and_then()`.
For example:
```rs
fn foo(_: &str) {}
Some(String::new()).map(foo);
```
The `.map()` method requires its argument to satisfy `F: FnOnce(String)`, but it received `fn(&str)`, which won't pass. However, placing a `.as_deref()` before the `.map()` call fixes this since `&str == &<String as Deref>::Target`
@bors bors closed this as completed in 91f222f Jun 3, 2023
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.

2 participants