Skip to content

Commit 459b234

Browse files
committed
fix #105494, Suggest remove last method call when type coerce with expected
1 parent daccb3d commit 459b234

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3838

3939
// Use `||` to give these suggestions a precedence
4040
let _ = self.suggest_missing_parentheses(err, expr)
41+
|| self.suggest_remove_last_method_call(err, expr, expected)
4142
|| self.suggest_associated_const(err, expr, expected)
4243
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
4344
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+20
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
329329
}
330330
}
331331

332+
pub fn suggest_remove_last_method_call(
333+
&self,
334+
err: &mut Diagnostic,
335+
expr: &hir::Expr<'tcx>,
336+
expected: Ty<'tcx>,
337+
) -> bool {
338+
if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind &&
339+
let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) &&
340+
self.can_coerce(recv_ty, expected) {
341+
err.span_suggestion_verbose(
342+
expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1)),
343+
"try removing the method call",
344+
"",
345+
Applicability::MachineApplicable,
346+
);
347+
return true;
348+
}
349+
false
350+
}
351+
332352
pub fn suggest_deref_ref_or_into(
333353
&self,
334354
err: &mut Diagnostic,
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fn test1() {
2+
let _v: i32 = (1 as i32).to_string(); //~ ERROR mismatched types
3+
4+
// won't suggestion
5+
let _v: i32 = (1 as i128).to_string(); //~ ERROR mismatched types
6+
7+
let _v: &str = "foo".to_string(); //~ ERROR mismatched types
8+
}
9+
10+
fn test2() {
11+
let mut path: String = "/usr".to_string();
12+
let folder: String = "lib".to_string();
13+
14+
path = format!("{}/{}", path, folder).as_str(); //~ ERROR mismatched types
15+
16+
println!("{}", &path);
17+
}
18+
19+
fn main() {
20+
test1();
21+
test2();
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-105494.rs:2:19
3+
|
4+
LL | let _v: i32 = (1 as i32).to_string();
5+
| --- ^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String`
6+
| |
7+
| expected due to this
8+
|
9+
help: try removing the method call
10+
|
11+
LL - let _v: i32 = (1 as i32).to_string();
12+
LL + let _v: i32 = (1 as i32);
13+
|
14+
15+
error[E0308]: mismatched types
16+
--> $DIR/issue-105494.rs:5:19
17+
|
18+
LL | let _v: i32 = (1 as i128).to_string();
19+
| --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String`
20+
| |
21+
| expected due to this
22+
23+
error[E0308]: mismatched types
24+
--> $DIR/issue-105494.rs:7:20
25+
|
26+
LL | let _v: &str = "foo".to_string();
27+
| ---- ^^^^^^^^^^^^^^^^^ expected `&str`, found struct `String`
28+
| |
29+
| expected due to this
30+
|
31+
help: try removing the method call
32+
|
33+
LL - let _v: &str = "foo".to_string();
34+
LL + let _v: &str = "foo";
35+
|
36+
37+
error[E0308]: mismatched types
38+
--> $DIR/issue-105494.rs:14:12
39+
|
40+
LL | let mut path: String = "/usr".to_string();
41+
| ------ expected due to this type
42+
...
43+
LL | path = format!("{}/{}", path, folder).as_str();
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&str`
45+
|
46+
help: try removing the method call
47+
|
48+
LL - path = format!("{}/{}", path, folder).as_str();
49+
LL + path = format!("{}/{}", path, folder);
50+
|
51+
52+
error: aborting due to 4 previous errors
53+
54+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)