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