Skip to content

Commit adb030d

Browse files
committed
fresh binding should shadow the def after expand
1 parent 64a99db commit adb030d

15 files changed

+1603
-53
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ resolve_binding_shadows_something_unacceptable =
5353
resolve_binding_shadows_something_unacceptable_suggestion =
5454
try specify the pattern arguments
5555
56+
resolve_cannot_access_the_local_binding =
57+
cannot access the local binding `{$name}`
58+
.note = `{$name}` is defined here
59+
5660
resolve_cannot_be_reexported_crate_public =
5761
`{$ident}` is only public within the crate, and cannot be re-exported outside
5862

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/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,3 +1264,13 @@ pub(crate) struct TraitImplMismatch {
12641264
#[label(resolve_trait_impl_mismatch_label_item)]
12651265
pub(crate) trait_item_span: Span,
12661266
}
1267+
1268+
#[derive(Diagnostic)]
1269+
#[diag(resolve_cannot_access_the_local_binding)]
1270+
pub(crate) struct CannotAccessTheLocalBinding {
1271+
#[primary_span]
1272+
pub(crate) span: Span,
1273+
pub(crate) name: Symbol,
1274+
#[note]
1275+
pub(crate) local_binding_def_span: Span,
1276+
}

compiler/rustc_resolve/src/ident.rs

Lines changed: 144 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,144 @@ 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 } => {
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+
r.bindings_of_macro_def[def_id].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+
return Some(LexicalScopeBinding::Item(binding));
468+
}
345469
} else if let RibKind::Module(module) = rib.kind {
346470
// Encountered a module item, abandon ribs and look into that module and preludes.
347471
let parent_scope = &ParentScope { module, ..*parent_scope };
@@ -1163,7 +1287,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11631287
for rib in ribs {
11641288
match rib.kind {
11651289
RibKind::Normal
1166-
| RibKind::Block(..)
1290+
| RibKind::Block { .. }
11671291
| RibKind::FnOrCoroutine
11681292
| RibKind::Module(..)
11691293
| RibKind::MacroDefinition(..)
@@ -1256,7 +1380,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12561380
for rib in ribs {
12571381
let (has_generic_params, def_kind) = match rib.kind {
12581382
RibKind::Normal
1259-
| RibKind::Block(..)
1383+
| RibKind::Block { .. }
12601384
| RibKind::FnOrCoroutine
12611385
| RibKind::Module(..)
12621386
| RibKind::MacroDefinition(..)
@@ -1350,7 +1474,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13501474
for rib in ribs {
13511475
let (has_generic_params, def_kind) = match rib.kind {
13521476
RibKind::Normal
1353-
| RibKind::Block(..)
1477+
| RibKind::Block { .. }
13541478
| RibKind::FnOrCoroutine
13551479
| RibKind::Module(..)
13561480
| RibKind::MacroDefinition(..)

0 commit comments

Comments
 (0)