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.
@@ -372,7 +373,7 @@ fn iterate_method_candidates_with_autoref(
372373 return true ;
373374 }
374375 let refed = Canonical {
375- num_vars : deref_chain[ 0 ] . num_vars ,
376+ kinds : deref_chain[ 0 ] . kinds . clone ( ) ,
376377 value : Ty :: apply_one ( TypeCtor :: Ref ( Mutability :: Shared ) , deref_chain[ 0 ] . value . clone ( ) ) ,
377378 } ;
378379 if iterate_method_candidates_by_receiver (
@@ -388,7 +389,7 @@ fn iterate_method_candidates_with_autoref(
388389 return true ;
389390 }
390391 let ref_muted = Canonical {
391- num_vars : deref_chain[ 0 ] . num_vars ,
392+ kinds : deref_chain[ 0 ] . kinds . clone ( ) ,
392393 value : Ty :: apply_one ( TypeCtor :: Ref ( Mutability :: Mut ) , deref_chain[ 0 ] . value . clone ( ) ) ,
393394 } ;
394395 if iterate_method_candidates_by_receiver (
@@ -607,18 +608,19 @@ pub(crate) fn inherent_impl_substs(
607608 // we create a var for each type parameter of the impl; we need to keep in
608609 // mind here that `self_ty` might have vars of its own
609610 let vars = Substs :: build_for_def ( db, impl_id)
610- . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , self_ty. num_vars )
611+ . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , self_ty. kinds . len ( ) )
611612 . build ( ) ;
612613 let self_ty_with_vars = db. impl_self_ty ( impl_id) . subst ( & vars) ;
613- let self_ty_with_vars =
614- Canonical { num_vars : vars. len ( ) + self_ty. num_vars , value : self_ty_with_vars } ;
615- let substs = super :: infer:: unify ( & self_ty_with_vars, self_ty) ;
614+ let mut kinds = self_ty. kinds . to_vec ( ) ;
615+ kinds. extend ( iter:: repeat ( TyKind :: General ) . take ( vars. len ( ) ) ) ;
616+ let tys = Canonical { kinds : kinds. into ( ) , value : ( self_ty_with_vars, self_ty. value . clone ( ) ) } ;
617+ let substs = super :: infer:: unify ( & tys) ;
616618 // We only want the substs for the vars we added, not the ones from self_ty.
617619 // Also, if any of the vars we added are still in there, we replace them by
618620 // Unknown. I think this can only really happen if self_ty contained
619621 // Unknown, and in that case we want the result to contain Unknown in those
620622 // places again.
621- substs. map ( |s| fallback_bound_vars ( s. suffix ( vars. len ( ) ) , self_ty. num_vars ) )
623+ substs. map ( |s| fallback_bound_vars ( s. suffix ( vars. len ( ) ) , self_ty. kinds . len ( ) ) )
622624}
623625
624626/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -678,15 +680,15 @@ fn generic_implements_goal(
678680 trait_ : TraitId ,
679681 self_ty : Canonical < Ty > ,
680682) -> Canonical < InEnvironment < super :: Obligation > > {
681- let num_vars = self_ty. num_vars ;
683+ let mut kinds = self_ty. kinds . to_vec ( ) ;
682684 let substs = super :: Substs :: build_for_def ( db, trait_)
683685 . push ( self_ty. value )
684- . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , num_vars )
686+ . fill_with_bound_vars ( DebruijnIndex :: INNERMOST , kinds . len ( ) )
685687 . build ( ) ;
686- let num_vars = substs. len ( ) - 1 + self_ty . num_vars ;
688+ kinds . extend ( iter :: repeat ( TyKind :: General ) . take ( substs. len ( ) - 1 ) ) ;
687689 let trait_ref = TraitRef { trait_, substs } ;
688690 let obligation = super :: Obligation :: Trait ( trait_ref) ;
689- Canonical { num_vars , value : InEnvironment :: new ( env, obligation) }
691+ Canonical { kinds : kinds . into ( ) , value : InEnvironment :: new ( env, obligation) }
690692}
691693
692694fn autoderef_method_receiver (
@@ -699,9 +701,9 @@ fn autoderef_method_receiver(
699701 if let Some ( Ty :: Apply ( ApplicationTy { ctor : TypeCtor :: Array , parameters } ) ) =
700702 deref_chain. last ( ) . map ( |ty| & ty. value )
701703 {
702- let num_vars = deref_chain. last ( ) . unwrap ( ) . num_vars ;
704+ let kinds = deref_chain. last ( ) . unwrap ( ) . kinds . clone ( ) ;
703705 let unsized_ty = Ty :: apply ( TypeCtor :: Slice , parameters. clone ( ) ) ;
704- deref_chain. push ( Canonical { value : unsized_ty, num_vars } )
706+ deref_chain. push ( Canonical { value : unsized_ty, kinds } )
705707 }
706708 deref_chain
707709}
0 commit comments