Skip to content

Commit 402596d

Browse files
authored
Rollup merge of rust-lang#59035 - estebank:closure-instacall, r=davidtwco
When encountetring `||{}()`, suggest the likely intended `(||{})()` Fix rust-lang#55851.
2 parents d222e41 + 9aa89b2 commit 402596d

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

src/librustc_typeck/check/callee.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::autoderef::Autoderef;
22
use super::method::MethodCallee;
33
use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
44

5-
use errors::Applicability;
5+
use errors::{Applicability, DiagnosticBuilder};
66
use hir::def::Def;
77
use hir::def_id::{DefId, LOCAL_CRATE};
88
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -232,6 +232,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
232232
None
233233
}
234234

235+
/// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the
236+
/// likely intention is to call the closure, suggest `(||{})()`. (#55851)
237+
fn identify_bad_closure_def_and_call(
238+
&self,
239+
err: &mut DiagnosticBuilder<'a>,
240+
hir_id: hir::HirId,
241+
callee_node: &hir::ExprKind,
242+
callee_span: Span,
243+
) {
244+
let hir_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
245+
let parent_node = self.tcx.hir().get_by_hir_id(hir_id);
246+
if let (
247+
hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
248+
hir::ExprKind::Block(..),
249+
) = (parent_node, callee_node) {
250+
let start = sp.shrink_to_lo();
251+
let end = self.tcx.sess.source_map().next_point(callee_span);
252+
err.multipart_suggestion(
253+
"if you meant to create this closure and immediately call it, surround the \
254+
closure with parenthesis",
255+
vec![(start, "(".to_string()), (end, ")".to_string())],
256+
Applicability::MaybeIncorrect,
257+
);
258+
}
259+
}
260+
235261
fn confirm_builtin_call(
236262
&self,
237263
call_expr: &hir::Expr,
@@ -268,6 +294,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
268294
}
269295
);
270296

297+
self.identify_bad_closure_def_and_call(
298+
&mut err,
299+
call_expr.hir_id,
300+
&callee.node,
301+
callee.span,
302+
);
303+
271304
if let Some(ref path) = unit_variant {
272305
err.span_suggestion(
273306
call_expr.span,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let _ = ||{}();
3+
//~^ ERROR expected function, found `()`
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0618]: expected function, found `()`
2+
--> $DIR/suggest-on-bare-closure-call.rs:2:15
3+
|
4+
LL | let _ = ||{}();
5+
| ^^--
6+
| |
7+
| call expression requires function
8+
help: if you meant to create this closure and immediately call it, surround the closure with parenthesis
9+
|
10+
LL | let _ = (||{})();
11+
| ^ ^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0618`.

0 commit comments

Comments
 (0)