@@ -21,14 +21,15 @@ use rustc_hir::lang_items::LangItem;
21
21
use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
22
22
use rustc_infer:: infer:: error_reporting:: TypeErrCtxt ;
23
23
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
24
+ use rustc_infer:: infer:: LateBoundRegionConversionTime ;
24
25
use rustc_middle:: hir:: map;
25
26
use rustc_middle:: ty:: {
26
27
self , suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind , DefIdTree ,
27
28
GeneratorDiagnosticData , GeneratorInteriorTypeCause , Infer , InferTy , IsSuggestable ,
28
29
ToPredicate , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitable ,
29
30
} ;
30
31
use rustc_middle:: ty:: { TypeAndMut , TypeckResults } ;
31
- use rustc_span:: symbol:: { kw , sym, Ident , Symbol } ;
32
+ use rustc_span:: symbol:: { sym, Ident , Symbol } ;
32
33
use rustc_span:: { BytePos , DesugaringKind , ExpnKind , Span , DUMMY_SP } ;
33
34
use rustc_target:: spec:: abi;
34
35
use std:: fmt;
@@ -814,80 +815,85 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
814
815
// Skipping binder here, remapping below
815
816
let self_ty = trait_pred. self_ty ( ) . skip_binder ( ) ;
816
817
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
+ }
827
835
_ => return false ,
828
836
} ;
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
+ } ) ;
834
849
835
850
// 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 ) ) ;
837
852
838
853
let new_obligation =
839
854
self . mk_trait_obligation_with_new_self_ty ( obligation. param_env , trait_pred_and_self) ;
840
-
841
855
if !self . predicate_must_hold_modulo_regions ( & new_obligation) {
842
856
return false ;
843
857
}
844
858
845
- let hir = self . tcx . hir ( ) ;
846
859
// 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) {
848
876
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, .. } ) ,
850
878
..
851
879
} ) ) => {
852
880
err. span_label ( * fn_decl_span, "consider calling this closure" ) ;
853
881
let Some ( name) = self . get_closure_name ( def_id, err, & msg) else {
854
882
return false ;
855
883
} ;
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 ( )
859
885
}
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 ( ..) , .. } ) ) => {
865
887
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 ( )
881
889
}
882
- Some ( hir:: Node :: Ctor ( data ) ) => {
890
+ Some ( hir:: Node :: Ctor ( .. ) ) => {
883
891
let name = self . tcx . def_path_str ( def_id) ;
884
892
err. span_label (
885
893
self . tcx . def_span ( def_id) ,
886
894
format ! ( "consider calling the constructor for `{}`" , name) ,
887
895
) ;
888
- let args = data. fields ( ) . iter ( ) . map ( |_| "_" ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
889
- let sugg = format ! ( "({})" , args) ;
890
- ( format ! ( "{name}{sugg}" ) , sugg)
896
+ name
891
897
}
892
898
_ => return false ,
893
899
} ;
@@ -901,11 +907,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
901
907
err. span_suggestion_verbose (
902
908
obligation. cause . span . shrink_to_hi ( ) ,
903
909
& msg,
904
- sugg ,
910
+ format ! ( "({args})" ) ,
905
911
Applicability :: HasPlaceholders ,
906
912
) ;
907
913
} else {
908
- err. help ( & format ! ( "{}: `{}`" , msg , snippet ) ) ;
914
+ err. help ( & format ! ( "{msg }: `{name}({args})`" ) ) ;
909
915
}
910
916
true
911
917
}
0 commit comments