fix #105494, Suggest remove last method call when type coerce with expected

This commit is contained in:
yukang 2022-12-18 02:56:56 +08:00
parent daccb3d974
commit 459b234e6a
4 changed files with 97 additions and 0 deletions

View File

@ -38,6 +38,7 @@ pub fn emit_type_mismatch_suggestions(
// Use `||` to give these suggestions a precedence // Use `||` to give these suggestions a precedence
let _ = self.suggest_missing_parentheses(err, expr) let _ = self.suggest_missing_parentheses(err, expr)
|| self.suggest_remove_last_method_call(err, expr, expected)
|| self.suggest_associated_const(err, expr, expected) || self.suggest_associated_const(err, expr, expected)
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|| self.suggest_option_to_bool(err, expr, expr_ty, expected) || self.suggest_option_to_bool(err, expr, expr_ty, expected)

View File

@ -329,6 +329,26 @@ pub fn suggest_two_fn_call(
} }
} }
pub fn suggest_remove_last_method_call(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>,
) -> bool {
if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind &&
let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) &&
self.can_coerce(recv_ty, expected) {
err.span_suggestion_verbose(
expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1)),
"try removing the method call",
"",
Applicability::MachineApplicable,
);
return true;
}
false
}
pub fn suggest_deref_ref_or_into( pub fn suggest_deref_ref_or_into(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,

View File

@ -0,0 +1,22 @@
fn test1() {
let _v: i32 = (1 as i32).to_string(); //~ ERROR mismatched types
// won't suggestion
let _v: i32 = (1 as i128).to_string(); //~ ERROR mismatched types
let _v: &str = "foo".to_string(); //~ ERROR mismatched types
}
fn test2() {
let mut path: String = "/usr".to_string();
let folder: String = "lib".to_string();
path = format!("{}/{}", path, folder).as_str(); //~ ERROR mismatched types
println!("{}", &path);
}
fn main() {
test1();
test2();
}

View File

@ -0,0 +1,54 @@
error[E0308]: mismatched types
--> $DIR/issue-105494.rs:2:19
|
LL | let _v: i32 = (1 as i32).to_string();
| --- ^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String`
| |
| expected due to this
|
help: try removing the method call
|
LL - let _v: i32 = (1 as i32).to_string();
LL + let _v: i32 = (1 as i32);
|
error[E0308]: mismatched types
--> $DIR/issue-105494.rs:5:19
|
LL | let _v: i32 = (1 as i128).to_string();
| --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String`
| |
| expected due to this
error[E0308]: mismatched types
--> $DIR/issue-105494.rs:7:20
|
LL | let _v: &str = "foo".to_string();
| ---- ^^^^^^^^^^^^^^^^^ expected `&str`, found struct `String`
| |
| expected due to this
|
help: try removing the method call
|
LL - let _v: &str = "foo".to_string();
LL + let _v: &str = "foo";
|
error[E0308]: mismatched types
--> $DIR/issue-105494.rs:14:12
|
LL | let mut path: String = "/usr".to_string();
| ------ expected due to this type
...
LL | path = format!("{}/{}", path, folder).as_str();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&str`
|
help: try removing the method call
|
LL - path = format!("{}/{}", path, folder).as_str();
LL + path = format!("{}/{}", path, folder);
|
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.