@@ -218,35 +218,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
218
218
}
219
219
}
220
220
221
- let mut err = type_error_struct ! (
222
- self . tcx. sess,
223
- call_expr. span,
224
- callee_ty,
225
- E0618 ,
226
- "expected function, found {}" ,
227
- match unit_variant {
228
- Some ( ref path) => format!( "enum variant `{}`" , path) ,
229
- None => format!( "`{}`" , callee_ty) ,
230
- } ) ;
231
-
232
- err. span_label ( call_expr. span , "not a function" ) ;
221
+ if let hir:: ExprKind :: Call ( ref callee, _) = call_expr. node {
222
+ let mut err = type_error_struct ! (
223
+ self . tcx. sess,
224
+ callee. span,
225
+ callee_ty,
226
+ E0618 ,
227
+ "expected function, found {}" ,
228
+ match unit_variant {
229
+ Some ( ref path) => format!( "enum variant `{}`" , path) ,
230
+ None => format!( "`{}`" , callee_ty) ,
231
+ } ) ;
233
232
234
- if let Some ( ref path) = unit_variant {
235
- err. span_suggestion_with_applicability (
236
- call_expr. span ,
237
- & format ! ( "`{}` is a unit variant, you need to write it \
238
- without the parenthesis", path) ,
239
- path. to_string ( ) ,
240
- Applicability :: MachineApplicable
241
- ) ;
242
- }
233
+ if let Some ( ref path) = unit_variant {
234
+ err. span_suggestion_with_applicability (
235
+ call_expr. span ,
236
+ & format ! ( "`{}` is a unit variant, you need to write it \
237
+ without the parenthesis", path) ,
238
+ path. to_string ( ) ,
239
+ Applicability :: MachineApplicable
240
+ ) ;
241
+ }
243
242
244
- if let hir:: ExprKind :: Call ( ref expr, _) = call_expr. node {
245
- let def = if let hir:: ExprKind :: Path ( ref qpath) = expr. node {
246
- self . tables . borrow ( ) . qpath_def ( qpath, expr. hir_id )
247
- } else {
248
- Def :: Err
243
+ let mut inner_callee_path = None ;
244
+ let def = match callee. node {
245
+ hir:: ExprKind :: Path ( ref qpath) => {
246
+ self . tables . borrow ( ) . qpath_def ( qpath, callee. hir_id )
247
+ } ,
248
+ hir:: ExprKind :: Call ( ref inner_callee, _) => {
249
+ // If the call spans more than one line and the callee kind is
250
+ // itself another `ExprCall`, that's a clue that we might just be
251
+ // missing a semicolon (Issue #51055)
252
+ let call_is_multiline = self . tcx . sess . source_map ( )
253
+ . is_multiline ( call_expr. span ) ;
254
+ if call_is_multiline {
255
+ let span = self . tcx . sess . source_map ( ) . next_point ( callee. span ) ;
256
+ err. span_suggestion_with_applicability (
257
+ span,
258
+ "try adding a semicolon" ,
259
+ ";" . to_owned ( ) ,
260
+ Applicability :: MaybeIncorrect
261
+ ) ;
262
+ }
263
+ if let hir:: ExprKind :: Path ( ref inner_qpath) = inner_callee. node {
264
+ inner_callee_path = Some ( inner_qpath) ;
265
+ self . tables . borrow ( ) . qpath_def ( inner_qpath, inner_callee. hir_id )
266
+ } else {
267
+ Def :: Err
268
+ }
269
+ } ,
270
+ _ => {
271
+ Def :: Err
272
+ }
249
273
} ;
274
+
275
+ err. span_label ( call_expr. span , "call expression requires function" ) ;
276
+
250
277
let def_span = match def {
251
278
Def :: Err => None ,
252
279
Def :: Local ( id) | Def :: Upvar ( id, ..) => {
@@ -255,16 +282,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
255
282
_ => self . tcx . hir . span_if_local ( def. def_id ( ) )
256
283
} ;
257
284
if let Some ( span) = def_span {
258
- let name = match unit_variant {
259
- Some ( path) => path,
260
- None => callee_ty. to_string ( ) ,
285
+ let label = match ( unit_variant, inner_callee_path) {
286
+ ( Some ( path) , _) => format ! ( "`{}` defined here" , path) ,
287
+ ( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => format ! (
288
+ "`{}` defined here returns `{}`" , path, callee_ty. to_string( )
289
+ ) ,
290
+ _ => format ! ( "`{}` defined here" , callee_ty. to_string( ) ) ,
261
291
} ;
262
- err. span_label ( span, format ! ( "`{}` defined here" , name ) ) ;
292
+ err. span_label ( span, label ) ;
263
293
}
294
+ err. emit ( ) ;
295
+ } else {
296
+ bug ! ( "call_expr.node should be an ExprKind::Call, got {:?}" , call_expr. node) ;
264
297
}
265
298
266
- err. emit ( ) ;
267
-
268
299
// This is the "default" function signature, used in case of error.
269
300
// In that case, we check each argument against "error" in order to
270
301
// set up all the node type bindings.
0 commit comments