From 87f0c1f33789df39db871857055a2d7d533da47f Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:16:53 +0800 Subject: [PATCH 1/7] Suggest to take and ignore args while closure args count mismatching --- src/librustc/traits/error_reporting.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index df26ac670601c..1c502b6610302 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1048,7 +1048,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(span, format!( "expected {} that takes {}", kind, expected_str)); if let Some(found_span) = found_span { - err.span_label(found_span, format!("takes {}", found_str)); + // Suggest to take and ignore the arguments with expected_args_length `_`s if + // found arguments is empty(Suppose the user just wants to ignore args in this case). + // like `|_, _|` for closure with 2 expected args. + if found_args.is_empty() && is_closure { + let mut underscores = "_".repeat(expected_args.len()) + .split("") + .filter(|s| !s.is_empty()) + .collect::>() + .join(", "); + err.span_suggestion( + found_span, + "consider changing this to", + format!("|{}|", underscores), + ); + } else { + err.span_label(found_span, format!("takes {}", found_str)); + } + if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { if fields.len() == expected_args.len() { From 27c0d564efedef1bec06076c8c12108c0d6fd6ec Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:45:37 +0800 Subject: [PATCH 2/7] Mark the suggestion applicable --- src/librustc/traits/error_reporting.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1c502b6610302..e0dcbf520b4c6 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1048,25 +1048,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(span, format!( "expected {} that takes {}", kind, expected_str)); if let Some(found_span) = found_span { + err.span_label(found_span, format!("takes {}", found_str)); + // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty(Suppose the user just wants to ignore args in this case). // like `|_, _|` for closure with 2 expected args. if found_args.is_empty() && is_closure { let mut underscores = "_".repeat(expected_args.len()) - .split("") - .filter(|s| !s.is_empty()) - .collect::>() - .join(", "); - err.span_suggestion( + .split("") + .filter(|s| !s.is_empty()) + .collect::>() + .join(", "); + err.span_suggestion_with_applicability( found_span, - "consider changing this to", + &format!("change the closure to take and ignore the argument{}", + if expected_args.len() < 2 { + "" + } else { + "s" + } + ), format!("|{}|", underscores), + Applicability::MachineApplicable, ); - } else { - err.span_label(found_span, format!("takes {}", found_str)); } - if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { if fields.len() == expected_args.len() { let sugg = fields.iter() From a71deb2633eeaf03f64ae0ee3b389128ec06f392 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Tue, 24 Jul 2018 10:09:45 +0800 Subject: [PATCH 3/7] Fix ui test --- .../ui/mismatched_types/closure-arg-count.stderr | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 6270e79449876..73e00df21110e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -2,8 +2,10 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 0 arguments --> $DIR/closure-arg-count.rs:15:15 | LL | [1, 2, 3].sort_by(|| panic!()); - | ^^^^^^^ -- takes 0 arguments - | | + | ^^^^^^^ -- + | | | + | | takes 0 arguments + | | help: change the closure to take and ignore the arguments: `|_, _|` | expected closure that takes 2 arguments error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument @@ -42,8 +44,10 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:23:5 | LL | f(|| panic!()); - | ^ -- takes 0 arguments - | | + | ^ -- + | | | + | | takes 0 arguments + | | help: change the closure to take and ignore the argument: `|_|` | expected closure that takes 1 argument | note: required by `f` From 94921768ea30fb74889d7a0e7b96989358573c63 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Wed, 25 Jul 2018 08:06:45 +0800 Subject: [PATCH 4/7] Suggest in separate line --- src/librustc/traits/error_reporting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index e0dcbf520b4c6..72ca6a4af1776 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1061,7 +1061,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .join(", "); err.span_suggestion_with_applicability( found_span, - &format!("change the closure to take and ignore the argument{}", + &format!("change the closure to take and ignore the expected argument{}", if expected_args.len() < 2 { "" } else { From 40c0339cf689f74b62b90297f21c4176af1193fc Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Wed, 25 Jul 2018 09:09:13 +0800 Subject: [PATCH 5/7] Fix test --- .../mismatched_types/closure-arg-count.stderr | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 73e00df21110e..5660ff4c792ea 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -2,11 +2,13 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 0 arguments --> $DIR/closure-arg-count.rs:15:15 | LL | [1, 2, 3].sort_by(|| panic!()); - | ^^^^^^^ -- - | | | - | | takes 0 arguments - | | help: change the closure to take and ignore the arguments: `|_, _|` + | ^^^^^^^ -- takes 0 arguments + | | | expected closure that takes 2 arguments +help: change the closure to take and ignore the expected arguments + | +LL | [1, 2, 3].sort_by(|_, _| panic!()); + | ^^^^^^ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument --> $DIR/closure-arg-count.rs:17:15 @@ -44,10 +46,8 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:23:5 | LL | f(|| panic!()); - | ^ -- - | | | - | | takes 0 arguments - | | help: change the closure to take and ignore the argument: `|_|` + | ^ -- takes 0 arguments + | | | expected closure that takes 1 argument | note: required by `f` @@ -55,6 +55,10 @@ note: required by `f` | LL | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: change the closure to take and ignore the expected argument + | +LL | f(|_| panic!()); + | ^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:26:53 From d5256b75dfca78e257748ec01947e7327ea627bd Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Wed, 25 Jul 2018 09:30:10 +0800 Subject: [PATCH 6/7] Update comment and do suggest --- src/librustc/traits/error_reporting.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 72ca6a4af1776..8300f98fb1cd5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1051,8 +1051,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(found_span, format!("takes {}", found_str)); // Suggest to take and ignore the arguments with expected_args_length `_`s if - // found arguments is empty(Suppose the user just wants to ignore args in this case). - // like `|_, _|` for closure with 2 expected args. + // found arguments is empty (assume the user just wants to ignore args in this case). + // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args.is_empty() && is_closure { let mut underscores = "_".repeat(expected_args.len()) .split("") @@ -1061,12 +1061,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .join(", "); err.span_suggestion_with_applicability( found_span, - &format!("change the closure to take and ignore the expected argument{}", - if expected_args.len() < 2 { - "" - } else { - "s" - } + &format!( + "consider changing the closure to take and ignore the expected argument{}", + if expected_args.len() < 2 { + "" + } else { + "s" + } ), format!("|{}|", underscores), Applicability::MachineApplicable, From 1d79588994ca773fa80938021729dbff4679d78b Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Wed, 25 Jul 2018 09:30:53 +0800 Subject: [PATCH 7/7] Update ui test --- src/test/ui/mismatched_types/closure-arg-count.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 5660ff4c792ea..057cf6efa1dea 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -5,7 +5,7 @@ LL | [1, 2, 3].sort_by(|| panic!()); | ^^^^^^^ -- takes 0 arguments | | | expected closure that takes 2 arguments -help: change the closure to take and ignore the expected arguments +help: consider changing the closure to take and ignore the expected arguments | LL | [1, 2, 3].sort_by(|_, _| panic!()); | ^^^^^^ @@ -55,7 +55,7 @@ note: required by `f` | LL | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: change the closure to take and ignore the expected argument +help: consider changing the closure to take and ignore the expected argument | LL | f(|_| panic!()); | ^^^