Auto merge of #90645 - terrarier2111:master, r=estebank
Implement diagnostic for String conversion This is my first real contribution to rustc, any feedback is highly appreciated. This should fix https://github.com/rust-lang/rust/issues/89856 Thanks to `@estebank` for guiding me.
This commit is contained in:
commit
d5a0c7cb03
3 changed files with 85 additions and 36 deletions
|
@ -14,6 +14,7 @@ use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty::{self, Binder, Ty};
|
use rustc_middle::ty::{self, Binder, Ty};
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
|
|
||||||
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
@ -232,6 +233,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let is_struct_pat_shorthand_field =
|
let is_struct_pat_shorthand_field =
|
||||||
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
|
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
|
||||||
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
|
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
|
||||||
|
if !methods.is_empty() {
|
||||||
if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
|
if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
|
||||||
let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods)
|
let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods)
|
||||||
.filter_map(|(receiver, method)| {
|
.filter_map(|(receiver, method)| {
|
||||||
|
@ -249,7 +251,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
format!("{}{}", &receiver[..max_len], method_call),
|
format!("{}{}", &receiver[..max_len], method_call),
|
||||||
)]
|
)]
|
||||||
} else {
|
} else {
|
||||||
if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
|
if expr.precedence().order()
|
||||||
|
< ExprPrecedence::MethodCall.order()
|
||||||
|
{
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), "(".to_string()),
|
(expr.span.shrink_to_lo(), "(".to_string()),
|
||||||
(expr.span.shrink_to_hi(), format!("){}", method_call)),
|
(expr.span.shrink_to_hi(), format!("){}", method_call)),
|
||||||
|
@ -276,6 +280,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if found.to_string().starts_with("Option<")
|
||||||
|
&& expected.to_string() == "Option<&str>"
|
||||||
|
{
|
||||||
|
if let ty::Adt(_def, subst) = found.kind() {
|
||||||
|
if subst.len() != 0 {
|
||||||
|
if let GenericArgKind::Type(ty) = subst[0].unpack() {
|
||||||
|
let peeled = ty.peel_refs().to_string();
|
||||||
|
if peeled == "String" {
|
||||||
|
let ref_cnt = ty.to_string().len() - peeled.len();
|
||||||
|
let result = format!(".map(|x| &*{}x)", "*".repeat(ref_cnt));
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
expr.span.shrink_to_hi(),
|
||||||
|
"try converting the passed type into a `&str`",
|
||||||
|
result,
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
src/test/ui/typeck/issue-89856.rs
Normal file
8
src/test/ui/typeck/issue-89856.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let string = String::from("Hello, world");
|
||||||
|
let option = Some(&string);
|
||||||
|
take_str_maybe(option);
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
}
|
16
src/test/ui/typeck/issue-89856.stderr
Normal file
16
src/test/ui/typeck/issue-89856.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-89856.rs:6:20
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option);
|
||||||
|
| ^^^^^^ expected `str`, found struct `String`
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<&str>`
|
||||||
|
found enum `Option<&String>`
|
||||||
|
help: try converting the passed type into a `&str`
|
||||||
|
|
|
||||||
|
LL | take_str_maybe(option.map(|x| &**x));
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Reference in a new issue