Skip to content

Commit ec8d2bf

Browse files
committed
fresh binding should shadow the def after expand
1 parent cccf075 commit ec8d2bf

File tree

5 files changed

+742
-11
lines changed

5 files changed

+742
-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();
@@ -1165,6 +1167,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11651167
| RibKind::FnOrCoroutine
11661168
| RibKind::Module(..)
11671169
| RibKind::MacroDefinition(..)
1170+
| RibKind::LookAheadMacroDefinition(..)
11681171
| RibKind::ForwardGenericParamBan(_) => {
11691172
// Nothing to do. Continue.
11701173
}
@@ -1257,6 +1260,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12571260
| RibKind::FnOrCoroutine
12581261
| RibKind::Module(..)
12591262
| RibKind::MacroDefinition(..)
1263+
| RibKind::LookAheadMacroDefinition(..)
12601264
| RibKind::InlineAsmSym
12611265
| RibKind::AssocItem
12621266
| RibKind::ForwardGenericParamBan(_) => {
@@ -1350,6 +1354,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13501354
| RibKind::FnOrCoroutine
13511355
| RibKind::Module(..)
13521356
| RibKind::MacroDefinition(..)
1357+
| RibKind::LookAheadMacroDefinition(..)
13531358
| RibKind::InlineAsmSym
13541359
| RibKind::AssocItem
13551360
| 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
@@ -3791,17 +3829,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37913829

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

@@ -4673,6 +4715,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46734715
}
46744716

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

0 commit comments

Comments
 (0)