@@ -17,9 +17,9 @@ use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib
1717use crate :: macros:: { MacroRulesScope , sub_namespace_match} ;
1818use crate :: {
1919 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,
2323} ;
2424
2525#[ derive( Copy , Clone ) ]
@@ -328,20 +328,160 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
328328 * original_rib_ident_def,
329329 ribs,
330330 ) ) ) ;
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+ }
345485 } else if let RibKind :: Module ( module) = rib. kind {
346486 // Encountered a module item, abandon ribs and look into that module and preludes.
347487 let parent_scope = & ParentScope { module, ..* parent_scope } ;
@@ -1163,7 +1303,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11631303 for rib in ribs {
11641304 match rib. kind {
11651305 RibKind :: Normal
1166- | RibKind :: Block ( .. )
1306+ | RibKind :: Block { .. }
11671307 | RibKind :: FnOrCoroutine
11681308 | RibKind :: Module ( ..)
11691309 | RibKind :: MacroDefinition ( ..)
@@ -1256,7 +1396,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12561396 for rib in ribs {
12571397 let ( has_generic_params, def_kind) = match rib. kind {
12581398 RibKind :: Normal
1259- | RibKind :: Block ( .. )
1399+ | RibKind :: Block { .. }
12601400 | RibKind :: FnOrCoroutine
12611401 | RibKind :: Module ( ..)
12621402 | RibKind :: MacroDefinition ( ..)
@@ -1350,7 +1490,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13501490 for rib in ribs {
13511491 let ( has_generic_params, def_kind) = match rib. kind {
13521492 RibKind :: Normal
1353- | RibKind :: Block ( .. )
1493+ | RibKind :: Block { .. }
13541494 | RibKind :: FnOrCoroutine
13551495 | RibKind :: Module ( ..)
13561496 | RibKind :: MacroDefinition ( ..)
0 commit comments