@@ -21,14 +21,15 @@ use rustc_hir::lang_items::LangItem;
2121use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
2222use rustc_infer:: infer:: error_reporting:: TypeErrCtxt ;
2323use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
24+ use rustc_infer:: infer:: LateBoundRegionConversionTime ;
2425use rustc_middle:: hir:: map;
2526use rustc_middle:: ty:: {
2627 self , suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind , DefIdTree ,
2728 GeneratorDiagnosticData , GeneratorInteriorTypeCause , Infer , InferTy , IsSuggestable ,
2829 ToPredicate , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitable ,
2930} ;
3031use rustc_middle:: ty:: { TypeAndMut , TypeckResults } ;
31- use rustc_span:: symbol:: { kw , sym, Ident , Symbol } ;
32+ use rustc_span:: symbol:: { sym, Ident , Symbol } ;
3233use rustc_span:: { BytePos , DesugaringKind , ExpnKind , Span , DUMMY_SP } ;
3334use rustc_target:: spec:: abi;
3435use std:: fmt;
@@ -814,80 +815,85 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
814815 // Skipping binder here, remapping below
815816 let self_ty = trait_pred. self_ty ( ) . skip_binder ( ) ;
816817
817- let ( def_id, output_ty, callable) = match * self_ty. kind ( ) {
818- ty:: Closure ( def_id, substs) => ( def_id, substs. as_closure ( ) . sig ( ) . output ( ) , "closure" ) ,
819- ty:: FnDef ( def_id, _) => (
820- def_id,
821- self_ty. fn_sig ( self . tcx ) . output ( ) ,
822- match self . tcx . def_kind ( def_id) {
823- DefKind :: Ctor ( ..) => "constructor" ,
824- _ => "function" ,
825- } ,
826- ) ,
818+ let ( def_id, inputs, output, kind) = match * self_ty. kind ( ) {
819+ ty:: Closure ( def_id, substs) => {
820+ let sig = substs. as_closure ( ) . sig ( ) ;
821+ ( def_id, sig. inputs ( ) . map_bound ( |inputs| & inputs[ 1 ..] ) , sig. output ( ) , "closure" )
822+ }
823+ ty:: FnDef ( def_id, _) => {
824+ let sig = self_ty. fn_sig ( self . tcx ) ;
825+ (
826+ def_id,
827+ sig. inputs ( ) ,
828+ sig. output ( ) ,
829+ match self . tcx . def_kind ( def_id) {
830+ DefKind :: Ctor ( ..) => "constructor" ,
831+ _ => "function" ,
832+ } ,
833+ )
834+ }
827835 _ => return false ,
828836 } ;
829- let msg = format ! ( "use parentheses to call the {}" , callable) ;
830-
831- // "We should really create a single list of bound vars from the combined vars
832- // from the predicate and function, but instead we just liberate the function bound vars"
833- let output_ty = self . tcx . liberate_late_bound_regions ( def_id, output_ty) ;
837+ let output = self . replace_bound_vars_with_fresh_vars (
838+ obligation. cause . span ,
839+ LateBoundRegionConversionTime :: FnCall ,
840+ output,
841+ ) ;
842+ let inputs = inputs. skip_binder ( ) . iter ( ) . map ( |ty| {
843+ self . replace_bound_vars_with_fresh_vars (
844+ obligation. cause . span ,
845+ LateBoundRegionConversionTime :: FnCall ,
846+ inputs. rebind ( * ty) ,
847+ )
848+ } ) ;
834849
835850 // Remapping bound vars here
836- let trait_pred_and_self = trait_pred. map_bound ( |trait_pred| ( trait_pred, output_ty ) ) ;
851+ let trait_pred_and_self = trait_pred. map_bound ( |trait_pred| ( trait_pred, output ) ) ;
837852
838853 let new_obligation =
839854 self . mk_trait_obligation_with_new_self_ty ( obligation. param_env , trait_pred_and_self) ;
840-
841855 if !self . predicate_must_hold_modulo_regions ( & new_obligation) {
842856 return false ;
843857 }
844858
845- let hir = self . tcx . hir ( ) ;
846859 // Get the name of the callable and the arguments to be used in the suggestion.
847- let ( snippet, sugg) = match hir. get_if_local ( def_id) {
860+ let hir = self . tcx . hir ( ) ;
861+
862+ let msg = format ! ( "use parentheses to call the {}" , kind) ;
863+
864+ let args = inputs
865+ . map ( |ty| {
866+ if ty. is_suggestable ( self . tcx , false ) {
867+ format ! ( "/* {ty} */" )
868+ } else {
869+ "/* value */" . to_string ( )
870+ }
871+ } )
872+ . collect :: < Vec < _ > > ( )
873+ . join ( ", " ) ;
874+
875+ let name = match hir. get_if_local ( def_id) {
848876 Some ( hir:: Node :: Expr ( hir:: Expr {
849- kind : hir:: ExprKind :: Closure ( hir:: Closure { fn_decl , fn_decl_span, .. } ) ,
877+ kind : hir:: ExprKind :: Closure ( hir:: Closure { fn_decl_span, .. } ) ,
850878 ..
851879 } ) ) => {
852880 err. span_label ( * fn_decl_span, "consider calling this closure" ) ;
853881 let Some ( name) = self . get_closure_name ( def_id, err, & msg) else {
854882 return false ;
855883 } ;
856- let args = fn_decl. inputs . iter ( ) . map ( |_| "_" ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
857- let sugg = format ! ( "({})" , args) ;
858- ( format ! ( "{}{}" , name, sugg) , sugg)
884+ name. to_string ( )
859885 }
860- Some ( hir:: Node :: Item ( hir:: Item {
861- ident,
862- kind : hir:: ItemKind :: Fn ( .., body_id) ,
863- ..
864- } ) ) => {
886+ Some ( hir:: Node :: Item ( hir:: Item { ident, kind : hir:: ItemKind :: Fn ( ..) , .. } ) ) => {
865887 err. span_label ( ident. span , "consider calling this function" ) ;
866- let body = hir. body ( * body_id) ;
867- let args = body
868- . params
869- . iter ( )
870- . map ( |arg| match & arg. pat . kind {
871- hir:: PatKind :: Binding ( _, _, ident, None )
872- // FIXME: provide a better suggestion when encountering `SelfLower`, it
873- // should suggest a method call.
874- if ident. name != kw:: SelfLower => ident. to_string ( ) ,
875- _ => "_" . to_string ( ) ,
876- } )
877- . collect :: < Vec < _ > > ( )
878- . join ( ", " ) ;
879- let sugg = format ! ( "({})" , args) ;
880- ( format ! ( "{}{}" , ident, sugg) , sugg)
888+ ident. to_string ( )
881889 }
882- Some ( hir:: Node :: Ctor ( data ) ) => {
890+ Some ( hir:: Node :: Ctor ( .. ) ) => {
883891 let name = self . tcx . def_path_str ( def_id) ;
884892 err. span_label (
885893 self . tcx . def_span ( def_id) ,
886894 format ! ( "consider calling the constructor for `{}`" , name) ,
887895 ) ;
888- let args = data. fields ( ) . iter ( ) . map ( |_| "_" ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
889- let sugg = format ! ( "({})" , args) ;
890- ( format ! ( "{name}{sugg}" ) , sugg)
896+ name
891897 }
892898 _ => return false ,
893899 } ;
@@ -901,11 +907,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
901907 err. span_suggestion_verbose (
902908 obligation. cause . span . shrink_to_hi ( ) ,
903909 & msg,
904- sugg ,
910+ format ! ( "({args})" ) ,
905911 Applicability :: HasPlaceholders ,
906912 ) ;
907913 } else {
908- err. help ( & format ! ( "{}: `{}`" , msg , snippet ) ) ;
914+ err. help ( & format ! ( "{msg }: `{name}({args})`" ) ) ;
909915 }
910916 true
911917 }
0 commit comments