@@ -683,87 +683,82 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
683
683
} )
684
684
} ;
685
685
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) ;
701
699
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 {
728
712
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 ;
729
723
}
724
+ } ) ;
725
+ if found {
726
+ return ;
730
727
}
728
+ }
731
729
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 ( )
753
748
}
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
+ } ) ;
767
762
paths
768
763
}
769
764
}
0 commit comments