@@ -12,6 +12,7 @@ use hir_expand::{
12
12
use intern:: { sym, Symbol } ;
13
13
use la_arena:: { Arena , ArenaMap , Idx } ;
14
14
use span:: Edition ;
15
+ use stdx:: thin_vec:: { thin_vec_with_header_struct, EmptyOptimizedThinVec , ThinVec } ;
15
16
use syntax:: {
16
17
ast:: { self , HasGenericArgs , HasName , IsString } ,
17
18
AstPtr ,
@@ -108,31 +109,50 @@ impl TraitRef {
108
109
}
109
110
}
110
111
112
+ thin_vec_with_header_struct ! {
113
+ pub new( pub ( crate ) ) struct FnType , FnTypeHeader {
114
+ pub params: [ ( Option <Name >, TypeRefId ) ] ,
115
+ pub is_varargs: bool ,
116
+ pub is_unsafe: bool ,
117
+ pub abi: Option <Symbol >; ref,
118
+ }
119
+ }
120
+
121
+ #[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
122
+ pub struct ArrayType {
123
+ pub ty : TypeRefId ,
124
+ // FIXME: This should be Ast<ConstArg>
125
+ pub len : ConstRef ,
126
+ }
127
+
128
+ #[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
129
+ pub struct RefType {
130
+ pub ty : TypeRefId ,
131
+ pub lifetime : Option < LifetimeRef > ,
132
+ pub mutability : Mutability ,
133
+ }
134
+
111
135
/// Compare ty::Ty
112
136
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
113
137
pub enum TypeRef {
114
138
Never ,
115
139
Placeholder ,
116
- Tuple ( Vec < TypeRefId > ) ,
140
+ Tuple ( EmptyOptimizedThinVec < TypeRefId > ) ,
117
141
Path ( Path ) ,
118
142
RawPtr ( TypeRefId , Mutability ) ,
119
- Reference ( TypeRefId , Option < LifetimeRef > , Mutability ) ,
120
- // FIXME: This should be Array(TypeRefId, Ast<ConstArg>),
121
- Array ( TypeRefId , ConstRef ) ,
143
+ Reference ( Box < RefType > ) ,
144
+ Array ( Box < ArrayType > ) ,
122
145
Slice ( TypeRefId ) ,
123
146
/// A fn pointer. Last element of the vector is the return type.
124
- Fn {
125
- params : Box < [ ( Option < Name > , TypeRefId ) ] > ,
126
- is_varargs : bool ,
127
- is_unsafe : bool ,
128
- abi : Option < Symbol > ,
129
- } ,
130
- ImplTrait ( Vec < TypeBound > ) ,
131
- DynTrait ( Vec < TypeBound > ) ,
147
+ Fn ( FnType ) ,
148
+ ImplTrait ( ThinVec < TypeBound > ) ,
149
+ DynTrait ( ThinVec < TypeBound > ) ,
132
150
Macro ( AstId < ast:: MacroCall > ) ,
133
151
Error ,
134
152
}
135
153
154
+ const _: ( ) = assert ! ( size_of:: <TypeRef >( ) == 16 ) ;
155
+
136
156
pub type TypeRefId = Idx < TypeRef > ;
137
157
138
158
#[ derive( Default , Clone , PartialEq , Eq , Debug , Hash ) ]
@@ -212,9 +232,9 @@ impl TypeRef {
212
232
pub fn from_ast ( ctx : & LowerCtx < ' _ > , node : ast:: Type ) -> TypeRefId {
213
233
let ty = match & node {
214
234
ast:: Type :: ParenType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
215
- ast:: Type :: TupleType ( inner) => {
216
- TypeRef :: Tuple ( inner. fields ( ) . map ( |it| TypeRef :: from_ast ( ctx, it) ) . collect ( ) )
217
- }
235
+ ast:: Type :: TupleType ( inner) => TypeRef :: Tuple ( EmptyOptimizedThinVec :: from_iter (
236
+ Vec :: from_iter ( inner. fields ( ) . map ( |it| TypeRef :: from_ast ( ctx, it) ) ) ,
237
+ ) ) ,
218
238
ast:: Type :: NeverType ( ..) => TypeRef :: Never ,
219
239
ast:: Type :: PathType ( inner) => {
220
240
// FIXME: Use `Path::from_src`
@@ -231,22 +251,25 @@ impl TypeRef {
231
251
}
232
252
ast:: Type :: ArrayType ( inner) => {
233
253
let len = ConstRef :: from_const_arg ( ctx, inner. const_arg ( ) ) ;
234
- TypeRef :: Array ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) , len)
254
+ TypeRef :: Array ( Box :: new ( ArrayType {
255
+ ty : TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
256
+ len,
257
+ } ) )
235
258
}
236
259
ast:: Type :: SliceType ( inner) => TypeRef :: Slice ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ) ,
237
260
ast:: Type :: RefType ( inner) => {
238
261
let inner_ty = TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ;
239
262
let lifetime = inner. lifetime ( ) . map ( |lt| LifetimeRef :: new ( & lt) ) ;
240
263
let mutability = Mutability :: from_mutable ( inner. mut_token ( ) . is_some ( ) ) ;
241
- TypeRef :: Reference ( inner_ty, lifetime, mutability)
264
+ TypeRef :: Reference ( Box :: new ( RefType { ty : inner_ty, lifetime, mutability } ) )
242
265
}
243
266
ast:: Type :: InferType ( _inner) => TypeRef :: Placeholder ,
244
267
ast:: Type :: FnPtrType ( inner) => {
245
268
let ret_ty = inner
246
269
. ret_type ( )
247
270
. and_then ( |rt| rt. ty ( ) )
248
271
. map ( |it| TypeRef :: from_ast ( ctx, it) )
249
- . unwrap_or_else ( || ctx. alloc_type_ref_desugared ( TypeRef :: Tuple ( Vec :: new ( ) ) ) ) ;
272
+ . unwrap_or_else ( || ctx. alloc_type_ref_desugared ( TypeRef :: unit ( ) ) ) ;
250
273
let mut is_varargs = false ;
251
274
let mut params = if let Some ( pl) = inner. param_list ( ) {
252
275
if let Some ( param) = pl. params ( ) . last ( ) {
@@ -278,12 +301,7 @@ impl TypeRef {
278
301
279
302
let abi = inner. abi ( ) . map ( lower_abi) ;
280
303
params. push ( ( None , ret_ty) ) ;
281
- TypeRef :: Fn {
282
- params : params. into ( ) ,
283
- is_varargs,
284
- is_unsafe : inner. unsafe_token ( ) . is_some ( ) ,
285
- abi,
286
- }
304
+ TypeRef :: Fn ( FnType :: new ( is_varargs, inner. unsafe_token ( ) . is_some ( ) , abi, params) )
287
305
}
288
306
// for types are close enough for our purposes to the inner type for now...
289
307
ast:: Type :: ForType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
@@ -315,7 +333,7 @@ impl TypeRef {
315
333
}
316
334
317
335
pub ( crate ) fn unit ( ) -> TypeRef {
318
- TypeRef :: Tuple ( Vec :: new ( ) )
336
+ TypeRef :: Tuple ( EmptyOptimizedThinVec :: empty ( ) )
319
337
}
320
338
321
339
pub fn walk ( this : TypeRefId , map : & TypesMap , f : & mut impl FnMut ( & TypeRef ) ) {
@@ -325,14 +343,13 @@ impl TypeRef {
325
343
let type_ref = & map[ type_ref] ;
326
344
f ( type_ref) ;
327
345
match type_ref {
328
- TypeRef :: Fn { params , is_varargs : _ , is_unsafe : _ , abi : _ } => {
329
- params. iter ( ) . for_each ( |& ( _, param_type) | go ( param_type, f, map) )
346
+ TypeRef :: Fn ( fn_ ) => {
347
+ fn_ . params ( ) . iter ( ) . for_each ( |& ( _, param_type) | go ( param_type, f, map) )
330
348
}
331
349
TypeRef :: Tuple ( types) => types. iter ( ) . for_each ( |& t| go ( t, f, map) ) ,
332
- TypeRef :: RawPtr ( type_ref, _)
333
- | TypeRef :: Reference ( type_ref, ..)
334
- | TypeRef :: Array ( type_ref, _)
335
- | TypeRef :: Slice ( type_ref) => go ( * type_ref, f, map) ,
350
+ TypeRef :: RawPtr ( type_ref, _) | TypeRef :: Slice ( type_ref) => go ( * type_ref, f, map) ,
351
+ TypeRef :: Reference ( it) => go ( it. ty , f, map) ,
352
+ TypeRef :: Array ( it) => go ( it. ty , f, map) ,
336
353
TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
337
354
for bound in bounds {
338
355
match bound {
@@ -384,11 +401,13 @@ impl TypeRef {
384
401
pub ( crate ) fn type_bounds_from_ast (
385
402
lower_ctx : & LowerCtx < ' _ > ,
386
403
type_bounds_opt : Option < ast:: TypeBoundList > ,
387
- ) -> Vec < TypeBound > {
404
+ ) -> ThinVec < TypeBound > {
388
405
if let Some ( type_bounds) = type_bounds_opt {
389
- type_bounds. bounds ( ) . map ( |it| TypeBound :: from_ast ( lower_ctx, it) ) . collect ( )
406
+ ThinVec :: from_iter ( Vec :: from_iter (
407
+ type_bounds. bounds ( ) . map ( |it| TypeBound :: from_ast ( lower_ctx, it) ) ,
408
+ ) )
390
409
} else {
391
- vec ! [ ]
410
+ ThinVec :: from_iter ( [ ] )
392
411
}
393
412
}
394
413
0 commit comments