1
- use itertools:: Itertools ;
2
1
use ruff_python_ast as ast;
3
2
use rustc_hash:: FxHashMap ;
4
3
@@ -17,7 +16,7 @@ use crate::{Db, FxOrderSet};
17
16
#[ salsa:: interned( debug) ]
18
17
pub struct GenericContext < ' db > {
19
18
#[ return_ref]
20
- pub ( crate ) variables : Box < [ TypeVarInstance < ' db > ] > ,
19
+ pub ( crate ) variables : FxOrderSet < TypeVarInstance < ' db > > ,
21
20
}
22
21
23
22
impl < ' db > GenericContext < ' db > {
@@ -27,7 +26,7 @@ impl<'db> GenericContext<'db> {
27
26
index : & ' db SemanticIndex < ' db > ,
28
27
type_params_node : & ast:: TypeParams ,
29
28
) -> Self {
30
- let variables: Box < [ _ ] > = type_params_node
29
+ let variables: FxOrderSet < _ > = type_params_node
31
30
. iter ( )
32
31
. filter_map ( |type_param| Self :: variable_from_type_param ( db, index, type_param) )
33
32
. collect ( ) ;
@@ -77,7 +76,6 @@ impl<'db> GenericContext<'db> {
77
76
if variables. is_empty ( ) {
78
77
return None ;
79
78
}
80
- let variables: Box < [ _ ] > = variables. into_iter ( ) . collect ( ) ;
81
79
Some ( Self :: new ( db, variables) )
82
80
}
83
81
@@ -94,7 +92,6 @@ impl<'db> GenericContext<'db> {
94
92
if variables. is_empty ( ) {
95
93
return None ;
96
94
}
97
- let variables: Box < [ _ ] > = variables. into_iter ( ) . collect ( ) ;
98
95
Some ( Self :: new ( db, variables) )
99
96
}
100
97
@@ -149,19 +146,17 @@ impl<'db> GenericContext<'db> {
149
146
}
150
147
151
148
pub ( crate ) fn is_subset_of ( self , db : & ' db dyn Db , other : GenericContext < ' db > ) -> bool {
152
- for variable in self . variables ( db) {
153
- if !other. variables ( db) . iter ( ) . contains ( variable) {
154
- return false ;
155
- }
156
- }
157
- true
149
+ self . variables ( db) . is_subset ( other. variables ( db) )
158
150
}
159
151
152
+ /// Creates a specialization of this generic context. Panics if the length of `types` does not
153
+ /// match the number of typevars in the generic context.
160
154
pub ( crate ) fn specialize (
161
155
self ,
162
156
db : & ' db dyn Db ,
163
157
types : Box < [ Type < ' db > ] > ,
164
158
) -> Specialization < ' db > {
159
+ assert ! ( self . variables( db) . len( ) == types. len( ) ) ;
165
160
Specialization :: new ( db, self , types)
166
161
}
167
162
}
@@ -232,12 +227,11 @@ impl<'db> Specialization<'db> {
232
227
/// Returns the type that a typevar is specialized to, or None if the typevar isn't part of
233
228
/// this specialization.
234
229
pub ( crate ) fn get ( self , db : & ' db dyn Db , typevar : TypeVarInstance < ' db > ) -> Option < Type < ' db > > {
235
- self . generic_context ( db)
230
+ let index = self
231
+ . generic_context ( db)
236
232
. variables ( db)
237
- . into_iter ( )
238
- . zip ( self . types ( db) )
239
- . find ( |( var, _) | * * var == typevar)
240
- . map ( |( _, ty) | * ty)
233
+ . get_index_of ( & typevar) ?;
234
+ Some ( self . types ( db) [ index] )
241
235
}
242
236
243
237
pub ( crate ) fn is_subtype_of ( self , db : & ' db dyn Db , other : Specialization < ' db > ) -> bool {
0 commit comments