@@ -3819,55 +3819,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3819
3819
pointing_at_return_type
3820
3820
}
3821
3821
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
+ /// ```
3822
3828
fn suggest_fn_call (
3823
3829
& self ,
3824
3830
err : & mut DiagnosticBuilder < ' tcx > ,
3825
3831
expr : & hir:: Expr ,
3826
3832
expected : Ty < ' tcx > ,
3827
3833
found : Ty < ' tcx > ,
3828
3834
) -> 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 ( ", " ) ;
3860
3864
}
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
+ _ => { }
3870
3870
}
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 ;
3871
3880
}
3872
3881
}
3873
3882
false
0 commit comments