Skip to content

Commit 1b4f2b6

Browse files
committed
fresh binding should shadow the def after expand
1 parent 69b76df commit 1b4f2b6

20 files changed

+1474
-62
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
455455

456456
fn block_needs_anonymous_module(&self, block: &Block) -> bool {
457457
// If any statements are items, we need to create an anonymous module
458-
block
459-
.stmts
460-
.iter()
461-
.any(|statement| matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_)))
458+
block.stmts.iter().any(|statement| {
459+
matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_) | StmtKind::Let(_))
460+
})
462461
}
463462

464463
// Add an import to the current module.

compiler/rustc_resolve/src/ident.rs

Lines changed: 160 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib
1717
use crate::macros::{MacroRulesScope, sub_namespace_match};
1818
use 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

Comments
 (0)