@@ -3819,55 +3819,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38193819 pointing_at_return_type
38203820 }
38213821
3822+ /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
3823+ /// the ctor would successfully solve the type mismatch and if so, suggest it:
3824+ /// ```
3825+ /// fn foo(x: usize) -> usize { x }
3826+ /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
3827+ /// ```
38223828 fn suggest_fn_call (
38233829 & self ,
38243830 err : & mut DiagnosticBuilder < ' tcx > ,
38253831 expr : & hir:: Expr ,
38263832 expected : Ty < ' tcx > ,
38273833 found : Ty < ' tcx > ,
38283834 ) -> bool {
3829- if let ty:: FnDef ( ..) | ty:: FnPtr ( _) = & found. sty {
3830- let sig = found. fn_sig ( self . tcx ) ;
3831- let sig = self
3832- . replace_bound_vars_with_fresh_vars ( expr. span , infer:: FnCall , & sig)
3833- . 0 ;
3834- let sig = self . normalize_associated_types_in ( expr. span , & sig) ;
3835- if let Ok ( _) = self . try_coerce ( expr, sig. output ( ) , expected, AllowTwoPhase :: No ) {
3836- let ( mut sugg_call, applicability) = if sig. inputs ( ) . is_empty ( ) {
3837- ( String :: new ( ) , Applicability :: MachineApplicable )
3838- } else {
3839- ( "..." . to_owned ( ) , Applicability :: HasPlaceholders )
3840- } ;
3841- let mut msg = "call this function" ;
3842- if let ty:: FnDef ( def_id, ..) = found. sty {
3843- match self . tcx . hir ( ) . get_if_local ( def_id) {
3844- Some ( Node :: Item ( hir:: Item {
3845- node : ItemKind :: Fn ( .., body_id) ,
3846- ..
3847- } ) ) => {
3848- let body = self . tcx . hir ( ) . body ( * body_id) ;
3849- sugg_call = body. arguments . iter ( )
3850- . map ( |arg| hir:: print:: to_string (
3851- hir:: print:: NO_ANN ,
3852- |s| s. print_pat ( & arg. pat ) ,
3853- ) ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
3854- }
3855- Some ( Node :: Ctor ( hir:: VariantData :: Tuple ( field, _) ) ) => {
3856- sugg_call = field. iter ( ) . map ( |_| "_" ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
3857- msg = "instatiate this tuple struct" ;
3858- }
3859- _ => { }
3835+ match found. sty {
3836+ ty:: FnDef ( ..) | ty:: FnPtr ( _) => { }
3837+ _ => return false ,
3838+ }
3839+
3840+ let sig = found. fn_sig ( self . tcx ) ;
3841+ let sig = self
3842+ . replace_bound_vars_with_fresh_vars ( expr. span , infer:: FnCall , & sig)
3843+ . 0 ;
3844+ let sig = self . normalize_associated_types_in ( expr. span , & sig) ;
3845+ if let Ok ( _) = self . try_coerce ( expr, sig. output ( ) , expected, AllowTwoPhase :: No ) {
3846+ let ( mut sugg_call, applicability) = if sig. inputs ( ) . is_empty ( ) {
3847+ ( String :: new ( ) , Applicability :: MachineApplicable )
3848+ } else {
3849+ ( "..." . to_owned ( ) , Applicability :: HasPlaceholders )
3850+ } ;
3851+ let mut msg = "call this function" ;
3852+ if let ty:: FnDef ( def_id, ..) = found. sty {
3853+ match self . tcx . hir ( ) . get_if_local ( def_id) {
3854+ Some ( Node :: Item ( hir:: Item {
3855+ node : ItemKind :: Fn ( .., body_id) ,
3856+ ..
3857+ } ) ) => {
3858+ let body = self . tcx . hir ( ) . body ( * body_id) ;
3859+ sugg_call = body. arguments . iter ( )
3860+ . map ( |arg| hir:: print:: to_string (
3861+ hir:: print:: NO_ANN ,
3862+ |s| s. print_pat ( & arg. pat ) ,
3863+ ) ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
38603864 }
3861- } ;
3862- if let Ok ( code) = self . sess ( ) . source_map ( ) . span_to_snippet ( expr. span ) {
3863- err. span_suggestion (
3864- expr. span ,
3865- & format ! ( "use parentheses to {}" , msg) ,
3866- format ! ( "{}({})" , code, sugg_call) ,
3867- applicability,
3868- ) ;
3869- return true ;
3865+ Some ( Node :: Ctor ( hir:: VariantData :: Tuple ( field, _) ) ) => {
3866+ sugg_call = field. iter ( ) . map ( |_| "_" ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
3867+ msg = "instatiate this tuple struct" ;
3868+ }
3869+ _ => { }
38703870 }
3871+ } ;
3872+ if let Ok ( code) = self . sess ( ) . source_map ( ) . span_to_snippet ( expr. span ) {
3873+ err. span_suggestion (
3874+ expr. span ,
3875+ & format ! ( "use parentheses to {}" , msg) ,
3876+ format ! ( "{}({})" , code, sugg_call) ,
3877+ applicability,
3878+ ) ;
3879+ return true ;
38713880 }
38723881 }
38733882 false
0 commit comments