@@ -77,11 +77,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7777 let output = match result {
7878 None => {
7979 // this will report an error since original_callee_ty is not a fn
80- self . confirm_builtin_call ( call_expr, original_callee_ty, arg_exprs, expected)
80+ self . confirm_builtin_call (
81+ call_expr,
82+ callee_expr,
83+ original_callee_ty,
84+ arg_exprs,
85+ expected,
86+ )
8187 }
8288
8389 Some ( CallStep :: Builtin ( callee_ty) ) => {
84- self . confirm_builtin_call ( call_expr, callee_ty, arg_exprs, expected)
90+ self . confirm_builtin_call ( call_expr, callee_expr , callee_ty, arg_exprs, expected)
8591 }
8692
8793 Some ( CallStep :: DeferredClosure ( fn_sig) ) => {
@@ -281,6 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
281287 fn confirm_builtin_call (
282288 & self ,
283289 call_expr : & ' tcx hir:: Expr < ' tcx > ,
290+ callee_expr : & ' tcx hir:: Expr < ' tcx > ,
284291 callee_ty : Ty < ' tcx > ,
285292 arg_exprs : & ' tcx [ hir:: Expr < ' tcx > ] ,
286293 expected : Expectation < ' tcx > ,
@@ -299,110 +306,104 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
299306 }
300307 }
301308
302- if let hir:: ExprKind :: Call ( callee, _) = call_expr. kind {
303- let mut err = type_error_struct ! (
304- self . tcx. sess,
305- callee. span,
306- callee_ty,
307- E0618 ,
308- "expected function, found {}" ,
309- match unit_variant {
310- Some ( ref path) => format!( "enum variant `{}`" , path) ,
311- None => format!( "`{}`" , callee_ty) ,
312- }
313- ) ;
309+ let mut err = type_error_struct ! (
310+ self . tcx. sess,
311+ callee_expr. span,
312+ callee_ty,
313+ E0618 ,
314+ "expected function, found {}" ,
315+ match unit_variant {
316+ Some ( ref path) => format!( "enum variant `{}`" , path) ,
317+ None => format!( "`{}`" , callee_ty) ,
318+ }
319+ ) ;
314320
315- self . identify_bad_closure_def_and_call (
316- & mut err,
317- call_expr. hir_id ,
318- & callee . kind ,
319- callee . span ,
320- ) ;
321+ self . identify_bad_closure_def_and_call (
322+ & mut err,
323+ call_expr. hir_id ,
324+ & callee_expr . kind ,
325+ callee_expr . span ,
326+ ) ;
321327
322- if let Some ( ref path) = unit_variant {
323- err. span_suggestion (
324- call_expr. span ,
325- & format ! (
326- "`{}` is a unit variant, you need to write it \
328+ if let Some ( ref path) = unit_variant {
329+ err. span_suggestion (
330+ call_expr. span ,
331+ & format ! (
332+ "`{}` is a unit variant, you need to write it \
327333 without the parenthesis",
328- path
329- ) ,
330- path. to_string ( ) ,
331- Applicability :: MachineApplicable ,
332- ) ;
333- }
334+ path
335+ ) ,
336+ path. to_string ( ) ,
337+ Applicability :: MachineApplicable ,
338+ ) ;
339+ }
334340
335- let mut inner_callee_path = None ;
336- let def = match callee. kind {
337- hir:: ExprKind :: Path ( ref qpath) => {
338- self . typeck_results . borrow ( ) . qpath_res ( qpath, callee. hir_id )
341+ let mut inner_callee_path = None ;
342+ let def = match callee_expr. kind {
343+ hir:: ExprKind :: Path ( ref qpath) => {
344+ self . typeck_results . borrow ( ) . qpath_res ( qpath, callee_expr. hir_id )
345+ }
346+ hir:: ExprKind :: Call ( ref inner_callee, _) => {
347+ // If the call spans more than one line and the callee kind is
348+ // itself another `ExprCall`, that's a clue that we might just be
349+ // missing a semicolon (Issue #51055)
350+ let call_is_multiline =
351+ self . tcx . sess . source_map ( ) . is_multiline ( call_expr. span ) ;
352+ if call_is_multiline {
353+ err. span_suggestion (
354+ callee_expr. span . shrink_to_hi ( ) ,
355+ "consider using a semicolon here" ,
356+ ";" . to_owned ( ) ,
357+ Applicability :: MaybeIncorrect ,
358+ ) ;
339359 }
340- hir:: ExprKind :: Call ( ref inner_callee, _) => {
341- // If the call spans more than one line and the callee kind is
342- // itself another `ExprCall`, that's a clue that we might just be
343- // missing a semicolon (Issue #51055)
344- let call_is_multiline =
345- self . tcx . sess . source_map ( ) . is_multiline ( call_expr. span ) ;
346- if call_is_multiline {
347- err. span_suggestion (
348- callee. span . shrink_to_hi ( ) ,
349- "consider using a semicolon here" ,
350- ";" . to_owned ( ) ,
351- Applicability :: MaybeIncorrect ,
352- ) ;
353- }
354- if let hir:: ExprKind :: Path ( ref inner_qpath) = inner_callee. kind {
355- inner_callee_path = Some ( inner_qpath) ;
356- self . typeck_results
357- . borrow ( )
358- . qpath_res ( inner_qpath, inner_callee. hir_id )
359- } else {
360- Res :: Err
361- }
360+ if let hir:: ExprKind :: Path ( ref inner_qpath) = inner_callee. kind {
361+ inner_callee_path = Some ( inner_qpath) ;
362+ self . typeck_results . borrow ( ) . qpath_res ( inner_qpath, inner_callee. hir_id )
363+ } else {
364+ Res :: Err
362365 }
363- _ => Res :: Err ,
364- } ;
365-
366- err. span_label ( call_expr. span , "call expression requires function" ) ;
367-
368- if let Some ( span) = self . tcx . hir ( ) . res_span ( def) {
369- let callee_ty = callee_ty. to_string ( ) ;
370- let label = match ( unit_variant, inner_callee_path) {
371- ( Some ( path) , _) => Some ( format ! ( "`{}` defined here" , path) ) ,
372- ( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => {
373- self . tcx . sess . source_map ( ) . span_to_snippet ( path. span ) . ok ( ) . map (
374- |p| format ! ( "`{}` defined here returns `{}`" , p, callee_ty) ,
375- )
376- }
377- _ => {
378- match def {
379- // Emit a different diagnostic for local variables, as they are not
380- // type definitions themselves, but rather variables *of* that type.
381- Res :: Local ( hir_id) => Some ( format ! (
382- "`{}` has type `{}`" ,
383- self . tcx. hir( ) . name( hir_id) ,
384- callee_ty
385- ) ) ,
386- Res :: Def ( kind, def_id)
387- if kind. ns ( ) == Some ( Namespace :: ValueNS ) =>
388- {
389- Some ( format ! (
390- "`{}` defined here" ,
391- self . tcx. def_path_str( def_id) ,
392- ) )
393- }
394- _ => Some ( format ! ( "`{}` defined here" , callee_ty) ) ,
366+ }
367+ _ => Res :: Err ,
368+ } ;
369+
370+ err. span_label ( call_expr. span , "call expression requires function" ) ;
371+
372+ if let Some ( span) = self . tcx . hir ( ) . res_span ( def) {
373+ let callee_ty = callee_ty. to_string ( ) ;
374+ let label = match ( unit_variant, inner_callee_path) {
375+ ( Some ( path) , _) => Some ( format ! ( "`{}` defined here" , path) ) ,
376+ ( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => self
377+ . tcx
378+ . sess
379+ . source_map ( )
380+ . span_to_snippet ( path. span )
381+ . ok ( )
382+ . map ( |p| format ! ( "`{}` defined here returns `{}`" , p, callee_ty) ) ,
383+ _ => {
384+ match def {
385+ // Emit a different diagnostic for local variables, as they are not
386+ // type definitions themselves, but rather variables *of* that type.
387+ Res :: Local ( hir_id) => Some ( format ! (
388+ "`{}` has type `{}`" ,
389+ self . tcx. hir( ) . name( hir_id) ,
390+ callee_ty
391+ ) ) ,
392+ Res :: Def ( kind, def_id) if kind. ns ( ) == Some ( Namespace :: ValueNS ) => {
393+ Some ( format ! (
394+ "`{}` defined here" ,
395+ self . tcx. def_path_str( def_id) ,
396+ ) )
395397 }
398+ _ => Some ( format ! ( "`{}` defined here" , callee_ty) ) ,
396399 }
397- } ;
398- if let Some ( label) = label {
399- err. span_label ( span, label) ;
400400 }
401+ } ;
402+ if let Some ( label) = label {
403+ err. span_label ( span, label) ;
401404 }
402- err. emit ( ) ;
403- } else {
404- bug ! ( "call_expr.kind should be an ExprKind::Call, got {:?}" , call_expr. kind) ;
405405 }
406+ err. emit ( ) ;
406407
407408 // This is the "default" function signature, used in case of error.
408409 // In that case, we check each argument against "error" in order to
0 commit comments