@@ -449,7 +449,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
449449 error_code,
450450 ) ;
451451
452- let suffix = match local_visitor. found_node_ty {
452+ let ( suffix, sugg_ty ) = match local_visitor. found_node_ty {
453453 Some ( ty) if ty. is_closure ( ) => {
454454 let substs =
455455 if let ty:: Closure ( _, substs) = * ty. kind ( ) { substs } else { unreachable ! ( ) } ;
@@ -484,20 +484,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
484484 // This suggestion is incomplete, as the user will get further type inference
485485 // errors due to the `_` placeholders and the introduction of `Box`, but it does
486486 // nudge them in the right direction.
487- format ! ( "a boxed closure type like `Box<dyn Fn({}) -> {}>`" , args, ret)
487+ (
488+ format ! ( "a boxed closure type like `Box<dyn Fn({}) -> {}>`" , args, ret) ,
489+ format ! ( "Box<dyn Fn({}) -> {}>" , args, ret) ,
490+ )
488491 }
489492 Some ( ty) if is_named_and_not_impl_trait ( ty) && arg_data. name == "_" => {
490493 let ty = ty_to_string ( ty) ;
491- format ! ( "the explicit type `{}`, with the type parameters specified" , ty)
494+ (
495+ format ! ( "the explicit type `{}`, with the type parameters specified" , ty) ,
496+ ty. to_string ( ) ,
497+ )
492498 }
493499 Some ( ty) if is_named_and_not_impl_trait ( ty) && ty. to_string ( ) != arg_data. name => {
494500 let ty = ty_to_string ( ty) ;
495- format ! (
496- "the explicit type `{}`, where the type parameter `{}` is specified" ,
497- ty, arg_data. name,
501+ (
502+ format ! (
503+ "the explicit type `{}`, where the type parameter `{}` is specified" ,
504+ ty, arg_data. name,
505+ ) ,
506+ ty. to_string ( ) ,
498507 )
499508 }
500- _ => "a type" . to_string ( ) ,
509+ _ if turbofish_suggestions. len ( ) == 1 => (
510+ format ! ( "the explicit type `{}`" , turbofish_suggestions[ 0 ] ) ,
511+ turbofish_suggestions[ 0 ] . clone ( ) ,
512+ ) ,
513+ _ => ( "a type" . to_string ( ) , "Type" . to_string ( ) ) ,
501514 } ;
502515
503516 if let Some ( e) = local_visitor. found_exact_method_call {
@@ -552,18 +565,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
552565 format ! ( "consider giving this closure parameter {}" , suffix) ,
553566 ) ;
554567 } else if let Some ( pattern) = local_visitor. found_local_pattern {
555- let msg = if let Some ( simple_ident) = pattern. simple_ident ( ) {
556- match pattern. span . desugaring_kind ( ) {
557- None => format ! ( "consider giving `{}` {}" , simple_ident, suffix) ,
558- Some ( DesugaringKind :: ForLoop ( _) ) => {
559- "the element type for this iterator is not specified" . to_string ( )
560- }
561- _ => format ! ( "this needs {}" , suffix) ,
562- }
568+ if let ( hir:: Node :: Local ( local) , None ) = (
569+ self . tcx . hir ( ) . get ( self . tcx . hir ( ) . get_parent_node ( pattern. hir_id ) ) ,
570+ pattern. span . desugaring_kind ( ) ,
571+ ) {
572+ let ( span, prefix) = match local. ty {
573+ Some ( ty) => ( ty. span , "" ) ,
574+ None => ( local. pat . span . shrink_to_hi ( ) , ": " ) ,
575+ } ;
576+ let msg = format ! ( "consider giving this binding {}" , suffix) ;
577+ match & turbofish_suggestions[ ..] {
578+ [ ] => err. span_suggestion_verbose (
579+ span,
580+ & msg,
581+ format ! ( "{}{}" , prefix, sugg_ty) ,
582+ Applicability :: HasPlaceholders ,
583+ ) ,
584+ [ ty] => err. span_suggestion_verbose (
585+ span,
586+ & msg,
587+ format ! ( "{}{}" , prefix, ty) ,
588+ Applicability :: MachineApplicable ,
589+ ) ,
590+ _ => err. span_suggestions (
591+ span,
592+ & msg,
593+ turbofish_suggestions. into_iter ( ) . map ( |ty| format ! ( "{}{}" , prefix, ty) ) ,
594+ Applicability :: MaybeIncorrect ,
595+ ) ,
596+ } ;
563597 } else {
564- format ! ( "consider giving this pattern {}" , suffix)
565- } ;
566- err. span_label ( pattern. span , msg) ;
598+ let msg = if let Some ( simple_ident) = pattern. simple_ident ( ) {
599+ match pattern. span . desugaring_kind ( ) {
600+ None => format ! ( "consider giving `{}` {}" , simple_ident, suffix) ,
601+ Some ( DesugaringKind :: ForLoop ( _) ) => {
602+ "the element type for this iterator is not specified" . to_string ( )
603+ }
604+ _ => format ! ( "this needs {}" , suffix) ,
605+ }
606+ } else {
607+ format ! ( "consider giving this pattern {}" , suffix)
608+ } ;
609+ err. span_label ( pattern. span , msg) ;
610+ }
567611 } else if let Some ( e) = local_visitor. found_method_call {
568612 if let ExprKind :: MethodCall ( segment, ..) = & e. kind {
569613 // Suggest specifying type params or point out the return type of the call:
0 commit comments