Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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