@@ -218,35 +218,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
218218 }
219219 }
220220
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+ } ) ;
233232
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+ }
243242
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+ }
249273 } ;
274+
275+ err. span_label ( call_expr. span , "call expression requires function" ) ;
276+
250277 let def_span = match def {
251278 Def :: Err => None ,
252279 Def :: Local ( id) | Def :: Upvar ( id, ..) => {
@@ -255,16 +282,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
255282 _ => self . tcx . hir . span_if_local ( def. def_id ( ) )
256283 } ;
257284 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( ) ) ,
261291 } ;
262- err. span_label ( span, format ! ( "`{}` defined here" , name ) ) ;
292+ err. span_label ( span, label ) ;
263293 }
294+ err. emit ( ) ;
295+ } else {
296+ bug ! ( "call_expr.node should be an ExprKind::Call, got {:?}" , call_expr. node) ;
264297 }
265298
266- err. emit ( ) ;
267-
268299 // This is the "default" function signature, used in case of error.
269300 // In that case, we check each argument against "error" in order to
270301 // set up all the node type bindings.
0 commit comments