@@ -683,87 +683,82 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
683683 } )
684684 } ;
685685 let args = args. unwrap_or_else ( || empty_args ( def_id) ) ;
686- tcx. for_each_relevant_impl (
687- tcx. parent ( def_id) , // Trait `DefId`
688- self_ty,
689- |impl_def_id| {
690- let impl_args = empty_args ( impl_def_id) ;
691- let impl_trait_ref =
692- tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate ( tcx, impl_args) ;
693- let impl_self_ty = impl_trait_ref. self_ty ( ) ;
694- if self . infcx . can_eq ( param_env, impl_self_ty, self_ty) {
695- // The expr's self type could conform to this impl's self type.
696- } else {
697- // Nope, don't bother.
698- return ;
699- }
700- let assocs = tcx. associated_items ( impl_def_id) ;
686+ let trait_def_id = tcx. parent ( def_id) ;
687+ tcx. for_each_relevant_impl ( trait_def_id, self_ty, |impl_def_id| {
688+ let impl_args = empty_args ( impl_def_id) ;
689+ let impl_trait_ref =
690+ tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate ( tcx, impl_args) ;
691+ let impl_self_ty = impl_trait_ref. self_ty ( ) ;
692+ if self . infcx . can_eq ( param_env, impl_self_ty, self_ty) {
693+ // The expr's self type could conform to this impl's self type.
694+ } else {
695+ // Nope, don't bother.
696+ return ;
697+ }
698+ let assocs = tcx. associated_items ( impl_def_id) ;
701699
702- if tcx. is_diagnostic_item ( sym:: blanket_into_impl, impl_def_id)
703- && let Some ( did) = tcx. get_diagnostic_item ( sym:: From )
704- {
705- let mut found = false ;
706- tcx. for_each_impl ( did, |impl_def_id| {
707- // We had an `<A as Into<B>::into` and we've hit the blanket
708- // impl for `From<A>`. So we try and look for the right `From`
709- // impls that *would* apply. We *could* do this in a generalized
710- // version by evaluating the `where` clauses, but that would be
711- // way too involved to implement. Instead we special case the
712- // arguably most common case of `expr.into()`.
713- let Some ( header) = tcx. impl_trait_header ( impl_def_id) else {
714- return ;
715- } ;
716- let target = header. trait_ref . skip_binder ( ) . args . type_at ( 0 ) ;
717- let ty = header. trait_ref . skip_binder ( ) . args . type_at ( 1 ) ;
718- if ty == self_ty {
719- if target_type {
720- paths. push ( format ! ( "{target}" ) ) ;
721- } else {
722- paths. push ( format ! ( "<{self_ty} as Into<{target}>>::into" ) ) ;
723- }
724- found = true ;
725- }
726- } ) ;
727- if found {
700+ if tcx. is_diagnostic_item ( sym:: blanket_into_impl, impl_def_id)
701+ && let Some ( did) = tcx. get_diagnostic_item ( sym:: From )
702+ {
703+ let mut found = false ;
704+ tcx. for_each_impl ( did, |impl_def_id| {
705+ // We had an `<A as Into<B>::into` and we've hit the blanket
706+ // impl for `From<A>`. So we try and look for the right `From`
707+ // impls that *would* apply. We *could* do this in a generalized
708+ // version by evaluating the `where` clauses, but that would be
709+ // way too involved to implement. Instead we special case the
710+ // arguably most common case of `expr.into()`.
711+ let Some ( header) = tcx. impl_trait_header ( impl_def_id) else {
728712 return ;
713+ } ;
714+ let target = header. trait_ref . skip_binder ( ) . args . type_at ( 0 ) ;
715+ let ty = header. trait_ref . skip_binder ( ) . args . type_at ( 1 ) ;
716+ if ty == self_ty {
717+ if target_type {
718+ paths. push ( format ! ( "{target}" ) ) ;
719+ } else {
720+ paths. push ( format ! ( "<{self_ty} as Into<{target}>>::into" ) ) ;
721+ }
722+ found = true ;
729723 }
724+ } ) ;
725+ if found {
726+ return ;
730727 }
728+ }
731729
732- // We're at the `impl` level, but we want to get the same method we
733- // called *on this `impl`*, in order to get the right DefId and args.
734- let Some ( assoc) = assocs. filter_by_name_unhygienic ( name) . next ( ) else {
735- // The method isn't in this `impl`? Not useful to us then.
736- return ;
737- } ;
738- let Some ( trait_assoc_item) = assoc. trait_item_def_id else {
739- return ;
740- } ;
741- let trait_assoc_substs =
742- impl_trait_ref. args . extend_to ( tcx, trait_assoc_item, |def, _| {
743- // We don't want to name the arguments, we just want to give an
744- // idea of what the syntax is.
745- match def. kind {
746- ty:: GenericParamDefKind :: Lifetime => tcx. lifetimes . re_erased . into ( ) ,
747- ty:: GenericParamDefKind :: Type { .. } => {
748- self . next_ty_var ( DUMMY_SP ) . into ( )
749- }
750- ty:: GenericParamDefKind :: Const { .. } => {
751- self . next_const_var ( DUMMY_SP ) . into ( )
752- }
730+ // We're at the `impl` level, but we want to get the same method we
731+ // called *on this `impl`*, in order to get the right DefId and args.
732+ let Some ( assoc) = assocs. filter_by_name_unhygienic ( name) . next ( ) else {
733+ // The method isn't in this `impl`? Not useful to us then.
734+ return ;
735+ } ;
736+ let Some ( trait_assoc_item) = assoc. trait_item_def_id else {
737+ return ;
738+ } ;
739+ let trait_assoc_substs =
740+ impl_trait_ref. args . extend_to ( tcx, trait_assoc_item, |def, _| {
741+ // We don't want to name the arguments, we just want to give an
742+ // idea of what the syntax is.
743+ match def. kind {
744+ ty:: GenericParamDefKind :: Lifetime => tcx. lifetimes . re_erased . into ( ) ,
745+ ty:: GenericParamDefKind :: Type { .. } => self . next_ty_var ( DUMMY_SP ) . into ( ) ,
746+ ty:: GenericParamDefKind :: Const { .. } => {
747+ self . next_const_var ( DUMMY_SP ) . into ( )
753748 }
754- } ) ;
755- let identity_method = args . rebase_onto ( tcx , def_id , trait_assoc_substs ) ;
756- if target_type {
757- let fn_sig = tcx . fn_sig ( def_id ) . instantiate ( tcx , identity_method ) ;
758- let ret = fn_sig . skip_binder ( ) . output ( ) ;
759- paths . push ( format ! ( "{ret}" ) ) ;
760- } else {
761- let mut printer = fmt_printer ( self , Namespace :: ValueNS ) ;
762- printer . print_def_path ( def_id , identity_method ) . unwrap ( ) ;
763- paths . push ( printer. into_buffer ( ) ) ;
764- }
765- } ,
766- ) ;
749+ }
750+ } ) ;
751+ let identity_method = args . rebase_onto ( tcx , def_id , trait_assoc_substs ) ;
752+ if target_type {
753+ let fn_sig = tcx . fn_sig ( def_id ) . instantiate ( tcx , identity_method ) ;
754+ let ret = fn_sig . skip_binder ( ) . output ( ) ;
755+ paths . push ( format ! ( "{ret}" ) ) ;
756+ } else {
757+ let mut printer = fmt_printer ( self , Namespace :: ValueNS ) ;
758+ printer. print_def_path ( def_id , identity_method ) . unwrap ( ) ;
759+ paths . push ( printer . into_buffer ( ) ) ;
760+ }
761+ } ) ;
767762 paths
768763 }
769764}
0 commit comments