@@ -453,15 +453,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
453453 let mut infer_subdiags = Vec :: new ( ) ;
454454 let mut multi_suggestions = Vec :: new ( ) ;
455455 match kind {
456- InferSourceKind :: LetBinding { insert_span, pattern_name, ty, def_id, hir_id } => {
456+ InferSourceKind :: LetBinding {
457+ insert_span,
458+ pattern_name,
459+ ty,
460+ def_id,
461+ init_expr_hir_id,
462+ } => {
457463 let mut paths = vec ! [ ] ;
458464 if let Some ( def_id) = def_id
459- && let Some ( hir_id) = hir_id
465+ && let Some ( hir_id) = init_expr_hir_id
460466 && let expr = self . infcx . tcx . hir ( ) . expect_expr ( hir_id)
461467 && let hir:: ExprKind :: MethodCall ( _, rcvr, _, _) = expr. kind
462468 && let Some ( ty) = typeck_results. node_type_opt ( rcvr. hir_id )
463469 {
464- paths = self . get_suggestions ( ty, def_id, true , param_env, None , predicate) ;
470+ paths = self . get_fully_qualified_path_suggestions_from_impls (
471+ ty, def_id, true , param_env, predicate,
472+ ) ;
465473 }
466474
467475 if paths. is_empty ( ) {
@@ -588,12 +596,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
588596
589597 // Look for all the possible implementations to suggest, otherwise we'll show
590598 // just suggest the syntax for the fully qualified path with placeholders.
591- let paths = self . get_suggestions (
599+ let paths = self . get_fully_qualified_path_suggestions_from_impls (
592600 args. type_at ( 0 ) ,
593601 def_id,
594602 false ,
595603 param_env,
596- Some ( args) ,
597604 predicate,
598605 ) ;
599606 if paths. len ( ) > 20 || paths. is_empty ( ) {
@@ -667,33 +674,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
667674 }
668675 }
669676
670- fn get_suggestions (
677+ fn get_fully_qualified_path_suggestions_from_impls (
671678 & self ,
672679 self_ty : Ty < ' tcx > ,
673680 def_id : DefId ,
674681 target_type : bool ,
675682 param_env : ty:: ParamEnv < ' tcx > ,
676- args : Option < & ty:: GenericArgs < ' tcx > > ,
677683 predicate : Option < ty:: Predicate < ' tcx > > ,
678684 ) -> Vec < String > {
679685 let tcx = self . infcx . tcx ;
680686 let mut paths = vec ! [ ] ;
681687 let name = tcx. item_name ( def_id) ;
682- let empty_args = |def_id| {
683- ty:: GenericArgs :: for_item ( tcx, def_id, |param, _| {
684- // We don't want to name the arguments, we just want to give an
685- // idea of what the syntax is.
686- match param. kind {
687- ty:: GenericParamDefKind :: Lifetime => tcx. lifetimes . re_erased . into ( ) ,
688- ty:: GenericParamDefKind :: Type { .. } => self . next_ty_var ( DUMMY_SP ) . into ( ) ,
689- ty:: GenericParamDefKind :: Const { .. } => self . next_const_var ( DUMMY_SP ) . into ( ) ,
690- }
691- } )
692- } ;
693- let args = args. unwrap_or_else ( || empty_args ( def_id) ) ;
688+ let args = self . fresh_args_for_item ( DUMMY_SP , def_id) ;
694689 let trait_def_id = tcx. parent ( def_id) ;
695690 tcx. for_each_relevant_impl ( trait_def_id, self_ty, |impl_def_id| {
696- let impl_args = empty_args ( impl_def_id) ;
691+ let impl_args = self . fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
697692 let impl_trait_ref =
698693 tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate ( tcx, impl_args) ;
699694 let impl_self_ty = impl_trait_ref. self_ty ( ) ;
@@ -704,18 +699,28 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
704699 return ;
705700 }
706701
702+ let lang = tcx. lang_items ( ) ;
707703 let filter = if let Some ( ty:: ProjectionPredicate {
708704 projection_term : ty:: AliasTerm { def_id, .. } ,
709705 term,
710706 } ) =
711707 predicate. and_then ( |p| p. as_projection_clause ( ) ) . map ( |p| p. skip_binder ( ) )
712708 && let ty:: TermKind :: Ty ( assoc_ty) = term. unpack ( )
713709 && tcx. item_name ( def_id) == sym:: Output
710+ && [
711+ lang. add_trait ( ) ,
712+ lang. sub_trait ( ) ,
713+ lang. mul_trait ( ) ,
714+ lang. div_trait ( ) ,
715+ lang. rem_trait ( ) ,
716+ lang. neg_trait ( ) ,
717+ ]
718+ . contains ( & Some ( tcx. parent ( def_id) ) )
714719 {
715720 // If the predicate that failed to be inferred is an associated type called
716- // "Output" (presumably from one of the math traits), we will only mention the
717- // `Into` and ` From` impls that correspond to the self type as well, so as to
718- // avoid showing multiple conversion options.
721+ // "Output" (from one of the math traits), we will only mention the `Into` and
722+ // `From` impls that correspond to the self type as well, so as to avoid showing
723+ // multiple conversion options.
719724 Some ( assoc_ty)
720725 } else {
721726 None
@@ -766,26 +771,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
766771 return ;
767772 } ;
768773 let trait_assoc_substs =
769- impl_trait_ref. args . extend_to ( tcx, trait_assoc_item, |def, _| {
770- // We don't want to name the arguments, we just want to give an
771- // idea of what the syntax is.
772- match def. kind {
773- ty:: GenericParamDefKind :: Lifetime => tcx. lifetimes . re_erased . into ( ) ,
774- ty:: GenericParamDefKind :: Type { .. } => self . next_ty_var ( DUMMY_SP ) . into ( ) ,
775- ty:: GenericParamDefKind :: Const { .. } => {
776- self . next_const_var ( DUMMY_SP ) . into ( )
777- }
778- }
779- } ) ;
774+ impl_trait_ref
775+ . args
776+ . extend_to ( tcx, trait_assoc_item, |def, _| self . var_for_def ( DUMMY_SP , def) ) ;
780777 let identity_method = args. rebase_onto ( tcx, def_id, trait_assoc_substs) ;
781778 if target_type {
782779 let fn_sig = tcx. fn_sig ( def_id) . instantiate ( tcx, identity_method) ;
783780 let ret = fn_sig. skip_binder ( ) . output ( ) ;
784781 paths. push ( format ! ( "{ret}" ) ) ;
785782 } else {
786- let mut printer = fmt_printer ( self , Namespace :: ValueNS ) ;
787- printer. print_def_path ( def_id, identity_method) . unwrap ( ) ;
788- paths. push ( printer. into_buffer ( ) ) ;
783+ paths. push ( self . tcx . value_path_str_with_args ( def_id, identity_method) ) ;
789784 }
790785 } ) ;
791786 paths
@@ -805,7 +800,7 @@ enum InferSourceKind<'tcx> {
805800 pattern_name : Option < Ident > ,
806801 ty : Ty < ' tcx > ,
807802 def_id : Option < DefId > ,
808- hir_id : Option < HirId > ,
803+ init_expr_hir_id : Option < HirId > ,
809804 } ,
810805 ClosureArg {
811806 insert_span : Span ,
@@ -1304,7 +1299,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
13041299 pattern_name : local. pat . simple_ident ( ) ,
13051300 ty,
13061301 def_id : None ,
1307- hir_id : local. init . map ( |e| e. hir_id ) ,
1302+ init_expr_hir_id : local. init . map ( |e| e. hir_id ) ,
13081303 } ,
13091304 } )
13101305 }
0 commit comments