@@ -17,9 +17,9 @@ use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib
17
17
use crate :: macros:: { MacroRulesScope , sub_namespace_match} ;
18
18
use crate :: {
19
19
AmbiguityError , AmbiguityErrorMisc , AmbiguityKind , BindingKey , CmResolver , Determinacy ,
20
- Finalize , ImportKind , LexicalScopeBinding , Module , ModuleKind , ModuleOrUniformRoot ,
21
- NameBinding , NameBindingKind , ParentScope , PathResult , PrivacyError , Res , ResolutionError ,
22
- Resolver , Scope , ScopeSet , Segment , Stage , Used , Weak , errors,
20
+ Finalize , ImportKind , LexicalScopeBinding , LookaheadItemInBlock , Module , ModuleKind ,
21
+ ModuleOrUniformRoot , NameBinding , NameBindingKind , ParentScope , PathResult , PrivacyError , Res ,
22
+ ResolutionError , Resolver , Scope , ScopeSet , Segment , Stage , Used , Weak , errors,
23
23
} ;
24
24
25
25
#[ derive( Copy , Clone ) ]
@@ -40,6 +40,13 @@ enum Shadowing {
40
40
Unrestricted ,
41
41
}
42
42
43
+ pub ( crate ) enum ResolveIdentInBlockRes < ' ra > {
44
+ Res ( Res ) ,
45
+ Item ( NameBinding < ' ra > ) ,
46
+ DefinedLater { def_site : Span } ,
47
+ NotFound ,
48
+ }
49
+
43
50
impl < ' ra , ' tcx > Resolver < ' ra , ' tcx > {
44
51
/// A generic scope visitor.
45
52
/// Visits scopes in order to resolve some identifier in them or perform other actions.
@@ -270,6 +277,168 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
270
277
None
271
278
}
272
279
280
+ pub ( crate ) fn resolve_ident_in_block_lexical_scope (
281
+ & mut self ,
282
+ ident : & mut Ident ,
283
+ ns : Namespace ,
284
+ parent_scope : & ParentScope < ' ra > ,
285
+ finalize : Option < Finalize > ,
286
+ rib_index : usize ,
287
+ ribs : & [ Rib < ' ra > ] ,
288
+ ignore_binding : Option < NameBinding < ' ra > > ,
289
+ ) -> ResolveIdentInBlockRes < ' ra > {
290
+ let mut original_ident = * ident;
291
+
292
+ fn resolve_ident_in_forward_macro_of_block < ' ra > (
293
+ r : & mut Resolver < ' ra , ' _ > ,
294
+ expansion : & mut Option < NodeId > , // macro_def_id
295
+ module : Module < ' ra > ,
296
+ resolving_block : NodeId ,
297
+ ident : & mut Ident ,
298
+ rib_index : usize ,
299
+ finalize : Option < Finalize > ,
300
+ ribs : & [ Rib < ' ra > ] ,
301
+ ) -> Option < Res > {
302
+ let items = r. lookahead_items_in_block . get ( & resolving_block) ?;
303
+ for ( node_id, item) in items. iter ( ) . rev ( ) {
304
+ match item {
305
+ LookaheadItemInBlock :: MacroDef { def_id } => {
306
+ if * def_id != r. macro_def ( ident. span . ctxt ( ) ) {
307
+ continue ;
308
+ }
309
+ expansion. get_or_insert ( * node_id) ;
310
+ ident. span . remove_mark ( ) ;
311
+ if let Some ( ( original_rib_ident_def, ( module_of_res, res, _) ) ) =
312
+ r. bindings_of_macro_def [ def_id] . get_key_value ( ident)
313
+ && module_of_res. is_ancestor_of ( module)
314
+ {
315
+ // The ident resolves to a type parameter or local variable.
316
+ return Some ( r. validate_res_from_ribs (
317
+ rib_index,
318
+ * ident,
319
+ * res,
320
+ finalize. map ( |finalize| finalize. path_span ) ,
321
+ * original_rib_ident_def,
322
+ ribs,
323
+ ) ) ;
324
+ }
325
+ }
326
+ LookaheadItemInBlock :: Block => {
327
+ // resolve child block later
328
+ }
329
+ LookaheadItemInBlock :: Binding { .. } => { }
330
+ }
331
+ }
332
+
333
+ let subs = items
334
+ . iter ( )
335
+ . filter_map ( |( node_id, item) | {
336
+ if matches ! ( item, LookaheadItemInBlock :: Block ) { Some ( * node_id) } else { None }
337
+ } )
338
+ . collect :: < Vec < _ > > ( ) ;
339
+ for node_id in subs {
340
+ if let Some ( res) = resolve_ident_in_forward_macro_of_block (
341
+ r, expansion, module, node_id, ident, rib_index, finalize, ribs,
342
+ ) {
343
+ return Some ( res) ;
344
+ }
345
+ }
346
+
347
+ None
348
+ }
349
+
350
+ fn is_defined_later (
351
+ r : & Resolver < ' _ , ' _ > ,
352
+ macro_def_node : NodeId ,
353
+ resolving_block : NodeId ,
354
+ ident : & Ident ,
355
+ ) -> Option < Span > {
356
+ let Some ( items) = r. lookahead_items_in_block . get ( & resolving_block) else {
357
+ return None ;
358
+ } ;
359
+ for ( node_id, item) in items {
360
+ match item {
361
+ LookaheadItemInBlock :: Binding { name } => {
362
+ if name. name == ident. name {
363
+ return Some ( name. span ) ;
364
+ }
365
+ }
366
+ LookaheadItemInBlock :: Block => {
367
+ if let Some ( def_span) = is_defined_later ( r, macro_def_node, * node_id, ident)
368
+ {
369
+ return Some ( def_span) ;
370
+ }
371
+ }
372
+ LookaheadItemInBlock :: MacroDef { .. } => {
373
+ if macro_def_node. eq ( node_id) {
374
+ return None ;
375
+ }
376
+ }
377
+ }
378
+ }
379
+
380
+ None
381
+ }
382
+
383
+ let RibKind :: Block { module : block_module, id : resolving_block } = ribs[ rib_index] . kind
384
+ else {
385
+ bug ! ( "expected a block rib" ) ;
386
+ } ;
387
+ let mut expansion = None ;
388
+ if let Some ( res) = resolve_ident_in_forward_macro_of_block (
389
+ self ,
390
+ & mut expansion,
391
+ parent_scope. module ,
392
+ resolving_block,
393
+ ident,
394
+ rib_index,
395
+ finalize,
396
+ ribs,
397
+ ) {
398
+ return ResolveIdentInBlockRes :: Res ( res) ;
399
+ }
400
+
401
+ if let Some ( expansion) = expansion
402
+ && let Some ( def_site) = is_defined_later ( self , expansion, resolving_block, & ident)
403
+ {
404
+ // return `None` for this case:
405
+ //
406
+ // ```
407
+ // let a = m!();
408
+ // let b = 1;
409
+ // macro_rules! m { () => { b } }
410
+ // use b;
411
+ // ```
412
+ return ResolveIdentInBlockRes :: DefinedLater { def_site } ;
413
+ }
414
+
415
+ if let Some ( module) = block_module {
416
+ if let Some ( seen_macro_def_list) = self . seen_macro_def_in_block . get ( & resolving_block) {
417
+ for m in seen_macro_def_list. iter ( ) . rev ( ) {
418
+ if self . macro_def ( original_ident. span . ctxt ( ) ) == * m {
419
+ original_ident. span . remove_mark ( ) ;
420
+ }
421
+ }
422
+ }
423
+
424
+ if let Ok ( binding) = self . cm ( ) . resolve_ident_in_module_unadjusted (
425
+ ModuleOrUniformRoot :: Module ( module) ,
426
+ original_ident,
427
+ ns,
428
+ parent_scope,
429
+ Shadowing :: Unrestricted ,
430
+ finalize. map ( |finalize| Finalize { used : Used :: Scope , ..finalize } ) ,
431
+ ignore_binding,
432
+ None ,
433
+ ) {
434
+ // The ident resolves to an item in a block.
435
+ return ResolveIdentInBlockRes :: Item ( binding) ;
436
+ }
437
+ }
438
+
439
+ ResolveIdentInBlockRes :: NotFound
440
+ }
441
+
273
442
/// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
274
443
/// More specifically, we proceed up the hierarchy of scopes and return the binding for
275
444
/// `ident` in the first scope that defines it (or None if no scopes define it).
@@ -328,20 +497,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
328
497
* original_rib_ident_def,
329
498
ribs,
330
499
) ) ) ;
331
- } else if let RibKind :: Block ( Some ( module) ) = rib. kind
332
- && let Ok ( binding) = self . cm ( ) . resolve_ident_in_module_unadjusted (
333
- ModuleOrUniformRoot :: Module ( module) ,
334
- ident,
500
+ } else if let RibKind :: Block { .. } = rib. kind {
501
+ match self . resolve_ident_in_block_lexical_scope (
502
+ & mut ident,
335
503
ns,
336
504
parent_scope,
337
- Shadowing :: Unrestricted ,
338
- finalize. map ( |finalize| Finalize { used : Used :: Scope , ..finalize } ) ,
505
+ finalize,
506
+ i,
507
+ ribs,
339
508
ignore_binding,
340
- None ,
341
- )
342
- {
343
- // The ident resolves to an item in a block.
344
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
509
+ ) {
510
+ ResolveIdentInBlockRes :: Res ( res) => return Some ( LexicalScopeBinding :: Res ( res) ) ,
511
+ ResolveIdentInBlockRes :: Item ( item) => {
512
+ return Some ( LexicalScopeBinding :: Item ( item) ) ;
513
+ }
514
+ ResolveIdentInBlockRes :: DefinedLater { .. } => return None ,
515
+ ResolveIdentInBlockRes :: NotFound => { }
516
+ }
345
517
} else if let RibKind :: Module ( module) = rib. kind {
346
518
// Encountered a module item, abandon ribs and look into that module and preludes.
347
519
let parent_scope = & ParentScope { module, ..* parent_scope } ;
@@ -360,14 +532,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
360
532
. ok ( )
361
533
. map ( LexicalScopeBinding :: Item ) ;
362
534
}
363
-
364
- if let RibKind :: MacroDefinition ( def) = rib. kind
365
- && def == self . macro_def ( ident. span . ctxt ( ) )
366
- {
367
- // If an invocation of this macro created `ident`, give up on `ident`
368
- // and switch to `ident`'s source from the macro definition.
369
- ident. span . remove_mark ( ) ;
370
- }
371
535
}
372
536
373
537
unreachable ! ( )
@@ -1163,10 +1327,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1163
1327
for rib in ribs {
1164
1328
match rib. kind {
1165
1329
RibKind :: Normal
1166
- | RibKind :: Block ( .. )
1330
+ | RibKind :: Block { .. }
1167
1331
| RibKind :: FnOrCoroutine
1168
1332
| RibKind :: Module ( ..)
1169
- | RibKind :: MacroDefinition ( ..)
1170
1333
| RibKind :: ForwardGenericParamBan ( _) => {
1171
1334
// Nothing to do. Continue.
1172
1335
}
@@ -1256,10 +1419,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1256
1419
for rib in ribs {
1257
1420
let ( has_generic_params, def_kind) = match rib. kind {
1258
1421
RibKind :: Normal
1259
- | RibKind :: Block ( .. )
1422
+ | RibKind :: Block { .. }
1260
1423
| RibKind :: FnOrCoroutine
1261
1424
| RibKind :: Module ( ..)
1262
- | RibKind :: MacroDefinition ( ..)
1263
1425
| RibKind :: InlineAsmSym
1264
1426
| RibKind :: AssocItem
1265
1427
| RibKind :: ForwardGenericParamBan ( _) => {
@@ -1350,10 +1512,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1350
1512
for rib in ribs {
1351
1513
let ( has_generic_params, def_kind) = match rib. kind {
1352
1514
RibKind :: Normal
1353
- | RibKind :: Block ( .. )
1515
+ | RibKind :: Block { .. }
1354
1516
| RibKind :: FnOrCoroutine
1355
1517
| RibKind :: Module ( ..)
1356
- | RibKind :: MacroDefinition ( ..)
1357
1518
| RibKind :: InlineAsmSym
1358
1519
| RibKind :: AssocItem
1359
1520
| RibKind :: ForwardGenericParamBan ( _) => continue ,
0 commit comments