@@ -18,6 +18,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
1818use rustc_infer:: traits:: ObligationCauseCode ;
1919use rustc_middle:: middle:: stability;
2020use rustc_middle:: query:: Providers ;
21+ use rustc_middle:: ty:: fast_reject:: SimplifiedType ;
2122use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
2223use rustc_middle:: ty:: AssocItem ;
2324use rustc_middle:: ty:: AssocItemContainer ;
@@ -664,7 +665,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
664665
665666 #[ instrument( level = "debug" , skip( self ) ) ]
666667 fn assemble_probe ( & mut self , self_ty : & Canonical < ' tcx , QueryResponse < ' tcx , Ty < ' tcx > > > ) {
667- let raw_self_ty = self_ty. value . value ;
668+ let ( QueryResponse { value : raw_self_ty, .. } , _) =
669+ self . instantiate_canonical ( DUMMY_SP , self_ty) ;
668670 match * raw_self_ty. kind ( ) {
669671 ty:: Dynamic ( data, ..) if let Some ( p) = data. principal ( ) => {
670672 // Subtle: we can't use `instantiate_query_response` here: using it will
@@ -709,6 +711,47 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
709711 ty:: Param ( p) => {
710712 self . assemble_inherent_candidates_from_param ( p) ;
711713 }
714+ // which have some integer or float as a self type.
715+ ty:: Infer ( ty:: IntVar ( _) ) => {
716+ use ty:: IntTy :: * ;
717+ use ty:: UintTy :: * ;
718+ // This causes a compiler error if any new integer kinds are added.
719+ let ( I8 | I16 | I32 | I64 | I128 | Isize ) : ty:: IntTy ;
720+ let ( U8 | U16 | U32 | U64 | U128 | Usize ) : ty:: UintTy ;
721+ let possible_integers = [
722+ // signed integers
723+ SimplifiedType :: Int ( I8 ) ,
724+ SimplifiedType :: Int ( I16 ) ,
725+ SimplifiedType :: Int ( I32 ) ,
726+ SimplifiedType :: Int ( I64 ) ,
727+ SimplifiedType :: Int ( I128 ) ,
728+ SimplifiedType :: Int ( Isize ) ,
729+ // unsigned integers
730+ SimplifiedType :: Uint ( U8 ) ,
731+ SimplifiedType :: Uint ( U16 ) ,
732+ SimplifiedType :: Uint ( U32 ) ,
733+ SimplifiedType :: Uint ( U64 ) ,
734+ SimplifiedType :: Uint ( U128 ) ,
735+ SimplifiedType :: Uint ( Usize ) ,
736+ ] ;
737+ for simp in possible_integers {
738+ self . assemble_inherent_candidates_for_simplified_type ( simp) ;
739+ }
740+ }
741+ ty:: Infer ( ty:: FloatVar ( _) ) => {
742+ // This causes a compiler error if any new float kinds are added.
743+ let ( ty:: FloatTy :: F16 | ty:: FloatTy :: F32 | ty:: FloatTy :: F64 | ty:: FloatTy :: F128 ) ;
744+ let possible_floats = [
745+ SimplifiedType :: Float ( ty:: FloatTy :: F16 ) ,
746+ SimplifiedType :: Float ( ty:: FloatTy :: F32 ) ,
747+ SimplifiedType :: Float ( ty:: FloatTy :: F64 ) ,
748+ SimplifiedType :: Float ( ty:: FloatTy :: F128 ) ,
749+ ] ;
750+
751+ for simp in possible_floats {
752+ self . assemble_inherent_candidates_for_simplified_type ( simp) ;
753+ }
754+ }
712755 ty:: Bool
713756 | ty:: Char
714757 | ty:: Int ( _)
@@ -729,6 +772,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
729772 let Some ( simp) = simplify_type ( self . tcx , self_ty, TreatParams :: AsCandidateKey ) else {
730773 bug ! ( "unexpected incoherent type: {:?}" , self_ty)
731774 } ;
775+ self . assemble_inherent_candidates_for_simplified_type ( simp) ;
776+ }
777+
778+ fn assemble_inherent_candidates_for_simplified_type ( & mut self , simp : SimplifiedType ) {
732779 for & impl_def_id in self . tcx . incoherent_impls ( simp) . into_iter ( ) . flatten ( ) {
733780 self . assemble_inherent_impl_probe ( impl_def_id) ;
734781 }
@@ -1207,6 +1254,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12071254 for ( kind, candidates) in
12081255 [ ( "inherent" , & self . inherent_candidates ) , ( "extension" , & self . extension_candidates ) ]
12091256 {
1257+ if kind == "inherent" && self . should_skip_shadowable_inherent_numerical_methods ( ) {
1258+ continue ;
1259+ }
1260+
12101261 debug ! ( "searching {} candidates" , kind) ;
12111262 let res = self . consider_candidates (
12121263 self_ty,
@@ -1643,6 +1694,26 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16431694 } )
16441695 }
16451696
1697+ fn should_skip_shadowable_inherent_numerical_methods ( & self ) -> bool {
1698+ let res = self . inherent_candidates . len ( ) > 1
1699+ && self . extension_candidates . iter ( ) . any ( |cand| match cand. kind {
1700+ TraitCandidate ( trait_ref) => {
1701+ let trait_def_id = trait_ref. def_id ( ) ;
1702+ self . tcx . crate_name ( trait_def_id. krate ) == sym:: compiler_builtins
1703+ && [ sym:: Float , sym:: Int ] . contains ( & self . tcx . item_name ( trait_def_id) )
1704+ }
1705+ InherentImplCandidate ( _) | ObjectCandidate ( _) | WhereClauseCandidate ( _) => false ,
1706+ } )
1707+ && self . inherent_candidates . iter ( ) . all ( |cand| match cand. kind {
1708+ InherentImplCandidate ( def_id) => {
1709+ self . tcx . type_of ( def_id) . skip_binder ( ) . is_numeric ( )
1710+ }
1711+ ObjectCandidate ( _) | TraitCandidate ( _) | WhereClauseCandidate ( _) => false ,
1712+ } ) ;
1713+
1714+ res
1715+ }
1716+
16461717 /// Sometimes we get in a situation where we have multiple probes that are all impls of the
16471718 /// same trait, but we don't know which impl to use. In this case, since in all cases the
16481719 /// external interface of the method can be determined from the trait, it's ok not to decide.
0 commit comments