diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 2761a954cea88..48b2b25d6adf9 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1092,13 +1092,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(found_span) = found_span { err.span_label(found_span, format!("takes {}", found_str)); + // move |_| { ... } + // ^^^^^^^^-- def_span + // + // move |_| { ... } + // ^^^^^-- prefix + let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span); + // move |_| { ... } + // ^^^-- pipe_span + let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { + span + } else { + found_span + }; + // Suggest to take and ignore the arguments with expected_args_length `_`s if // 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 underscores = vec!["_"; expected_args.len()].join(", "); err.span_suggestion_with_applicability( - found_span, + pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", if expected_args.len() < 2 { diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 9eb11148a8bce..2dcc7a25c8401 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,6 +22,8 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take + f( move || panic!()); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); //~^ ERROR closure is expected to take diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 057cf6efa1dea..eeadf07262c3e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -60,8 +60,26 @@ help: consider changing the closure to take and ignore the expected argument LL | f(|_| panic!()); | ^^^ +error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments + --> $DIR/closure-arg-count.rs:25:5 + | +LL | f( move || panic!()); + | ^ ---------- takes 0 arguments + | | + | expected closure that takes 1 argument + | +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +LL | fn f>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider changing the closure to take and ignore the expected argument + | +LL | f( move |_| 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 + --> $DIR/closure-arg-count.rs:28:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); | ^^^ ------ takes 2 distinct arguments @@ -73,7 +91,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); | ^^^ ------------- takes 2 distinct arguments @@ -85,7 +103,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments @@ -93,7 +111,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:32:53 + --> $DIR/closure-arg-count.rs:34:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument @@ -102,7 +120,7 @@ LL | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:35:53 + --> $DIR/closure-arg-count.rs:37:53 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments @@ -110,7 +128,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:37:53 + --> $DIR/closure-arg-count.rs:39:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument @@ -119,13 +137,13 @@ LL | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments error[E0593]: function is expected to take 1 argument, but it takes 2 arguments - --> $DIR/closure-arg-count.rs:40:41 + --> $DIR/closure-arg-count.rs:42:41 | LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); | ^^^ expected function that takes 1 argument error[E0593]: function is expected to take 0 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:43:5 + --> $DIR/closure-arg-count.rs:45:5 | LL | call(Foo); | ^^^^ expected function that takes 0 arguments @@ -134,11 +152,11 @@ LL | struct Foo(u8); | --------------- takes 1 argument | note: required by `call` - --> $DIR/closure-arg-count.rs:50:1 + --> $DIR/closure-arg-count.rs:52:1 | LL | fn call(_: F) where F: FnOnce() -> R {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0593`.