22use std:: sync:: Arc ;
33
44use hir_expand:: name:: Name ;
5- use la_arena:: { Arena , Idx } ;
5+ use la_arena:: { Arena , Idx , IdxRange , RawIdx } ;
66use rustc_hash:: FxHashMap ;
77
88use crate :: {
@@ -17,6 +17,7 @@ pub type ScopeId = Idx<ScopeData>;
1717#[ derive( Debug , PartialEq , Eq ) ]
1818pub struct ExprScopes {
1919 scopes : Arena < ScopeData > ,
20+ scope_entries : Arena < ScopeEntry > ,
2021 scope_by_expr : FxHashMap < ExprId , ScopeId > ,
2122}
2223
@@ -41,7 +42,7 @@ pub struct ScopeData {
4142 parent : Option < ScopeId > ,
4243 block : Option < BlockId > ,
4344 label : Option < ( LabelId , Name ) > ,
44- entries : Vec < ScopeEntry > ,
45+ entries : IdxRange < ScopeEntry > ,
4546}
4647
4748impl ExprScopes {
@@ -53,7 +54,7 @@ impl ExprScopes {
5354 }
5455
5556 pub fn entries ( & self , scope : ScopeId ) -> & [ ScopeEntry ] {
56- & self . scopes [ scope] . entries
57+ & self . scope_entries [ self . scopes [ scope] . entries . clone ( ) ]
5758 }
5859
5960 /// If `scope` refers to a block expression scope, returns the corresponding `BlockId`.
@@ -85,31 +86,48 @@ impl ExprScopes {
8586 }
8687}
8788
89+ fn empty_entries ( idx : usize ) -> IdxRange < ScopeEntry > {
90+ IdxRange :: new ( Idx :: from_raw ( RawIdx :: from ( idx as u32 ) ) ..Idx :: from_raw ( RawIdx :: from ( idx as u32 ) ) )
91+ }
92+
8893impl ExprScopes {
8994 fn new ( body : & Body ) -> ExprScopes {
90- let mut scopes =
91- ExprScopes { scopes : Arena :: default ( ) , scope_by_expr : FxHashMap :: default ( ) } ;
95+ let mut scopes = ExprScopes {
96+ scopes : Arena :: default ( ) ,
97+ scope_entries : Arena :: default ( ) ,
98+ scope_by_expr : FxHashMap :: default ( ) ,
99+ } ;
92100 let mut root = scopes. root_scope ( ) ;
93101 scopes. add_params_bindings ( body, root, & body. params ) ;
94102 compute_expr_scopes ( body. body_expr , body, & mut scopes, & mut root) ;
95103 scopes
96104 }
97105
98106 fn root_scope ( & mut self ) -> ScopeId {
99- self . scopes . alloc ( ScopeData { parent : None , block : None , label : None , entries : vec ! [ ] } )
107+ self . scopes . alloc ( ScopeData {
108+ parent : None ,
109+ block : None ,
110+ label : None ,
111+ entries : empty_entries ( self . scope_entries . len ( ) ) ,
112+ } )
100113 }
101114
102115 fn new_scope ( & mut self , parent : ScopeId ) -> ScopeId {
103116 self . scopes . alloc ( ScopeData {
104117 parent : Some ( parent) ,
105118 block : None ,
106119 label : None ,
107- entries : vec ! [ ] ,
120+ entries : empty_entries ( self . scope_entries . len ( ) ) ,
108121 } )
109122 }
110123
111124 fn new_labeled_scope ( & mut self , parent : ScopeId , label : Option < ( LabelId , Name ) > ) -> ScopeId {
112- self . scopes . alloc ( ScopeData { parent : Some ( parent) , block : None , label, entries : vec ! [ ] } )
125+ self . scopes . alloc ( ScopeData {
126+ parent : Some ( parent) ,
127+ block : None ,
128+ label,
129+ entries : empty_entries ( self . scope_entries . len ( ) ) ,
130+ } )
113131 }
114132
115133 fn new_block_scope (
@@ -118,13 +136,19 @@ impl ExprScopes {
118136 block : Option < BlockId > ,
119137 label : Option < ( LabelId , Name ) > ,
120138 ) -> ScopeId {
121- self . scopes . alloc ( ScopeData { parent : Some ( parent) , block, label, entries : vec ! [ ] } )
139+ self . scopes . alloc ( ScopeData {
140+ parent : Some ( parent) ,
141+ block,
142+ label,
143+ entries : empty_entries ( self . scope_entries . len ( ) ) ,
144+ } )
122145 }
123146
124147 fn add_bindings ( & mut self , body : & Body , scope : ScopeId , binding : BindingId ) {
125148 let Binding { name, .. } = & body. bindings [ binding] ;
126- let entry = ScopeEntry { name : name. clone ( ) , binding } ;
127- self . scopes [ scope] . entries . push ( entry) ;
149+ let entry = self . scope_entries . alloc ( ScopeEntry { name : name. clone ( ) , binding } ) ;
150+ self . scopes [ scope] . entries =
151+ IdxRange :: new_inclusive ( self . scopes [ scope] . entries . start ( ) ..=entry) ;
128152 }
129153
130154 fn add_pat_bindings ( & mut self , body : & Body , scope : ScopeId , pat : PatId ) {
@@ -145,9 +169,9 @@ impl ExprScopes {
145169 }
146170
147171 fn shrink_to_fit ( & mut self ) {
148- let ExprScopes { scopes, scope_by_expr } = self ;
172+ let ExprScopes { scopes, scope_entries , scope_by_expr } = self ;
149173 scopes. shrink_to_fit ( ) ;
150- scopes . values_mut ( ) . for_each ( |it| it . entries . shrink_to_fit ( ) ) ;
174+ scope_entries . shrink_to_fit ( ) ;
151175 scope_by_expr. shrink_to_fit ( ) ;
152176 }
153177}
0 commit comments