Skip to content

Commit c927027

Browse files
authored
Rollup merge of #107633 - clubby789:option-string-coerce-fix, r=Nilstrieb
Fix suggestion for coercing Option<&String> to Option<&str> Fixes #107604 This also makes the diagnostic `MachineApplicable`, and runs `rustfix` to check we're not producing incorrect code. ``@rustbot`` label +A-diagnostics
2 parents d6f0c51 + f874f67 commit c927027

File tree

5 files changed

+88
-13
lines changed

5 files changed

+88
-13
lines changed

Diff for: compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,5 @@ hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang ite
6161
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
6262
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
6363
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
64+
65+
hir_typeck_convert_to_str = try converting the passed type into a `&str`

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::FnCtxt;
33
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
44
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
55
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
6-
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
6+
use rustc_errors::{fluent, Applicability, Diagnostic, MultiSpan};
77
use rustc_hir as hir;
88
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
99
use rustc_hir::lang_items::LangItem;
@@ -414,11 +414,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
414414
if let ty::Adt(adt, _) = peeled.kind()
415415
&& Some(adt.did()) == self.tcx.lang_items().string()
416416
{
417+
let sugg = if ref_cnt == 0 {
418+
".as_deref()"
419+
} else {
420+
".map(|x| x.as_str())"
421+
};
417422
err.span_suggestion_verbose(
418423
expr.span.shrink_to_hi(),
419-
"try converting the passed type into a `&str`",
420-
format!(".map(|x| &*{}x)", "*".repeat(ref_cnt)),
421-
Applicability::MaybeIncorrect,
424+
fluent::hir_typeck_convert_to_str,
425+
sugg,
426+
Applicability::MachineApplicable,
422427
);
423428
return true;
424429
}

Diff for: tests/ui/typeck/issue-89856.fixed

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// run-rustfix
2+
3+
fn take_str_maybe(_: Option<&str>) { }
4+
fn main() {
5+
let string = String::from("Hello, world");
6+
7+
let option: Option<String> = Some(string.clone());
8+
take_str_maybe(option.as_deref());
9+
//~^ ERROR: mismatched types [E0308]
10+
11+
let option_ref = Some(&string);
12+
take_str_maybe(option_ref.map(|x| x.as_str()));
13+
//~^ ERROR: mismatched types [E0308]
14+
15+
let option_ref_ref = option_ref.as_ref();
16+
take_str_maybe(option_ref_ref.map(|x| x.as_str()));
17+
//~^ ERROR: mismatched types [E0308]
18+
}

Diff for: tests/ui/typeck/issue-89856.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
1+
// run-rustfix
22

3+
fn take_str_maybe(_: Option<&str>) { }
34
fn main() {
45
let string = String::from("Hello, world");
5-
let option = Some(&string);
6+
7+
let option: Option<String> = Some(string.clone());
68
take_str_maybe(option);
79
//~^ ERROR: mismatched types [E0308]
10+
11+
let option_ref = Some(&string);
12+
take_str_maybe(option_ref);
13+
//~^ ERROR: mismatched types [E0308]
14+
15+
let option_ref_ref = option_ref.as_ref();
16+
take_str_maybe(option_ref_ref);
17+
//~^ ERROR: mismatched types [E0308]
818
}

Diff for: tests/ui/typeck/issue-89856.stderr

+47-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,63 @@
11
error[E0308]: mismatched types
2-
--> $DIR/issue-89856.rs:6:20
2+
--> $DIR/issue-89856.rs:8:20
33
|
44
LL | take_str_maybe(option);
5-
| -------------- ^^^^^^ expected `Option<&str>`, found `Option<&String>`
5+
| -------------- ^^^^^^ expected `Option<&str>`, found `Option<String>`
6+
| |
7+
| arguments to this function are incorrect
8+
|
9+
= note: expected enum `Option<&str>`
10+
found enum `Option<String>`
11+
note: function defined here
12+
--> $DIR/issue-89856.rs:3:4
13+
|
14+
LL | fn take_str_maybe(_: Option<&str>) { }
15+
| ^^^^^^^^^^^^^^ ---------------
16+
help: try converting the passed type into a `&str`
17+
|
18+
LL | take_str_maybe(option.as_deref());
19+
| +++++++++++
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/issue-89856.rs:12:20
23+
|
24+
LL | take_str_maybe(option_ref);
25+
| -------------- ^^^^^^^^^^ expected `Option<&str>`, found `Option<&String>`
626
| |
727
| arguments to this function are incorrect
828
|
929
= note: expected enum `Option<&str>`
1030
found enum `Option<&String>`
1131
note: function defined here
12-
--> $DIR/issue-89856.rs:1:4
32+
--> $DIR/issue-89856.rs:3:4
33+
|
34+
LL | fn take_str_maybe(_: Option<&str>) { }
35+
| ^^^^^^^^^^^^^^ ---------------
36+
help: try converting the passed type into a `&str`
37+
|
38+
LL | take_str_maybe(option_ref.map(|x| x.as_str()));
39+
| ++++++++++++++++++++
40+
41+
error[E0308]: mismatched types
42+
--> $DIR/issue-89856.rs:16:20
43+
|
44+
LL | take_str_maybe(option_ref_ref);
45+
| -------------- ^^^^^^^^^^^^^^ expected `Option<&str>`, found `Option<&&String>`
46+
| |
47+
| arguments to this function are incorrect
48+
|
49+
= note: expected enum `Option<&str>`
50+
found enum `Option<&&String>`
51+
note: function defined here
52+
--> $DIR/issue-89856.rs:3:4
1353
|
14-
LL | fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
54+
LL | fn take_str_maybe(_: Option<&str>) { }
1555
| ^^^^^^^^^^^^^^ ---------------
1656
help: try converting the passed type into a `&str`
1757
|
18-
LL | take_str_maybe(option.map(|x| &**x));
19-
| ++++++++++++++
58+
LL | take_str_maybe(option_ref_ref.map(|x| x.as_str()));
59+
| ++++++++++++++++++++
2060

21-
error: aborting due to previous error
61+
error: aborting due to 3 previous errors
2262

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

0 commit comments

Comments
 (0)