Skip to content

Commit 47ce876

Browse files
Auto merge of #143141 - bvanjoi:issue-95237, r=<try>
fresh binding should shadow the def in expand
2 parents f6df223 + ba9916f commit 47ce876

16 files changed

+1773
-77
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: 189 additions & 28 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)]
@@ -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+
4350
impl<'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

Comments
 (0)