@@ -13,6 +13,7 @@ use hir_def::{
1313} ;
1414use hir_expand:: name:: Name ;
1515use rustc_hash:: { FxHashMap , FxHashSet } ;
16+ use stdx:: always;
1617
1718use crate :: {
1819 autoderef,
@@ -21,50 +22,89 @@ use crate::{
2122 primitive:: { self , FloatTy , IntTy , UintTy } ,
2223 static_lifetime,
2324 utils:: all_super_traits,
24- AdtId , Canonical , CanonicalVarKinds , DebruijnIndex , FnPointer , FnSig , ForeignDefId ,
25- InEnvironment , Interner , Scalar , Substitution , TraitEnvironment , TraitRefExt , Ty , TyBuilder ,
26- TyExt , TyKind ,
25+ AdtId , Canonical , CanonicalVarKinds , DebruijnIndex , ForeignDefId , InEnvironment , Interner ,
26+ Scalar , Substitution , TraitEnvironment , TraitRefExt , Ty , TyBuilder , TyExt , TyKind ,
2727} ;
2828
2929/// This is used as a key for indexing impls.
3030#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
3131pub enum TyFingerprint {
32+ // These are lang item impls:
3233 Str ,
3334 Slice ,
3435 Array ,
3536 Never ,
3637 RawPtr ( Mutability ) ,
3738 Scalar ( Scalar ) ,
39+ // These can have user-defined impls:
3840 Adt ( hir_def:: AdtId ) ,
3941 Dyn ( TraitId ) ,
40- Tuple ( usize ) ,
4142 ForeignType ( ForeignDefId ) ,
42- FnPtr ( usize , FnSig ) ,
43+ // These only exist for trait impls
44+ Unit ,
45+ Unnameable ,
46+ Function ( u32 ) ,
4347}
4448
4549impl TyFingerprint {
46- /// Creates a TyFingerprint for looking up an impl. Only certain types can
47- /// have impls: if we have some `struct S`, we can have an `impl S`, but not
48- /// `impl &S`. Hence, this will return `None` for reference types and such.
49- pub fn for_impl ( ty : & Ty ) -> Option < TyFingerprint > {
50+ /// Creates a TyFingerprint for looking up an inherent impl. Only certain
51+ /// types can have inherent impls: if we have some `struct S`, we can have
52+ /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
53+ /// reference types and such.
54+ pub fn for_inherent_impl ( ty : & Ty ) -> Option < TyFingerprint > {
5055 let fp = match ty. kind ( & Interner ) {
5156 TyKind :: Str => TyFingerprint :: Str ,
5257 TyKind :: Never => TyFingerprint :: Never ,
5358 TyKind :: Slice ( ..) => TyFingerprint :: Slice ,
5459 TyKind :: Array ( ..) => TyFingerprint :: Array ,
5560 TyKind :: Scalar ( scalar) => TyFingerprint :: Scalar ( * scalar) ,
5661 TyKind :: Adt ( AdtId ( adt) , _) => TyFingerprint :: Adt ( * adt) ,
57- TyKind :: Tuple ( cardinality, _) => TyFingerprint :: Tuple ( * cardinality) ,
5862 TyKind :: Raw ( mutability, ..) => TyFingerprint :: RawPtr ( * mutability) ,
5963 TyKind :: Foreign ( alias_id, ..) => TyFingerprint :: ForeignType ( * alias_id) ,
60- TyKind :: Function ( FnPointer { sig, substitution : substs, .. } ) => {
61- TyFingerprint :: FnPtr ( substs. 0 . len ( & Interner ) - 1 , * sig)
62- }
6364 TyKind :: Dyn ( _) => ty. dyn_trait ( ) . map ( |trait_| TyFingerprint :: Dyn ( trait_) ) ?,
6465 _ => return None ,
6566 } ;
6667 Some ( fp)
6768 }
69+
70+ /// Creates a TyFingerprint for looking up a trait impl.
71+ pub fn for_trait_impl ( ty : & Ty ) -> Option < TyFingerprint > {
72+ let fp = match ty. kind ( & Interner ) {
73+ TyKind :: Str => TyFingerprint :: Str ,
74+ TyKind :: Never => TyFingerprint :: Never ,
75+ TyKind :: Slice ( ..) => TyFingerprint :: Slice ,
76+ TyKind :: Array ( ..) => TyFingerprint :: Array ,
77+ TyKind :: Scalar ( scalar) => TyFingerprint :: Scalar ( * scalar) ,
78+ TyKind :: Adt ( AdtId ( adt) , _) => TyFingerprint :: Adt ( * adt) ,
79+ TyKind :: Raw ( mutability, ..) => TyFingerprint :: RawPtr ( * mutability) ,
80+ TyKind :: Foreign ( alias_id, ..) => TyFingerprint :: ForeignType ( * alias_id) ,
81+ TyKind :: Dyn ( _) => ty. dyn_trait ( ) . map ( |trait_| TyFingerprint :: Dyn ( trait_) ) ?,
82+ TyKind :: Ref ( _, _, ty) => return TyFingerprint :: for_trait_impl ( ty) ,
83+ TyKind :: Tuple ( _, subst) => {
84+ let first_ty = subst. interned ( ) . get ( 0 ) . map ( |arg| arg. assert_ty_ref ( & Interner ) ) ;
85+ if let Some ( ty) = first_ty {
86+ return TyFingerprint :: for_trait_impl ( ty) ;
87+ } else {
88+ TyFingerprint :: Unit
89+ }
90+ }
91+ TyKind :: AssociatedType ( _, _)
92+ | TyKind :: OpaqueType ( _, _)
93+ | TyKind :: FnDef ( _, _)
94+ | TyKind :: Closure ( _, _)
95+ | TyKind :: Generator ( ..)
96+ | TyKind :: GeneratorWitness ( ..) => TyFingerprint :: Unnameable ,
97+ TyKind :: Function ( fn_ptr) => {
98+ TyFingerprint :: Function ( fn_ptr. substitution . 0 . len ( & Interner ) as u32 )
99+ }
100+ TyKind :: Alias ( _)
101+ | TyKind :: Placeholder ( _)
102+ | TyKind :: BoundVar ( _)
103+ | TyKind :: InferenceVar ( _, _)
104+ | TyKind :: Error => return None ,
105+ } ;
106+ Some ( fp)
107+ }
68108}
69109
70110pub ( crate ) const ALL_INT_FPS : [ TyFingerprint ; 12 ] = [
@@ -112,7 +152,7 @@ impl TraitImpls {
112152 None => continue ,
113153 } ;
114154 let self_ty = db. impl_self_ty ( impl_id) ;
115- let self_ty_fp = TyFingerprint :: for_impl ( self_ty. skip_binders ( ) ) ;
155+ let self_ty_fp = TyFingerprint :: for_trait_impl ( self_ty. skip_binders ( ) ) ;
116156 impls
117157 . map
118158 . entry ( target_trait)
@@ -157,10 +197,13 @@ impl TraitImpls {
157197 }
158198
159199 /// Queries all trait impls for the given type.
160- pub fn for_self_ty ( & self , fp : TyFingerprint ) -> impl Iterator < Item = ImplId > + ' _ {
200+ pub fn for_self_ty_without_blanket_impls (
201+ & self ,
202+ fp : TyFingerprint ,
203+ ) -> impl Iterator < Item = ImplId > + ' _ {
161204 self . map
162205 . values ( )
163- . flat_map ( move |impls| impls. get ( & None ) . into_iter ( ) . chain ( impls . get ( & Some ( fp) ) ) )
206+ . flat_map ( move |impls| impls. get ( & Some ( fp) ) . into_iter ( ) )
164207 . flat_map ( |it| it. iter ( ) . copied ( ) )
165208 }
166209
@@ -215,7 +258,9 @@ impl InherentImpls {
215258 }
216259
217260 let self_ty = db. impl_self_ty ( impl_id) ;
218- if let Some ( fp) = TyFingerprint :: for_impl ( self_ty. skip_binders ( ) ) {
261+ let fp = TyFingerprint :: for_inherent_impl ( self_ty. skip_binders ( ) ) ;
262+ always ! ( fp. is_some( ) ) ;
263+ if let Some ( fp) = fp {
219264 map. entry ( fp) . or_default ( ) . push ( impl_id) ;
220265 }
221266 }
@@ -228,7 +273,7 @@ impl InherentImpls {
228273 }
229274
230275 pub fn for_self_ty ( & self , self_ty : & Ty ) -> & [ ImplId ] {
231- match TyFingerprint :: for_impl ( self_ty) {
276+ match TyFingerprint :: for_inherent_impl ( self_ty) {
232277 Some ( fp) => self . map . get ( & fp) . map ( |vec| vec. as_ref ( ) ) . unwrap_or ( & [ ] ) ,
233278 None => & [ ] ,
234279 }
0 commit comments