Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest remove last method call when type coerce with expected type #105872

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Use `||` to give these suggestions a precedence
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_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

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) {
let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) {
expr.span.with_lo(recv_span.hi())
} else {
expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1))
};
err.span_suggestion_verbose(
span,
"try removing the method call",
"",
Applicability::MachineApplicable,
);
return true;
}
false
}

pub fn suggest_deref_ref_or_into(
&self,
err: &mut Diagnostic,
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/suggestions/issue-105494.rs
Original file line number Diff line number Diff line change
@@ -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();
}
54 changes: 54 additions & 0 deletions src/test/ui/suggestions/issue-105494.stderr
Original file line number Diff line number Diff line change
@@ -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`.