Skip to content

Commit 3bfa817

Browse files
committed
fresh binding should shadow the def after expand
1 parent 86e05cd commit 3bfa817

File tree

5 files changed

+733
-11
lines changed

5 files changed

+733
-11
lines changed

compiler/rustc_resolve/src/ident.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
330330

331331
module = match rib.kind {
332332
RibKind::Module(module) => module,
333-
RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
333+
RibKind::MacroDefinition(def) | RibKind::LookAheadMacroDefinition(def)
334+
if def == self.macro_def(ident.span.ctxt()) =>
335+
{
334336
// If an invocation of this macro created `ident`, give up on `ident`
335337
// and switch to `ident`'s source from the macro definition.
336338
ident.span.remove_mark();
@@ -1141,6 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11411143
| RibKind::FnOrCoroutine
11421144
| RibKind::Module(..)
11431145
| RibKind::MacroDefinition(..)
1146+
| RibKind::LookAheadMacroDefinition(..)
11441147
| RibKind::ForwardGenericParamBan(_) => {
11451148
// Nothing to do. Continue.
11461149
}
@@ -1233,6 +1236,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12331236
| RibKind::FnOrCoroutine
12341237
| RibKind::Module(..)
12351238
| RibKind::MacroDefinition(..)
1239+
| RibKind::LookAheadMacroDefinition(..)
12361240
| RibKind::InlineAsmSym
12371241
| RibKind::AssocItem
12381242
| RibKind::ForwardGenericParamBan(_) => {
@@ -1326,6 +1330,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13261330
| RibKind::FnOrCoroutine
13271331
| RibKind::Module(..)
13281332
| RibKind::MacroDefinition(..)
1333+
| RibKind::LookAheadMacroDefinition(..)
13291334
| RibKind::InlineAsmSym
13301335
| RibKind::AssocItem
13311336
| RibKind::ForwardGenericParamBan(_) => continue,

compiler/rustc_resolve/src/late.rs

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl IntoDiagArg for PatternSource {
103103
/// Denotes whether the context for the set of already bound bindings is a `Product`
104104
/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
105105
/// See those functions for more information.
106-
#[derive(PartialEq)]
106+
#[derive(PartialEq, Debug)]
107107
enum PatBoundCtx {
108108
/// A product pattern context, e.g., `Variant(a, b)`.
109109
Product,
@@ -217,6 +217,41 @@ pub(crate) enum RibKind<'ra> {
217217
/// We passed through a `macro_rules!` statement
218218
MacroDefinition(DefId),
219219

220+
/// Collects `macro_rules!` statements prior to resolution.
221+
/// For example:
222+
///
223+
/// ```ignore (illustrative)
224+
/// let f = || -> i16 { 42 }; // <1>
225+
/// let a: i16 = m!(); // <2>
226+
/// macro_rules! m {() => ( f() )} // <3>
227+
/// use m; // <4>
228+
/// ```
229+
///
230+
/// We record `<1>` when resolving the value of `<2>` (the expansion
231+
/// result of `<3>`), enabling the system to recognize that `<1>` is
232+
/// referenced in `<3>`.
233+
///
234+
/// ### Why Not Use `MacroDefinition` Directly?
235+
///
236+
/// This prevents edge cases like:
237+
///
238+
/// ```ignore (illustrative)
239+
/// fn f() {
240+
/// let x = 0; // <1>
241+
/// macro_rules! foo {
242+
/// () => {
243+
/// assert_eq!(x, 0);
244+
/// }
245+
/// }
246+
/// let x = 1; // <2>
247+
/// foo!();
248+
/// }
249+
/// ```
250+
///
251+
/// Using `MacroDefinition` would incorrectly record both `<1>` and `<2>` as
252+
/// potential resolutions for `x` within the macro, leading to assertion failed.
253+
LookAheadMacroDefinition(DefId),
254+
220255
/// All bindings in this rib are generic parameters that can't be used
221256
/// from the default of a generic parameter because they're not declared
222257
/// before said generic parameter. Also see the `visit_generics` override.
@@ -247,6 +282,7 @@ impl RibKind<'_> {
247282
| RibKind::ConstantItem(..)
248283
| RibKind::Module(_)
249284
| RibKind::MacroDefinition(_)
285+
| RibKind::LookAheadMacroDefinition(_)
250286
| RibKind::InlineAsmSym => false,
251287
RibKind::ConstParamTy
252288
| RibKind::AssocItem
@@ -258,7 +294,9 @@ impl RibKind<'_> {
258294
/// This rib forbids referring to labels defined in upwards ribs.
259295
fn is_label_barrier(self) -> bool {
260296
match self {
261-
RibKind::Normal | RibKind::MacroDefinition(..) => false,
297+
RibKind::Normal
298+
| RibKind::MacroDefinition(..)
299+
| RibKind::LookAheadMacroDefinition(..) => false,
262300

263301
RibKind::AssocItem
264302
| RibKind::FnOrCoroutine
@@ -3793,17 +3831,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37933831

37943832
/// Apply the bindings from a pattern to the innermost rib of the current scope.
37953833
fn apply_pattern_bindings(&mut self, mut pat_bindings: PatternBindings) {
3796-
let rib_bindings = self.innermost_rib_bindings(ValueNS);
37973834
let Some((_, pat_bindings)) = pat_bindings.pop() else {
37983835
bug!("tried applying nonexistent bindings from pattern");
37993836
};
3800-
3801-
if rib_bindings.is_empty() {
3802-
// Often, such as for match arms, the bindings are introduced into a new rib.
3803-
// In this case, we can move the bindings over directly.
3804-
*rib_bindings = pat_bindings;
3805-
} else {
3806-
rib_bindings.extend(pat_bindings);
3837+
for rib in self.ribs[ValueNS].iter_mut().rev() {
3838+
let stop = !matches!(rib.kind, RibKind::LookAheadMacroDefinition(_));
3839+
if rib.bindings.is_empty() {
3840+
// Often, such as for match arms, the bindings are introduced into a new rib.
3841+
// In this case, we can move the bindings over directly.
3842+
rib.bindings = pat_bindings.clone();
3843+
} else {
3844+
rib.bindings.extend(pat_bindings.clone());
3845+
}
3846+
if stop {
3847+
break;
3848+
}
38073849
}
38083850
}
38093851

@@ -4675,6 +4717,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46754717
}
46764718

46774719
// Descend into the block.
4720+
for stmt in &block.stmts {
4721+
if let StmtKind::Item(ref item) = stmt.kind
4722+
&& let ItemKind::MacroDef(..) = item.kind
4723+
{
4724+
let res = self.r.local_def_id(item.id).to_def_id();
4725+
self.ribs[ValueNS].push(Rib::new(RibKind::LookAheadMacroDefinition(res)));
4726+
}
4727+
}
4728+
46784729
for stmt in &block.stmts {
46794730
if let StmtKind::Item(ref item) = stmt.kind
46804731
&& let ItemKind::MacroDef(..) = item.kind
@@ -4691,6 +4742,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46914742
// Move back up.
46924743
self.parent_scope.module = orig_module;
46934744
for _ in 0..num_macro_definition_ribs {
4745+
// pop `LookAheadMacroDefinition` and `MacroDefinition`
4746+
self.ribs[ValueNS].pop();
46944747
self.ribs[ValueNS].pop();
46954748
self.label_ribs.pop();
46964749
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
//@ check-pass
2+
//@ edition:2018
3+
// issue#95237
4+
5+
6+
#![feature(decl_macro)]
7+
8+
fn f_without_definition_f() {
9+
let f = || -> i16 { 42 };
10+
let a: i16 = m!();
11+
macro m() { f() }
12+
}
13+
14+
fn f_without_closure_f() {
15+
fn f() -> i8 { 42 }
16+
let a: i8 = m!();
17+
macro m() { f() }
18+
}
19+
20+
fn f0() {
21+
let f = || -> i16 { 42 };
22+
fn f() -> i8 { 42 }
23+
let a: i16 = m!();
24+
macro m() { f() }
25+
}
26+
27+
fn f1() {
28+
let f = || -> i16 { 42 };
29+
let a: i16 = m!();
30+
fn f() -> i8 { 42 }
31+
macro m() { f() }
32+
}
33+
34+
fn f2() {
35+
let f = || -> i16 { 42 };
36+
let a: i16 = m!();
37+
macro m() { f() }
38+
fn f() -> i8 { 42 }
39+
}
40+
41+
fn f3() {
42+
let f = || -> i16 { 42 };
43+
macro m() { f() }
44+
let a: i16 = m!();
45+
fn f() -> i8 { 42 }
46+
}
47+
48+
fn f4() {
49+
let f = || -> i16 { 42 };
50+
macro m() { f() }
51+
fn f() -> i8 { 42 }
52+
let a: i16 = m!();
53+
}
54+
55+
fn f5() {
56+
let f = || -> i16 { 42 };
57+
fn f() -> i8 { 42 }
58+
macro m() { f() }
59+
let a: i16 = m!();
60+
}
61+
62+
fn f6() {
63+
fn f() -> i8 { 42 }
64+
let f = || -> i16 { 42 };
65+
let a: i16 = m!();
66+
macro m() { f() }
67+
}
68+
69+
fn f7() {
70+
fn f() -> i8 { 42 }
71+
let f = || -> i16 { 42 };
72+
macro m() { f() }
73+
let a: i16 = m!();
74+
}
75+
76+
fn f8() {
77+
fn f() -> i8 { 42 }
78+
let a: i8 = m!();
79+
let f = || -> i16 { 42 };
80+
macro m() { f() }
81+
}
82+
83+
fn f9() {
84+
fn f() -> i8 { 42 }
85+
let a: i8 = m!();
86+
macro m() { f() }
87+
let f = || -> i16 { 42 };
88+
}
89+
90+
fn f10() {
91+
fn f() -> i8 { 42 }
92+
macro m() { f() }
93+
let a: i8 = m!();
94+
let f = || -> i16 { 42 };
95+
}
96+
97+
fn f11() {
98+
fn f() -> i8 { 42 }
99+
macro m() { f() }
100+
let f = || -> i16 { 42 };
101+
let a: i8 = m!();
102+
}
103+
104+
fn f12() {
105+
let a: i8 = m!();
106+
fn f() -> i8 { 42 }
107+
let f = || -> i16 { 42 };
108+
macro m() { f() }
109+
}
110+
111+
fn f13() {
112+
let a: i8 = m!();
113+
let f = || -> i16 { 42 };
114+
fn f() -> i8 { 42 }
115+
macro m() { f() }
116+
}
117+
118+
fn f14() {
119+
let a: i8 = m!();
120+
let f = || -> i16 { 42 };
121+
macro m() { f() }
122+
fn f() -> i8 { 42 }
123+
}
124+
125+
fn f15() {
126+
let a: i8 = m!();
127+
macro m() { f() }
128+
let f = || -> i16 { 42 };
129+
fn f() -> i8 { 42 }
130+
}
131+
132+
fn f16() {
133+
let a: i8 = m!();
134+
macro m() { f() }
135+
fn f() -> i8 { 42 }
136+
let f = || -> i16 { 42 };
137+
}
138+
139+
fn f17() {
140+
let a: i8 = m!();
141+
fn f() -> i8 { 42 }
142+
macro m() { f() }
143+
let f = || -> i16 { 42 };
144+
}
145+
146+
fn f18() {
147+
macro m() { f() }
148+
let a: i8 = m!();
149+
fn f() -> i8 { 42 }
150+
let f = || -> i16 { 42 };
151+
}
152+
153+
fn f19() {
154+
macro m() { f() }
155+
fn f() -> i8 { 42 }
156+
let a: i8 = m!();
157+
let f = || -> i16 { 42 };
158+
}
159+
160+
fn f20() {
161+
macro m() { f() }
162+
fn f() -> i8 { 42 }
163+
let f = || -> i16 { 42 };
164+
let a: i8 = m!();
165+
}
166+
167+
fn f21() {
168+
macro m() { f() }
169+
let a: i8 = m!();
170+
let f = || -> i16 { 42 };
171+
fn f() -> i8 { 42 }
172+
}
173+
174+
fn f22() {
175+
macro m() { f() }
176+
let f = || -> i16 { 42 };
177+
fn f() -> i8 { 42 }
178+
let a: i8 = m!();
179+
}
180+
181+
fn f23() {
182+
macro m() { f() }
183+
let f = || -> i16 { 42 };
184+
let a: i8 = m!();
185+
fn f() -> i8 { 42 }
186+
}
187+
188+
fn main () {}

0 commit comments

Comments
 (0)