Skip to content

Commit

Permalink
Rollup merge of rust-lang#59035 - estebank:closure-instacall, r=david…
Browse files Browse the repository at this point in the history
…twco

When encountetring `||{}()`, suggest the likely intended `(||{})()`

Fix rust-lang#55851.
  • Loading branch information
Centril authored Mar 10, 2019
2 parents 65d565a + 9aa89b2 commit 91cbb53
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/librustc_typeck/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::autoderef::Autoderef;
use super::method::MethodCallee;
use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};

use errors::Applicability;
use errors::{Applicability, DiagnosticBuilder};
use hir::def::Def;
use hir::def_id::{DefId, LOCAL_CRATE};
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
Expand Down Expand Up @@ -232,6 +232,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None
}

/// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the
/// likely intention is to call the closure, suggest `(||{})()`. (#55851)
fn identify_bad_closure_def_and_call(
&self,
err: &mut DiagnosticBuilder<'a>,
hir_id: hir::HirId,
callee_node: &hir::ExprKind,
callee_span: Span,
) {
let hir_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
let parent_node = self.tcx.hir().get_by_hir_id(hir_id);
if let (
hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
hir::ExprKind::Block(..),
) = (parent_node, callee_node) {
let start = sp.shrink_to_lo();
let end = self.tcx.sess.source_map().next_point(callee_span);
err.multipart_suggestion(
"if you meant to create this closure and immediately call it, surround the \
closure with parenthesis",
vec![(start, "(".to_string()), (end, ")".to_string())],
Applicability::MaybeIncorrect,
);
}
}

fn confirm_builtin_call(
&self,
call_expr: &hir::Expr,
Expand Down Expand Up @@ -268,6 +294,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
);

self.identify_bad_closure_def_and_call(
&mut err,
call_expr.hir_id,
&callee.node,
callee.span,
);

if let Some(ref path) = unit_variant {
err.span_suggestion(
call_expr.span,
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/suggestions/suggest-on-bare-closure-call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
let _ = ||{}();
//~^ ERROR expected function, found `()`
}
15 changes: 15 additions & 0 deletions src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0618]: expected function, found `()`
--> $DIR/suggest-on-bare-closure-call.rs:2:15
|
LL | let _ = ||{}();
| ^^--
| |
| call expression requires function
help: if you meant to create this closure and immediately call it, surround the closure with parenthesis
|
LL | let _ = (||{})();
| ^ ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0618`.

0 comments on commit 91cbb53

Please sign in to comment.