diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7b86791026b41..f58ac9f00e4cc 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -744,8 +744,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { let (closure_span, found) = found_did .and_then(|did| self.tcx.hir.get_if_local(did)) - .map(|node| self.get_fn_like_arguments(node)) - .unwrap_or((found_span.unwrap(), found)); + .map(|node| { + let (found_span, found) = self.get_fn_like_arguments(node); + (Some(found_span), found) + }).unwrap_or((found_span, found)); self.report_arg_count_mismatch(span, closure_span, @@ -855,7 +857,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_arg_count_mismatch( &self, span: Span, - found_span: Span, + found_span: Option, expected_args: Vec, found_args: Vec, is_closure: bool, @@ -893,48 +895,51 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ); err.span_label(span, format!( "expected {} that takes {}", kind, expected_str)); - 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() - .map(|(name, _)| name.to_owned()) - .collect::>().join(", "); - err.span_suggestion(found_span, - "change the closure to take multiple arguments instead of \ - a single tuple", - format!("|{}|", sugg)); + + if let Some(found_span) = found_span { + 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() + .map(|(name, _)| name.to_owned()) + .collect::>().join(", "); + err.span_suggestion(found_span, + "change the closure to take multiple arguments instead of \ + a single tuple", + format!("|{}|", sugg)); + } } - } - if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { - if fields.len() == found_args.len() && is_closure { - let sugg = format!( - "|({}){}|", - found_args.iter() - .map(|arg| match arg { - ArgKind::Arg(name, _) => name.to_owned(), - _ => "_".to_owned(), - }) - .collect::>() - .join(", "), - // add type annotations if available - if found_args.iter().any(|arg| match arg { - ArgKind::Arg(_, ty) => ty != "_", - _ => false, - }) { - format!(": ({})", - fields.iter() - .map(|(_, ty)| ty.to_owned()) - .collect::>() - .join(", ")) - } else { - "".to_owned() - }, - ); - err.span_suggestion(found_span, - "change the closure to accept a tuple instead of individual \ - arguments", - sugg); + if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { + if fields.len() == found_args.len() && is_closure { + let sugg = format!( + "|({}){}|", + found_args.iter() + .map(|arg| match arg { + ArgKind::Arg(name, _) => name.to_owned(), + _ => "_".to_owned(), + }) + .collect::>() + .join(", "), + // add type annotations if available + if found_args.iter().any(|arg| match arg { + ArgKind::Arg(_, ty) => ty != "_", + _ => false, + }) { + format!(": ({})", + fields.iter() + .map(|(_, ty)| ty.to_owned()) + .collect::>() + .join(", ")) + } else { + "".to_owned() + }, + ); + err.span_suggestion(found_span, + "change the closure to accept a tuple instead of \ + individual arguments", + sugg); + } } } diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 96e5201716c71..34232e81cbdee 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -36,6 +36,9 @@ fn main() { //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); //~^ ERROR function is expected to take + + let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); + //~^ ERROR function is expected to take } fn foo() {} diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index be00ee4d74e7e..d2a6d6da814ca 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -90,7 +90,7 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it 32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -41 | fn foo() {} +44 | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments @@ -107,8 +107,14 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it 37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument ... -42 | fn qux(x: usize, y: usize) {} +45 | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments -error: aborting due to 11 previous errors +error[E0593]: function is expected to take 1 argument, but it takes 2 arguments + --> $DIR/closure-arg-count.rs:40:41 + | +40 | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); + | ^^^ expected function that takes 1 argument + +error: aborting due to 12 previous errors