@@ -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 ) ]
@@ -328,20 +328,160 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
328
328
* original_rib_ident_def,
329
329
ribs,
330
330
) ) ) ;
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,
335
- ns,
336
- parent_scope,
337
- Shadowing :: Unrestricted ,
338
- finalize. map ( |finalize| Finalize { used : Used :: Scope , ..finalize } ) ,
339
- ignore_binding,
340
- None ,
341
- )
342
- {
343
- // The ident resolves to an item in a block.
344
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
331
+ } else if let RibKind :: Block { module, id : block_id } = rib. kind {
332
+ fn resolve_ident_in_forward_macro_of_block < ' ra > (
333
+ r : & mut Resolver < ' ra , ' _ > ,
334
+ expansion : & mut Option < NodeId > , // macro_def_id
335
+ module : Module < ' ra > ,
336
+ resolving_block : NodeId ,
337
+ ident : & mut Ident ,
338
+ i : usize ,
339
+ finalize : Option < Finalize > ,
340
+ ribs : & [ Rib < ' ra > ] ,
341
+ ) -> Option < Res > {
342
+ let items = r. lookahead_items_in_block . get ( & resolving_block) ?;
343
+ for ( node_id, item) in items. iter ( ) . rev ( ) {
344
+ match item {
345
+ LookaheadItemInBlock :: MacroDef { def_id, bindings } => {
346
+ if * def_id != r. macro_def ( ident. span . ctxt ( ) ) {
347
+ continue ;
348
+ }
349
+ expansion. get_or_insert ( * node_id) ;
350
+ ident. span . remove_mark ( ) ;
351
+ if let Some ( ( original_rib_ident_def, ( module_of_res, res) ) ) =
352
+ bindings. get_key_value ( ident)
353
+ && module_of_res. is_ancestor_of ( module)
354
+ {
355
+ // The ident resolves to a type parameter or local variable.
356
+ return Some ( r. validate_res_from_ribs (
357
+ i,
358
+ * ident,
359
+ * res,
360
+ finalize. map ( |finalize| finalize. path_span ) ,
361
+ * original_rib_ident_def,
362
+ ribs,
363
+ ) ) ;
364
+ }
365
+ }
366
+ LookaheadItemInBlock :: Block => {
367
+ // resolve child block later
368
+ }
369
+ LookaheadItemInBlock :: Binding { .. } => { }
370
+ }
371
+ }
372
+
373
+ let subs = items
374
+ . iter ( )
375
+ . filter_map ( |( node_id, item) | {
376
+ if matches ! ( item, LookaheadItemInBlock :: Block ) {
377
+ Some ( * node_id)
378
+ } else {
379
+ None
380
+ }
381
+ } )
382
+ . collect :: < Vec < _ > > ( ) ;
383
+ for node_id in subs {
384
+ if let Some ( res) = resolve_ident_in_forward_macro_of_block (
385
+ r, expansion, module, node_id, ident, i, finalize, ribs,
386
+ ) {
387
+ return Some ( res) ;
388
+ }
389
+ }
390
+
391
+ None
392
+ }
393
+
394
+ fn is_defined_later (
395
+ r : & Resolver < ' _ , ' _ > ,
396
+ expansion : NodeId , // macro_def_id
397
+ block_id : NodeId ,
398
+ ident : & Ident ,
399
+ ) -> bool {
400
+ let Some ( items) = r. lookahead_items_in_block . get ( & block_id) else {
401
+ return false ;
402
+ } ;
403
+ for ( node_id, item) in items {
404
+ match item {
405
+ LookaheadItemInBlock :: Binding { name } => {
406
+ if name. name == ident. name {
407
+ return true ;
408
+ }
409
+ }
410
+ LookaheadItemInBlock :: Block => {
411
+ if is_defined_later ( r, expansion, * node_id, ident) {
412
+ return true ;
413
+ }
414
+ }
415
+ LookaheadItemInBlock :: MacroDef { .. } => {
416
+ if expansion. eq ( node_id) {
417
+ return false ;
418
+ }
419
+ }
420
+ }
421
+ }
422
+
423
+ false
424
+ }
425
+
426
+ let mut expansion = None ;
427
+ if let Some ( res) = resolve_ident_in_forward_macro_of_block (
428
+ self ,
429
+ & mut expansion,
430
+ parent_scope. module ,
431
+ block_id,
432
+ & mut ident,
433
+ i,
434
+ finalize,
435
+ ribs,
436
+ ) {
437
+ return Some ( LexicalScopeBinding :: Res ( res) ) ;
438
+ }
439
+
440
+ if let Some ( expansion) = expansion
441
+ && is_defined_later ( self , expansion, block_id, & ident)
442
+ {
443
+ // return `None` for this case:
444
+ //
445
+ // ```
446
+ // let a = m!();
447
+ // let b = 1;
448
+ // macro_rules! m { () => { b } }
449
+ // use b;
450
+ // ```
451
+ return None ;
452
+ }
453
+
454
+ if let Some ( module) = module
455
+ && let Ok ( binding) = self . cm ( ) . resolve_ident_in_module_unadjusted (
456
+ ModuleOrUniformRoot :: Module ( module) ,
457
+ ident,
458
+ ns,
459
+ parent_scope,
460
+ Shadowing :: Unrestricted ,
461
+ finalize. map ( |finalize| Finalize { used : Used :: Scope , ..finalize } ) ,
462
+ ignore_binding,
463
+ None ,
464
+ )
465
+ {
466
+ // The ident resolves to an item in a block.
467
+ if ns == TypeNS {
468
+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
469
+ }
470
+ let macro_def_id = self . macro_def ( ident. span . ctxt ( ) ) ;
471
+ if !matches ! ( self . tcx. def_kind( macro_def_id) , DefKind :: Macro ( _) ) {
472
+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
473
+ }
474
+ return if binding
475
+ . span
476
+ . ctxt ( )
477
+ . outer_expn ( )
478
+ . outer_expn_is_descendant_of ( ident. span . ctxt ( ) )
479
+ {
480
+ Some ( LexicalScopeBinding :: Item ( binding) )
481
+ } else {
482
+ None
483
+ } ;
484
+ }
345
485
} else if let RibKind :: Module ( module) = rib. kind {
346
486
// Encountered a module item, abandon ribs and look into that module and preludes.
347
487
let parent_scope = & ParentScope { module, ..* parent_scope } ;
@@ -1163,7 +1303,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1163
1303
for rib in ribs {
1164
1304
match rib. kind {
1165
1305
RibKind :: Normal
1166
- | RibKind :: Block ( .. )
1306
+ | RibKind :: Block { .. }
1167
1307
| RibKind :: FnOrCoroutine
1168
1308
| RibKind :: Module ( ..)
1169
1309
| RibKind :: MacroDefinition ( ..)
@@ -1256,7 +1396,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1256
1396
for rib in ribs {
1257
1397
let ( has_generic_params, def_kind) = match rib. kind {
1258
1398
RibKind :: Normal
1259
- | RibKind :: Block ( .. )
1399
+ | RibKind :: Block { .. }
1260
1400
| RibKind :: FnOrCoroutine
1261
1401
| RibKind :: Module ( ..)
1262
1402
| RibKind :: MacroDefinition ( ..)
@@ -1350,7 +1490,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1350
1490
for rib in ribs {
1351
1491
let ( has_generic_params, def_kind) = match rib. kind {
1352
1492
RibKind :: Normal
1353
- | RibKind :: Block ( .. )
1493
+ | RibKind :: Block { .. }
1354
1494
| RibKind :: FnOrCoroutine
1355
1495
| RibKind :: Module ( ..)
1356
1496
| RibKind :: MacroDefinition ( ..)
0 commit comments