@@ -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,51 @@ 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+ #[ cfg( target_arch = "x86_64" ) ]
155+ const _: ( ) = assert ! ( size_of:: <TypeRef >( ) == 16 ) ;
156+
136157pub type TypeRefId = Idx < TypeRef > ;
137158
138159#[ derive( Default , Clone , PartialEq , Eq , Debug , Hash ) ]
@@ -222,9 +243,9 @@ impl TypeRef {
222243 pub fn from_ast ( ctx : & LowerCtx < ' _ > , node : ast:: Type ) -> TypeRefId {
223244 let ty = match & node {
224245 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+ ) ) ,
228249 ast:: Type :: NeverType ( ..) => TypeRef :: Never ,
229250 ast:: Type :: PathType ( inner) => {
230251 // FIXME: Use `Path::from_src`
@@ -241,22 +262,25 @@ impl TypeRef {
241262 }
242263 ast:: Type :: ArrayType ( inner) => {
243264 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+ } ) )
245269 }
246270 ast:: Type :: SliceType ( inner) => TypeRef :: Slice ( TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ) ,
247271 ast:: Type :: RefType ( inner) => {
248272 let inner_ty = TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ;
249273 let lifetime = inner. lifetime ( ) . map ( |lt| LifetimeRef :: new ( & lt) ) ;
250274 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 } ) )
252276 }
253277 ast:: Type :: InferType ( _inner) => TypeRef :: Placeholder ,
254278 ast:: Type :: FnPtrType ( inner) => {
255279 let ret_ty = inner
256280 . ret_type ( )
257281 . and_then ( |rt| rt. ty ( ) )
258282 . 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 ( ) ) ) ;
260284 let mut is_varargs = false ;
261285 let mut params = if let Some ( pl) = inner. param_list ( ) {
262286 if let Some ( param) = pl. params ( ) . last ( ) {
@@ -288,12 +312,7 @@ impl TypeRef {
288312
289313 let abi = inner. abi ( ) . map ( lower_abi) ;
290314 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) )
297316 }
298317 // for types are close enough for our purposes to the inner type for now...
299318 ast:: Type :: ForType ( inner) => return TypeRef :: from_ast_opt ( ctx, inner. ty ( ) ) ,
@@ -325,7 +344,7 @@ impl TypeRef {
325344 }
326345
327346 pub ( crate ) fn unit ( ) -> TypeRef {
328- TypeRef :: Tuple ( Vec :: new ( ) )
347+ TypeRef :: Tuple ( EmptyOptimizedThinVec :: empty ( ) )
329348 }
330349
331350 pub fn walk ( this : TypeRefId , map : & TypesMap , f : & mut impl FnMut ( & TypeRef ) ) {
@@ -335,14 +354,13 @@ impl TypeRef {
335354 let type_ref = & map[ type_ref] ;
336355 f ( type_ref) ;
337356 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) )
340359 }
341360 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) ,
346364 TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
347365 for bound in bounds {
348366 match bound {
@@ -394,11 +412,13 @@ impl TypeRef {
394412pub ( crate ) fn type_bounds_from_ast (
395413 lower_ctx : & LowerCtx < ' _ > ,
396414 type_bounds_opt : Option < ast:: TypeBoundList > ,
397- ) -> Vec < TypeBound > {
415+ ) -> ThinVec < TypeBound > {
398416 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+ ) )
400420 } else {
401- vec ! [ ]
421+ ThinVec :: from_iter ( [ ] )
402422 }
403423}
404424
0 commit comments