@@ -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 ) ]
@@ -40,6 +40,13 @@ enum Shadowing {
4040 Unrestricted ,
4141}
4242
43+ pub ( crate ) enum ResolveIdentInBlockRes < ' ra > {
44+ Res ( Res ) ,
45+ Item ( NameBinding < ' ra > ) ,
46+ DefinedLater { def_site : Span } ,
47+ NotFound ,
48+ }
49+
4350impl < ' ra , ' tcx > Resolver < ' ra , ' tcx > {
4451 /// A generic scope visitor.
4552 /// Visits scopes in order to resolve some identifier in them or perform other actions.
@@ -270,6 +277,168 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
270277 None
271278 }
272279
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+
273442 /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
274443 /// More specifically, we proceed up the hierarchy of scopes and return the binding for
275444 /// `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> {
328497 * original_rib_ident_def,
329498 ribs,
330499 ) ) ) ;
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,
335503 ns,
336504 parent_scope,
337- Shadowing :: Unrestricted ,
338- finalize. map ( |finalize| Finalize { used : Used :: Scope , ..finalize } ) ,
505+ finalize,
506+ i,
507+ ribs,
339508 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+ }
345517 } else if let RibKind :: Module ( module) = rib. kind {
346518 // Encountered a module item, abandon ribs and look into that module and preludes.
347519 let parent_scope = & ParentScope { module, ..* parent_scope } ;
@@ -360,14 +532,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
360532 . ok ( )
361533 . map ( LexicalScopeBinding :: Item ) ;
362534 }
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- }
371535 }
372536
373537 unreachable ! ( )
@@ -1163,10 +1327,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11631327 for rib in ribs {
11641328 match rib. kind {
11651329 RibKind :: Normal
1166- | RibKind :: Block ( .. )
1330+ | RibKind :: Block { .. }
11671331 | RibKind :: FnOrCoroutine
11681332 | RibKind :: Module ( ..)
1169- | RibKind :: MacroDefinition ( ..)
11701333 | RibKind :: ForwardGenericParamBan ( _) => {
11711334 // Nothing to do. Continue.
11721335 }
@@ -1256,10 +1419,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12561419 for rib in ribs {
12571420 let ( has_generic_params, def_kind) = match rib. kind {
12581421 RibKind :: Normal
1259- | RibKind :: Block ( .. )
1422+ | RibKind :: Block { .. }
12601423 | RibKind :: FnOrCoroutine
12611424 | RibKind :: Module ( ..)
1262- | RibKind :: MacroDefinition ( ..)
12631425 | RibKind :: InlineAsmSym
12641426 | RibKind :: AssocItem
12651427 | RibKind :: ForwardGenericParamBan ( _) => {
@@ -1350,10 +1512,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13501512 for rib in ribs {
13511513 let ( has_generic_params, def_kind) = match rib. kind {
13521514 RibKind :: Normal
1353- | RibKind :: Block ( .. )
1515+ | RibKind :: Block { .. }
13541516 | RibKind :: FnOrCoroutine
13551517 | RibKind :: Module ( ..)
1356- | RibKind :: MacroDefinition ( ..)
13571518 | RibKind :: InlineAsmSym
13581519 | RibKind :: AssocItem
13591520 | RibKind :: ForwardGenericParamBan ( _) => continue ,
0 commit comments