@@ -12,6 +12,7 @@ use hir_expand::{
1212use intern:: { sym, Symbol } ;
1313use la_arena:: { Arena , ArenaMap , Idx } ;
1414use span:: Edition ;
15+ use stdx:: thin_vec:: { thin_vec_with_header_struct, EmptyOptimizedThinVec , ThinVec } ;
1516use syntax:: {
1617 ast:: { self , HasGenericArgs , HasName , IsString } ,
1718 AstPtr ,
@@ -108,31 +109,50 @@ impl TraitRef {
108109 }
109110}
110111
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+
111135/// Compare ty::Ty
112136#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
113137pub enum TypeRef {
114138 Never ,
115139 Placeholder ,
116- Tuple ( Vec < TypeRefId > ) ,
140+ Tuple ( EmptyOptimizedThinVec < TypeRefId > ) ,
117141 Path ( Path ) ,
118142 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 > ) ,
122145 Slice ( TypeRefId ) ,
123146 /// 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 > ) ,
132150 Macro ( AstId < ast:: MacroCall > ) ,
133151 Error ,
134152}
135153
154+ const _: ( ) = assert ! ( size_of:: <TypeRef >( ) == 16 ) ;
155+
136156pub type TypeRefId = Idx < TypeRef > ;
137157
138158#[ derive( Default , Clone , PartialEq , Eq , Debug , Hash ) ]
@@ -212,9 +232,9 @@ impl TypeRef {
212232 pub fn from_ast ( ctx : & LowerCtx < ' _ > , node : ast:: Type ) -> TypeRefId {
213233 let ty = match & node {
214234 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+ ) ) ,
218238 ast:: Type :: NeverType ( ..) => TypeRef :: Never ,
219239 ast:: Type :: PathType ( inner) => {
220240 // FIXME: Use `Path::from_src`
@@ -231,22 +251,25 @@ impl TypeRef {
231251 }
232252 ast:: Type :: ArrayType ( inner) => {
233253 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+ } ) )
235258 }
236259 ast:: Type :: SliceType ( inner) => TypeRef :: Slice ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ) ,
237260 ast:: Type :: RefType ( inner) => {
238261 let inner_ty = TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ;
239262 let lifetime = inner. lifetime ( ) . map ( |lt| LifetimeRef :: new ( & lt) ) ;
240263 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 } ) )
242265 }
243266 ast:: Type :: InferType ( _inner) => TypeRef :: Placeholder ,
244267 ast:: Type :: FnPtrType ( inner) => {
245268 let ret_ty = inner
246269 . ret_type ( )
247270 . and_then ( |rt| rt. ty ( ) )
248271 . 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 ( ) ) ) ;
250273 let mut is_varargs = false ;
251274 let mut params = if let Some ( pl) = inner. param_list ( ) {
252275 if let Some ( param) = pl. params ( ) . last ( ) {
@@ -278,12 +301,7 @@ impl TypeRef {
278301
279302 let abi = inner. abi ( ) . map ( lower_abi) ;
280303 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) )
287305 }
288306 // for types are close enough for our purposes to the inner type for now...
289307 ast:: Type :: ForType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
@@ -315,7 +333,7 @@ impl TypeRef {
315333 }
316334
317335 pub ( crate ) fn unit ( ) -> TypeRef {
318- TypeRef :: Tuple ( Vec :: new ( ) )
336+ TypeRef :: Tuple ( EmptyOptimizedThinVec :: empty ( ) )
319337 }
320338
321339 pub fn walk ( this : TypeRefId , map : & TypesMap , f : & mut impl FnMut ( & TypeRef ) ) {
@@ -325,14 +343,13 @@ impl TypeRef {
325343 let type_ref = & map[ type_ref] ;
326344 f ( type_ref) ;
327345 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) )
330348 }
331349 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) ,
336353 TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
337354 for bound in bounds {
338355 match bound {
@@ -384,11 +401,13 @@ impl TypeRef {
384401pub ( crate ) fn type_bounds_from_ast (
385402 lower_ctx : & LowerCtx < ' _ > ,
386403 type_bounds_opt : Option < ast:: TypeBoundList > ,
387- ) -> Vec < TypeBound > {
404+ ) -> ThinVec < TypeBound > {
388405 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+ ) )
390409 } else {
391- vec ! [ ]
410+ ThinVec :: from_iter ( [ ] )
392411 }
393412}
394413
0 commit comments