@@ -114,7 +114,7 @@ impl ItemTree {
114114
115115 let ctx = lower:: Ctx :: new ( db, file_id) ;
116116 let mut top_attrs = None ;
117- let ( mut item_tree, mut source_maps) = match_ast ! {
117+ let ( mut item_tree, source_maps) = match_ast ! {
118118 match syntax {
119119 ast:: SourceFile ( file) => {
120120 top_attrs = Some ( RawAttrs :: new( db. upcast( ) , & file, ctx. span_map( ) ) ) ;
@@ -156,7 +156,6 @@ impl ItemTree {
156156 . clone ( )
157157 } else {
158158 item_tree. shrink_to_fit ( ) ;
159- source_maps. shrink_to_fit ( ) ;
160159 ( Arc :: new ( item_tree) , Arc :: new ( source_maps) )
161160 }
162161 }
@@ -176,7 +175,7 @@ impl ItemTree {
176175 let block = loc. ast_id . to_node ( db. upcast ( ) ) ;
177176
178177 let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
179- let ( mut item_tree, mut source_maps) = ctx. lower_block ( & block) ;
178+ let ( mut item_tree, source_maps) = ctx. lower_block ( & block) ;
180179 if item_tree. data . is_none ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
181180 {
182181 EMPTY
@@ -193,7 +192,6 @@ impl ItemTree {
193192 . clone ( )
194193 } else {
195194 item_tree. shrink_to_fit ( ) ;
196- source_maps. shrink_to_fit ( ) ;
197195 ( Arc :: new ( item_tree) , Arc :: new ( source_maps) )
198196 }
199197 }
@@ -332,29 +330,59 @@ struct ItemTreeData {
332330}
333331
334332#[ derive( Default , Debug , Eq , PartialEq ) ]
335- pub struct GenericItemSourceMap {
333+ pub struct ItemTreeSourceMaps {
334+ all_concatenated : Box < [ TypesSourceMap ] > ,
335+ structs_offset : u32 ,
336+ unions_offset : u32 ,
337+ enum_generics_offset : u32 ,
338+ variants_offset : u32 ,
339+ consts_offset : u32 ,
340+ statics_offset : u32 ,
341+ trait_generics_offset : u32 ,
342+ trait_alias_generics_offset : u32 ,
343+ impls_offset : u32 ,
344+ type_aliases_offset : u32 ,
345+ }
346+
347+ #[ derive( Clone , Copy ) ]
348+ pub struct GenericItemSourceMap < ' a > ( & ' a [ TypesSourceMap ; 2 ] ) ;
349+
350+ impl < ' a > GenericItemSourceMap < ' a > {
351+ #[ inline]
352+ pub fn item ( self ) -> & ' a TypesSourceMap {
353+ & self . 0 [ 0 ]
354+ }
355+
356+ #[ inline]
357+ pub fn generics ( self ) -> & ' a TypesSourceMap {
358+ & self . 0 [ 1 ]
359+ }
360+ }
361+
362+ #[ derive( Default , Debug , Eq , PartialEq ) ]
363+ pub struct GenericItemSourceMapBuilder {
336364 pub item : TypesSourceMap ,
337365 pub generics : TypesSourceMap ,
338366}
339367
340368#[ derive( Default , Debug , Eq , PartialEq ) ]
341- pub struct ItemTreeSourceMaps {
342- functions : Vec < GenericItemSourceMap > ,
343- structs : Vec < GenericItemSourceMap > ,
344- unions : Vec < GenericItemSourceMap > ,
369+ struct ItemTreeSourceMapsBuilder {
370+ functions : Vec < GenericItemSourceMapBuilder > ,
371+ structs : Vec < GenericItemSourceMapBuilder > ,
372+ unions : Vec < GenericItemSourceMapBuilder > ,
345373 enum_generics : Vec < TypesSourceMap > ,
346374 variants : Vec < TypesSourceMap > ,
347375 consts : Vec < TypesSourceMap > ,
348376 statics : Vec < TypesSourceMap > ,
349377 trait_generics : Vec < TypesSourceMap > ,
350378 trait_alias_generics : Vec < TypesSourceMap > ,
351- impls : Vec < GenericItemSourceMap > ,
352- type_aliases : Vec < GenericItemSourceMap > ,
379+ impls : Vec < GenericItemSourceMapBuilder > ,
380+ type_aliases : Vec < GenericItemSourceMapBuilder > ,
353381}
354382
355- impl ItemTreeSourceMaps {
356- fn shrink_to_fit ( & mut self ) {
357- let ItemTreeSourceMaps {
383+ impl ItemTreeSourceMapsBuilder {
384+ fn build ( self ) -> ItemTreeSourceMaps {
385+ let ItemTreeSourceMapsBuilder {
358386 functions,
359387 structs,
360388 unions,
@@ -367,44 +395,92 @@ impl ItemTreeSourceMaps {
367395 impls,
368396 type_aliases,
369397 } = self ;
370- functions. shrink_to_fit ( ) ;
371- structs. shrink_to_fit ( ) ;
372- unions. shrink_to_fit ( ) ;
373- enum_generics. shrink_to_fit ( ) ;
374- variants. shrink_to_fit ( ) ;
375- consts. shrink_to_fit ( ) ;
376- statics. shrink_to_fit ( ) ;
377- trait_generics. shrink_to_fit ( ) ;
378- trait_alias_generics. shrink_to_fit ( ) ;
379- impls. shrink_to_fit ( ) ;
380- type_aliases. shrink_to_fit ( ) ;
398+ let structs_offset = functions. len ( ) as u32 * 2 ;
399+ let unions_offset = structs_offset + ( structs. len ( ) as u32 * 2 ) ;
400+ let enum_generics_offset = unions_offset + ( unions. len ( ) as u32 * 2 ) ;
401+ let variants_offset = enum_generics_offset + ( enum_generics. len ( ) as u32 ) ;
402+ let consts_offset = variants_offset + ( variants. len ( ) as u32 ) ;
403+ let statics_offset = consts_offset + ( consts. len ( ) as u32 ) ;
404+ let trait_generics_offset = statics_offset + ( statics. len ( ) as u32 ) ;
405+ let trait_alias_generics_offset = trait_generics_offset + ( trait_generics. len ( ) as u32 ) ;
406+ let impls_offset = trait_alias_generics_offset + ( trait_alias_generics. len ( ) as u32 ) ;
407+ let type_aliases_offset = impls_offset + ( impls. len ( ) as u32 * 2 ) ;
408+ let all_concatenated = generics_concat ( functions)
409+ . chain ( generics_concat ( structs) )
410+ . chain ( generics_concat ( unions) )
411+ . chain ( enum_generics)
412+ . chain ( variants)
413+ . chain ( consts)
414+ . chain ( statics)
415+ . chain ( trait_generics)
416+ . chain ( trait_alias_generics)
417+ . chain ( generics_concat ( impls) )
418+ . chain ( generics_concat ( type_aliases) )
419+ . collect ( ) ;
420+ return ItemTreeSourceMaps {
421+ all_concatenated,
422+ structs_offset,
423+ unions_offset,
424+ enum_generics_offset,
425+ variants_offset,
426+ consts_offset,
427+ statics_offset,
428+ trait_generics_offset,
429+ trait_alias_generics_offset,
430+ impls_offset,
431+ type_aliases_offset,
432+ } ;
433+
434+ fn generics_concat (
435+ source_maps : Vec < GenericItemSourceMapBuilder > ,
436+ ) -> impl Iterator < Item = TypesSourceMap > {
437+ source_maps. into_iter ( ) . flat_map ( |it| [ it. item , it. generics ] )
438+ }
381439 }
382440}
383441
384- macro_rules! index_source_maps {
385- ( $( $field: ident[ $tree_id: ident] = $result: ident, ) * ) => {
386- $(
387- impl Index <FileItemTreeId <$tree_id>> for ItemTreeSourceMaps {
388- type Output = $result;
389- fn index( & self , index: FileItemTreeId <$tree_id>) -> & Self :: Output {
390- & self . $field[ index. 0 . into_raw( ) . into_u32( ) as usize ]
442+ impl ItemTreeSourceMaps {
443+ #[ inline]
444+ fn generic_item ( & self , offset : u32 , index : u32 ) -> GenericItemSourceMap < ' _ > {
445+ GenericItemSourceMap (
446+ self . all_concatenated [ ( offset + ( index * 2 ) ) as usize ..] [ ..2 ] . try_into ( ) . unwrap ( ) ,
447+ )
448+ }
449+
450+ #[ inline]
451+ fn non_generic_item ( & self , offset : u32 , index : u32 ) -> & TypesSourceMap {
452+ & self . all_concatenated [ ( offset + index) as usize ]
453+ }
454+
455+ #[ inline]
456+ pub fn function ( & self , index : FileItemTreeId < Function > ) -> GenericItemSourceMap < ' _ > {
457+ self . generic_item ( 0 , index. 0 . into_raw ( ) . into_u32 ( ) )
458+ }
459+ }
460+
461+ macro_rules! index_item_source_maps {
462+ ( $( $name: ident; $field: ident[ $tree_id: ident] ; $fn: ident; $ret: ty, ) * ) => {
463+ impl ItemTreeSourceMaps {
464+ $(
465+ #[ inline]
466+ pub fn $name( & self , index: FileItemTreeId <$tree_id>) -> $ret {
467+ self . $fn( self . $field, index. 0 . into_raw( ) . into_u32( ) )
391468 }
392- }
393- ) *
469+ ) *
470+ }
394471 } ;
395472}
396- index_source_maps ! {
397- functions[ Function ] = GenericItemSourceMap ,
398- structs[ Struct ] = GenericItemSourceMap ,
399- unions[ Union ] = GenericItemSourceMap ,
400- enum_generics[ Enum ] = TypesSourceMap ,
401- variants[ Variant ] = TypesSourceMap ,
402- consts[ Const ] = TypesSourceMap ,
403- statics[ Static ] = TypesSourceMap ,
404- trait_generics[ Trait ] = TypesSourceMap ,
405- trait_alias_generics[ TraitAlias ] = TypesSourceMap ,
406- impls[ Impl ] = GenericItemSourceMap ,
407- type_aliases[ TypeAlias ] = GenericItemSourceMap ,
473+ index_item_source_maps ! {
474+ strukt; structs_offset[ Struct ] ; generic_item; GenericItemSourceMap <' _>,
475+ union ; unions_offset[ Union ] ; generic_item; GenericItemSourceMap <' _>,
476+ enum_generic; enum_generics_offset[ Enum ] ; non_generic_item; & TypesSourceMap ,
477+ variant; variants_offset[ Variant ] ; non_generic_item; & TypesSourceMap ,
478+ konst; consts_offset[ Const ] ; non_generic_item; & TypesSourceMap ,
479+ statik; statics_offset[ Static ] ; non_generic_item; & TypesSourceMap ,
480+ trait_generic; trait_generics_offset[ Trait ] ; non_generic_item; & TypesSourceMap ,
481+ trait_alias_generic; trait_alias_generics_offset[ TraitAlias ] ; non_generic_item; & TypesSourceMap ,
482+ impl_; impls_offset[ Impl ] ; generic_item; GenericItemSourceMap <' _>,
483+ type_alias; type_aliases_offset[ TypeAlias ] ; generic_item; GenericItemSourceMap <' _>,
408484}
409485
410486#[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
0 commit comments