22//! For details about how this works in rustc, see the method lookup page in the
33//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
44//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
5- use std:: sync:: Arc ;
5+ use std:: { iter , sync:: Arc } ;
66
77use arrayvec:: ArrayVec ;
88use hir_def:: {
@@ -17,7 +17,8 @@ use rustc_hash::{FxHashMap, FxHashSet};
1717use super :: Substs ;
1818use crate :: {
1919 autoderef, db:: HirDatabase , primitive:: FloatBitness , utils:: all_super_traits, ApplicationTy ,
20- Canonical , DebruijnIndex , InEnvironment , TraitEnvironment , TraitRef , Ty , TypeCtor , TypeWalk ,
20+ Canonical , DebruijnIndex , InEnvironment , TraitEnvironment , TraitRef , Ty , TyKind , TypeCtor ,
21+ TypeWalk ,
2122} ;
2223
2324/// This is used as a key for indexing impls.
@@ -377,7 +378,7 @@ fn iterate_method_candidates_with_autoref(
377378 return true ;
378379 }
379380 let refed = Canonical {
380- num_vars : deref_chain[ 0 ] . num_vars ,
381+ kinds : deref_chain[ 0 ] . kinds . clone ( ) ,
381382 value : Ty :: apply_one ( TypeCtor :: Ref ( Mutability :: Shared ) , deref_chain[ 0 ] . value . clone ( ) ) ,
382383 } ;
383384 if iterate_method_candidates_by_receiver (
@@ -393,7 +394,7 @@ fn iterate_method_candidates_with_autoref(
393394 return true ;
394395 }
395396 let ref_muted = Canonical {
396- num_vars : deref_chain[ 0 ] . num_vars ,
397+ kinds : deref_chain[ 0 ] . kinds . clone ( ) ,
397398 value : Ty :: apply_one ( TypeCtor :: Ref ( Mutability :: Mut ) , deref_chain[ 0 ] . value . clone ( ) ) ,
398399 } ;
399400 if iterate_method_candidates_by_receiver (
@@ -612,18 +613,19 @@ pub(crate) fn inherent_impl_substs(
612613 // we create a var for each type parameter of the impl; we need to keep in
613614 // mind here that `self_ty` might have vars of its own
614615 let vars = Substs :: build_for_def ( db, impl_id)
615- . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , self_ty. num_vars )
616+ . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , self_ty. kinds . len ( ) )
616617 . build ( ) ;
617618 let self_ty_with_vars = db. impl_self_ty ( impl_id) . subst ( & vars) ;
618- let self_ty_with_vars =
619- Canonical { num_vars : vars. len ( ) + self_ty. num_vars , value : self_ty_with_vars } ;
620- let substs = super :: infer:: unify ( & self_ty_with_vars, self_ty) ;
619+ let mut kinds = self_ty. kinds . to_vec ( ) ;
620+ kinds. extend ( iter:: repeat ( TyKind :: General ) . take ( vars. len ( ) ) ) ;
621+ let tys = Canonical { kinds : kinds. into ( ) , value : ( self_ty_with_vars, self_ty. value . clone ( ) ) } ;
622+ let substs = super :: infer:: unify ( & tys) ;
621623 // We only want the substs for the vars we added, not the ones from self_ty.
622624 // Also, if any of the vars we added are still in there, we replace them by
623625 // Unknown. I think this can only really happen if self_ty contained
624626 // Unknown, and in that case we want the result to contain Unknown in those
625627 // places again.
626- substs. map ( |s| fallback_bound_vars ( s. suffix ( vars. len ( ) ) , self_ty. num_vars ) )
628+ substs. map ( |s| fallback_bound_vars ( s. suffix ( vars. len ( ) ) , self_ty. kinds . len ( ) ) )
627629}
628630
629631/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -683,15 +685,15 @@ fn generic_implements_goal(
683685 trait_ : TraitId ,
684686 self_ty : Canonical < Ty > ,
685687) -> Canonical < InEnvironment < super :: Obligation > > {
686- let num_vars = self_ty. num_vars ;
688+ let mut kinds = self_ty. kinds . to_vec ( ) ;
687689 let substs = super :: Substs :: build_for_def ( db, trait_)
688690 . push ( self_ty. value )
689- . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , num_vars )
691+ . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , kinds . len ( ) )
690692 . build ( ) ;
691- let num_vars = substs. len ( ) - 1 + self_ty . num_vars ;
693+ kinds . extend ( iter :: repeat ( TyKind :: General ) . take ( substs. len ( ) - 1 ) ) ;
692694 let trait_ref = TraitRef { trait_, substs } ;
693695 let obligation = super :: Obligation :: Trait ( trait_ref) ;
694- Canonical { num_vars , value : InEnvironment :: new ( env, obligation) }
696+ Canonical { kinds : kinds . into ( ) , value : InEnvironment :: new ( env, obligation) }
695697}
696698
697699fn autoderef_method_receiver (
@@ -704,9 +706,9 @@ fn autoderef_method_receiver(
704706 if let Some ( Ty :: Apply ( ApplicationTy { ctor : TypeCtor :: Array , parameters } ) ) =
705707 deref_chain. last ( ) . map ( |ty| & ty. value )
706708 {
707- let num_vars = deref_chain. last ( ) . unwrap ( ) . num_vars ;
709+ let kinds = deref_chain. last ( ) . unwrap ( ) . kinds . clone ( ) ;
708710 let unsized_ty = Ty :: apply ( TypeCtor :: Slice , parameters. clone ( ) ) ;
709- deref_chain. push ( Canonical { value : unsized_ty, num_vars } )
711+ deref_chain. push ( Canonical { value : unsized_ty, kinds } )
710712 }
711713 deref_chain
712714}
0 commit comments