Fix suggestion for coercing Option<&String> to Option<&str>
This commit is contained in:
parent
5d32458343
commit
f874f6768c
5 changed files with 88 additions and 13 deletions
|
@ -61,3 +61,5 @@ hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang ite
|
||||||
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
|
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
|
||||||
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
|
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
|
||||||
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
|
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||||
|
|
||||||
|
hir_typeck_convert_to_str = try converting the passed type into a `&str`
|
||||||
|
|
|
@ -3,7 +3,7 @@ use super::FnCtxt;
|
||||||
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
|
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
|
||||||
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
|
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
|
||||||
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
||||||
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
|
use rustc_errors::{fluent, Applicability, Diagnostic, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
|
@ -414,11 +414,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let ty::Adt(adt, _) = peeled.kind()
|
if let ty::Adt(adt, _) = peeled.kind()
|
||||||
&& Some(adt.did()) == self.tcx.lang_items().string()
|
&& Some(adt.did()) == self.tcx.lang_items().string()
|
||||||
{
|
{
|
||||||
|
let sugg = if ref_cnt == 0 {
|
||||||
|
".as_deref()"
|
||||||
|
} else {
|
||||||
|
".map(|x| x.as_str())"
|
||||||
|
};
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
expr.span.shrink_to_hi(),
|
expr.span.shrink_to_hi(),
|
||||||
"try converting the passed type into a `&str`",
|
fluent::hir_typeck_convert_to_str,
|
||||||
format!(".map(|x| &*{}x)", "*".repeat(ref_cnt)),
|
sugg,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
18
tests/ui/typeck/issue-89856.fixed
Normal file
18
tests/ui/typeck/issue-89856.fixed
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
fn take_str_maybe(_: Option<&str>) { }
|
||||||
|
fn main() {
|
||||||
|
let string = String::from("Hello, world");
|
||||||
|
|
||||||
|
let option: Option<String> = Some(string.clone());
|
||||||
|
take_str_maybe(option.as_deref());
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
|
let option_ref = Some(&string);
|
||||||
|
take_str_maybe(option_ref.map(|x| x.as_str()));
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
|
let option_ref_ref = option_ref.as_ref();
|
||||||
|
take_str_maybe(option_ref_ref.map(|x| x.as_str()));
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
}
|
|
@ -1,8 +1,18 @@
|
||||||
fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
|
// run-rustfix
|
||||||
|
|
||||||
|
fn take_str_maybe(_: Option<&str>) { }
|
||||||
fn main() {
|
fn main() {
|
||||||
let string = String::from("Hello, world");
|
let string = String::from("Hello, world");
|
||||||
let option = Some(&string);
|
|
||||||
|
let option: Option<String> = Some(string.clone());
|
||||||
take_str_maybe(option);
|
take_str_maybe(option);
|
||||||
//~^ ERROR: mismatched types [E0308]
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
|
let option_ref = Some(&string);
|
||||||
|
take_str_maybe(option_ref);
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
|
let option_ref_ref = option_ref.as_ref();
|
||||||
|
take_str_maybe(option_ref_ref);
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,63 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-89856.rs:6:20
|
--> $DIR/issue-89856.rs:8:20
|
||||||
|
|
|
|
||||||
LL | take_str_maybe(option);
|
LL | take_str_maybe(option);
|
||||||
| -------------- ^^^^^^ expected `Option<&str>`, found `Option<&String>`
|
| -------------- ^^^^^^ expected `Option<&str>`, found `Option<String>`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<&str>`
|
||||||
|
found enum `Option<String>`
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/issue-89856.rs:3:4
|
||||||
|
|
|
||||||
|
LL | fn take_str_maybe(_: Option<&str>) { }
|
||||||
|
| ^^^^^^^^^^^^^^ ---------------
|
||||||
|
help: try converting the passed type into a `&str`
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option.as_deref());
|
||||||
|
| +++++++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-89856.rs:12:20
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option_ref);
|
||||||
|
| -------------- ^^^^^^^^^^ expected `Option<&str>`, found `Option<&String>`
|
||||||
| |
|
| |
|
||||||
| arguments to this function are incorrect
|
| arguments to this function are incorrect
|
||||||
|
|
|
|
||||||
= note: expected enum `Option<&str>`
|
= note: expected enum `Option<&str>`
|
||||||
found enum `Option<&String>`
|
found enum `Option<&String>`
|
||||||
note: function defined here
|
note: function defined here
|
||||||
--> $DIR/issue-89856.rs:1:4
|
--> $DIR/issue-89856.rs:3:4
|
||||||
|
|
|
|
||||||
LL | fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
|
LL | fn take_str_maybe(_: Option<&str>) { }
|
||||||
| ^^^^^^^^^^^^^^ ---------------
|
| ^^^^^^^^^^^^^^ ---------------
|
||||||
help: try converting the passed type into a `&str`
|
help: try converting the passed type into a `&str`
|
||||||
|
|
|
|
||||||
LL | take_str_maybe(option.map(|x| &**x));
|
LL | take_str_maybe(option_ref.map(|x| x.as_str()));
|
||||||
| ++++++++++++++
|
| ++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-89856.rs:16:20
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option_ref_ref);
|
||||||
|
| -------------- ^^^^^^^^^^^^^^ expected `Option<&str>`, found `Option<&&String>`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<&str>`
|
||||||
|
found enum `Option<&&String>`
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/issue-89856.rs:3:4
|
||||||
|
|
|
||||||
|
LL | fn take_str_maybe(_: Option<&str>) { }
|
||||||
|
| ^^^^^^^^^^^^^^ ---------------
|
||||||
|
help: try converting the passed type into a `&str`
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option_ref_ref.map(|x| x.as_str()));
|
||||||
|
| ++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue