diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index eea8f40635d74..0fea0afb572c9 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -307,6 +307,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Give appropriate suggestion when encountering `[("a", 0) ("b", 1)]`, where the + /// likely intention is to create an array containing tuples. + fn maybe_suggest_bad_array_definition( + &self, + err: &mut DiagnosticBuilder<'a>, + call_expr: &'tcx hir::Expr<'tcx>, + callee_expr: &'tcx hir::Expr<'tcx>, + ) -> bool { + let hir_id = self.tcx.hir().get_parent_node(call_expr.hir_id); + let parent_node = self.tcx.hir().get(hir_id); + if let ( + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }), + hir::ExprKind::Tup(exp), + hir::ExprKind::Call(_, args), + ) = (parent_node, &callee_expr.kind, &call_expr.kind) + { + if args.len() == exp.len() { + let start = callee_expr.span.shrink_to_hi(); + err.span_suggestion( + start, + "consider separating array elements with a comma", + ",".to_string(), + Applicability::MaybeIncorrect, + ); + return true; + } + } + false + } + fn confirm_builtin_call( &self, call_expr: &'tcx hir::Expr<'tcx>, @@ -422,7 +452,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Res::Err, }; - err.span_label(call_expr.span, "call expression requires function"); + if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) { + err.span_label(call_expr.span, "call expression requires function"); + } if let Some(span) = self.tcx.hir().res_span(def) { let callee_ty = callee_ty.to_string(); diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr index de71e1d1a6666..c87a3e348a2e9 100644 --- a/src/test/ui/issues/issue-5100.stderr +++ b/src/test/ui/issues/issue-5100.stderr @@ -59,10 +59,8 @@ LL | &(true, false) => () error[E0618]: expected function, found `(char, char)` --> $DIR/issue-5100.rs:48:14 | -LL | let v = [('a', 'b') - | ______________-^^^^^^^^^ -LL | | ('c', 'd'), - | |_______________________- call expression requires function +LL | let v = [('a', 'b') + | ^^^^^^^^^^- help: consider separating array elements with a comma: `,` error[E0308]: mismatched types --> $DIR/issue-5100.rs:55:19 diff --git a/src/test/ui/tuple/array-diagnostics.rs b/src/test/ui/tuple/array-diagnostics.rs new file mode 100644 index 0000000000000..1929dab073169 --- /dev/null +++ b/src/test/ui/tuple/array-diagnostics.rs @@ -0,0 +1,7 @@ +fn main() { + let _tmp = [ + ("C200B40A82", 3), + ("C200B40A83", 4) //~ ERROR: expected function, found `(&'static str, {integer})` [E0618] + ("C200B40A8537", 5), + ]; +} diff --git a/src/test/ui/tuple/array-diagnostics.stderr b/src/test/ui/tuple/array-diagnostics.stderr new file mode 100644 index 0000000000000..a10d7af470c7c --- /dev/null +++ b/src/test/ui/tuple/array-diagnostics.stderr @@ -0,0 +1,9 @@ +error[E0618]: expected function, found `(&'static str, {integer})` + --> $DIR/array-diagnostics.rs:4:9 + | +LL | ("C200B40A83", 4) + | ^^^^^^^^^^^^^^^^^- help: consider separating array elements with a comma: `,` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0618`.