@@ -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,51 @@ 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
+ #[ cfg( target_arch = "x86_64" ) ]
155
+ const _: ( ) = assert ! ( size_of:: <TypeRef >( ) == 16 ) ;
156
+
136
157
pub type TypeRefId = Idx < TypeRef > ;
137
158
138
159
#[ derive( Default , Clone , PartialEq , Eq , Debug , Hash ) ]
@@ -222,9 +243,9 @@ impl TypeRef {
222
243
pub fn from_ast ( ctx : & LowerCtx < ' _ > , node : ast:: Type ) -> TypeRefId {
223
244
let ty = match & node {
224
245
ast:: Type :: ParenType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
225
- ast:: Type :: TupleType ( inner) => {
226
- TypeRef :: Tuple ( inner. fields ( ) . map ( |it| TypeRef :: from_ast ( ctx, it) ) . collect ( ) )
227
- }
246
+ ast:: Type :: TupleType ( inner) => TypeRef :: Tuple ( EmptyOptimizedThinVec :: from_iter (
247
+ Vec :: from_iter ( inner. fields ( ) . map ( |it| TypeRef :: from_ast ( ctx, it) ) ) ,
248
+ ) ) ,
228
249
ast:: Type :: NeverType ( ..) => TypeRef :: Never ,
229
250
ast:: Type :: PathType ( inner) => {
230
251
// FIXME: Use `Path::from_src`
@@ -241,22 +262,25 @@ impl TypeRef {
241
262
}
242
263
ast:: Type :: ArrayType ( inner) => {
243
264
let len = ConstRef :: from_const_arg ( ctx, inner. const_arg ( ) ) ;
244
- TypeRef :: Array ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) , len)
265
+ TypeRef :: Array ( Box :: new ( ArrayType {
266
+ ty : TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
267
+ len,
268
+ } ) )
245
269
}
246
270
ast:: Type :: SliceType ( inner) => TypeRef :: Slice ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ) ,
247
271
ast:: Type :: RefType ( inner) => {
248
272
let inner_ty = TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ;
249
273
let lifetime = inner. lifetime ( ) . map ( |lt| LifetimeRef :: new ( & lt) ) ;
250
274
let mutability = Mutability :: from_mutable ( inner. mut_token ( ) . is_some ( ) ) ;
251
- TypeRef :: Reference ( inner_ty, lifetime, mutability)
275
+ TypeRef :: Reference ( Box :: new ( RefType { ty : inner_ty, lifetime, mutability } ) )
252
276
}
253
277
ast:: Type :: InferType ( _inner) => TypeRef :: Placeholder ,
254
278
ast:: Type :: FnPtrType ( inner) => {
255
279
let ret_ty = inner
256
280
. ret_type ( )
257
281
. and_then ( |rt| rt. ty ( ) )
258
282
. map ( |it| TypeRef :: from_ast ( ctx, it) )
259
- . unwrap_or_else ( || ctx. alloc_type_ref_desugared ( TypeRef :: Tuple ( Vec :: new ( ) ) ) ) ;
283
+ . unwrap_or_else ( || ctx. alloc_type_ref_desugared ( TypeRef :: unit ( ) ) ) ;
260
284
let mut is_varargs = false ;
261
285
let mut params = if let Some ( pl) = inner. param_list ( ) {
262
286
if let Some ( param) = pl. params ( ) . last ( ) {
@@ -288,12 +312,7 @@ impl TypeRef {
288
312
289
313
let abi = inner. abi ( ) . map ( lower_abi) ;
290
314
params. push ( ( None , ret_ty) ) ;
291
- TypeRef :: Fn {
292
- params : params. into ( ) ,
293
- is_varargs,
294
- is_unsafe : inner. unsafe_token ( ) . is_some ( ) ,
295
- abi,
296
- }
315
+ TypeRef :: Fn ( FnType :: new ( is_varargs, inner. unsafe_token ( ) . is_some ( ) , abi, params) )
297
316
}
298
317
// for types are close enough for our purposes to the inner type for now...
299
318
ast:: Type :: ForType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
@@ -325,7 +344,7 @@ impl TypeRef {
325
344
}
326
345
327
346
pub ( crate ) fn unit ( ) -> TypeRef {
328
- TypeRef :: Tuple ( Vec :: new ( ) )
347
+ TypeRef :: Tuple ( EmptyOptimizedThinVec :: empty ( ) )
329
348
}
330
349
331
350
pub fn walk ( this : TypeRefId , map : & TypesMap , f : & mut impl FnMut ( & TypeRef ) ) {
@@ -335,14 +354,13 @@ impl TypeRef {
335
354
let type_ref = & map[ type_ref] ;
336
355
f ( type_ref) ;
337
356
match type_ref {
338
- TypeRef :: Fn { params , is_varargs : _ , is_unsafe : _ , abi : _ } => {
339
- params. iter ( ) . for_each ( |& ( _, param_type) | go ( param_type, f, map) )
357
+ TypeRef :: Fn ( fn_ ) => {
358
+ fn_ . params ( ) . iter ( ) . for_each ( |& ( _, param_type) | go ( param_type, f, map) )
340
359
}
341
360
TypeRef :: Tuple ( types) => types. iter ( ) . for_each ( |& t| go ( t, f, map) ) ,
342
- TypeRef :: RawPtr ( type_ref, _)
343
- | TypeRef :: Reference ( type_ref, ..)
344
- | TypeRef :: Array ( type_ref, _)
345
- | TypeRef :: Slice ( type_ref) => go ( * type_ref, f, map) ,
361
+ TypeRef :: RawPtr ( type_ref, _) | TypeRef :: Slice ( type_ref) => go ( * type_ref, f, map) ,
362
+ TypeRef :: Reference ( it) => go ( it. ty , f, map) ,
363
+ TypeRef :: Array ( it) => go ( it. ty , f, map) ,
346
364
TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
347
365
for bound in bounds {
348
366
match bound {
@@ -394,11 +412,13 @@ impl TypeRef {
394
412
pub ( crate ) fn type_bounds_from_ast (
395
413
lower_ctx : & LowerCtx < ' _ > ,
396
414
type_bounds_opt : Option < ast:: TypeBoundList > ,
397
- ) -> Vec < TypeBound > {
415
+ ) -> ThinVec < TypeBound > {
398
416
if let Some ( type_bounds) = type_bounds_opt {
399
- type_bounds. bounds ( ) . map ( |it| TypeBound :: from_ast ( lower_ctx, it) ) . collect ( )
417
+ ThinVec :: from_iter ( Vec :: from_iter (
418
+ type_bounds. bounds ( ) . map ( |it| TypeBound :: from_ast ( lower_ctx, it) ) ,
419
+ ) )
400
420
} else {
401
- vec ! [ ]
421
+ ThinVec :: from_iter ( [ ] )
402
422
}
403
423
}
404
424
0 commit comments