@@ -7,7 +7,7 @@ use crate::{
77 body:: Body ,
88 db:: DefDatabase ,
99 hir:: { Binding , BindingId , Expr , ExprId , LabelId , Pat , PatId , Statement } ,
10- BlockId , DefWithBodyId ,
10+ BlockId , ConstBlockId , DefWithBodyId ,
1111} ;
1212
1313pub type ScopeId = Idx < ScopeData > ;
@@ -46,7 +46,9 @@ pub struct ScopeData {
4646impl ExprScopes {
4747 pub ( crate ) fn expr_scopes_query ( db : & dyn DefDatabase , def : DefWithBodyId ) -> Arc < ExprScopes > {
4848 let body = db. body ( def) ;
49- let mut scopes = ExprScopes :: new ( & body) ;
49+ let mut scopes = ExprScopes :: new ( & body, |const_block| {
50+ db. lookup_intern_anonymous_const ( const_block) . root
51+ } ) ;
5052 scopes. shrink_to_fit ( ) ;
5153 Arc :: new ( scopes)
5254 }
@@ -89,7 +91,10 @@ fn empty_entries(idx: usize) -> IdxRange<ScopeEntry> {
8991}
9092
9193impl ExprScopes {
92- fn new ( body : & Body ) -> ExprScopes {
94+ fn new (
95+ body : & Body ,
96+ resolve_const_block : impl ( Fn ( ConstBlockId ) -> ExprId ) + Copy ,
97+ ) -> ExprScopes {
9398 let mut scopes = ExprScopes {
9499 scopes : Arena :: default ( ) ,
95100 scope_entries : Arena :: default ( ) ,
@@ -100,7 +105,7 @@ impl ExprScopes {
100105 scopes. add_bindings ( body, root, self_param) ;
101106 }
102107 scopes. add_params_bindings ( body, root, & body. params ) ;
103- compute_expr_scopes ( body. body_expr , body, & mut scopes, & mut root) ;
108+ compute_expr_scopes ( body. body_expr , body, & mut scopes, & mut root, resolve_const_block ) ;
104109 scopes
105110 }
106111
@@ -183,89 +188,101 @@ fn compute_block_scopes(
183188 body : & Body ,
184189 scopes : & mut ExprScopes ,
185190 scope : & mut ScopeId ,
191+ resolve_const_block : impl ( Fn ( ConstBlockId ) -> ExprId ) + Copy ,
186192) {
187193 for stmt in statements {
188194 match stmt {
189195 Statement :: Let { pat, initializer, else_branch, .. } => {
190196 if let Some ( expr) = initializer {
191- compute_expr_scopes ( * expr, body, scopes, scope) ;
197+ compute_expr_scopes ( * expr, body, scopes, scope, resolve_const_block ) ;
192198 }
193199 if let Some ( expr) = else_branch {
194- compute_expr_scopes ( * expr, body, scopes, scope) ;
200+ compute_expr_scopes ( * expr, body, scopes, scope, resolve_const_block ) ;
195201 }
196202
197203 * scope = scopes. new_scope ( * scope) ;
198204 scopes. add_pat_bindings ( body, * scope, * pat) ;
199205 }
200206 Statement :: Expr { expr, .. } => {
201- compute_expr_scopes ( * expr, body, scopes, scope) ;
207+ compute_expr_scopes ( * expr, body, scopes, scope, resolve_const_block ) ;
202208 }
203209 Statement :: Item => ( ) ,
204210 }
205211 }
206212 if let Some ( expr) = tail {
207- compute_expr_scopes ( expr, body, scopes, scope) ;
213+ compute_expr_scopes ( expr, body, scopes, scope, resolve_const_block ) ;
208214 }
209215}
210216
211- fn compute_expr_scopes ( expr : ExprId , body : & Body , scopes : & mut ExprScopes , scope : & mut ScopeId ) {
217+ fn compute_expr_scopes (
218+ expr : ExprId ,
219+ body : & Body ,
220+ scopes : & mut ExprScopes ,
221+ scope : & mut ScopeId ,
222+ resolve_const_block : impl ( Fn ( ConstBlockId ) -> ExprId ) + Copy ,
223+ ) {
212224 let make_label =
213225 |label : & Option < LabelId > | label. map ( |label| ( label, body. labels [ label] . name . clone ( ) ) ) ;
214226
227+ let compute_expr_scopes = |scopes : & mut ExprScopes , expr : ExprId , scope : & mut ScopeId | {
228+ compute_expr_scopes ( expr, body, scopes, scope, resolve_const_block)
229+ } ;
230+
215231 scopes. set_scope ( expr, * scope) ;
216232 match & body[ expr] {
217233 Expr :: Block { statements, tail, id, label } => {
218234 let mut scope = scopes. new_block_scope ( * scope, * id, make_label ( label) ) ;
219235 // Overwrite the old scope for the block expr, so that every block scope can be found
220236 // via the block itself (important for blocks that only contain items, no expressions).
221237 scopes. set_scope ( expr, scope) ;
222- compute_block_scopes ( statements, * tail, body, scopes, & mut scope) ;
238+ compute_block_scopes ( statements, * tail, body, scopes, & mut scope, resolve_const_block ) ;
223239 }
224- Expr :: Const ( _) => {
225- // FIXME: This is broken.
240+ Expr :: Const ( id) => {
241+ let mut scope = scopes. root_scope ( ) ;
242+ compute_expr_scopes ( scopes, resolve_const_block ( * id) , & mut scope) ;
226243 }
227244 Expr :: Unsafe { id, statements, tail } | Expr :: Async { id, statements, tail } => {
228245 let mut scope = scopes. new_block_scope ( * scope, * id, None ) ;
229246 // Overwrite the old scope for the block expr, so that every block scope can be found
230247 // via the block itself (important for blocks that only contain items, no expressions).
231248 scopes. set_scope ( expr, scope) ;
232- compute_block_scopes ( statements, * tail, body, scopes, & mut scope) ;
249+ compute_block_scopes ( statements, * tail, body, scopes, & mut scope, resolve_const_block ) ;
233250 }
234251 Expr :: Loop { body : body_expr, label } => {
235252 let mut scope = scopes. new_labeled_scope ( * scope, make_label ( label) ) ;
236- compute_expr_scopes ( * body_expr , body , scopes , & mut scope) ;
253+ compute_expr_scopes ( scopes , * body_expr , & mut scope) ;
237254 }
238255 Expr :: Closure { args, body : body_expr, .. } => {
239256 let mut scope = scopes. new_scope ( * scope) ;
240257 scopes. add_params_bindings ( body, scope, args) ;
241- compute_expr_scopes ( * body_expr , body , scopes , & mut scope) ;
258+ compute_expr_scopes ( scopes , * body_expr , & mut scope) ;
242259 }
243260 Expr :: Match { expr, arms } => {
244- compute_expr_scopes ( * expr , body , scopes , scope) ;
261+ compute_expr_scopes ( scopes , * expr , scope) ;
245262 for arm in arms. iter ( ) {
246263 let mut scope = scopes. new_scope ( * scope) ;
247264 scopes. add_pat_bindings ( body, scope, arm. pat ) ;
248265 if let Some ( guard) = arm. guard {
249266 scope = scopes. new_scope ( scope) ;
250- compute_expr_scopes ( guard , body , scopes , & mut scope) ;
267+ compute_expr_scopes ( scopes , guard , & mut scope) ;
251268 }
252- compute_expr_scopes ( arm. expr , body , scopes , & mut scope) ;
269+ compute_expr_scopes ( scopes , arm. expr , & mut scope) ;
253270 }
254271 }
255272 & Expr :: If { condition, then_branch, else_branch } => {
256273 let mut then_branch_scope = scopes. new_scope ( * scope) ;
257- compute_expr_scopes ( condition , body , scopes , & mut then_branch_scope) ;
258- compute_expr_scopes ( then_branch , body , scopes , & mut then_branch_scope) ;
274+ compute_expr_scopes ( scopes , condition , & mut then_branch_scope) ;
275+ compute_expr_scopes ( scopes , then_branch , & mut then_branch_scope) ;
259276 if let Some ( else_branch) = else_branch {
260- compute_expr_scopes ( else_branch , body , scopes , scope) ;
277+ compute_expr_scopes ( scopes , else_branch , scope) ;
261278 }
262279 }
263280 & Expr :: Let { pat, expr } => {
264- compute_expr_scopes ( expr , body , scopes , scope) ;
281+ compute_expr_scopes ( scopes , expr , scope) ;
265282 * scope = scopes. new_scope ( * scope) ;
266283 scopes. add_pat_bindings ( body, * scope, pat) ;
267284 }
268- e => e. walk_child_exprs ( |e| compute_expr_scopes ( e , body , scopes , scope) ) ,
285+ e => e. walk_child_exprs ( |e| compute_expr_scopes ( scopes , e , scope) ) ,
269286 } ;
270287}
271288
0 commit comments