Skip to content

Commit ad0afa9

Browse files
committed
resolve: Relax shadowing restriction on macro-expanded macros
... for both legacy and modern macros. Fix previously introduced regressions, add tests.
1 parent 0953d28 commit ad0afa9

File tree

6 files changed

+57
-32
lines changed

6 files changed

+57
-32
lines changed

src/librustc_resolve/lib.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,9 +1274,18 @@ impl<'a> NameBinding<'a> {
12741274
// expansion round `max(invoc_id, binding)` when they both emerged from macros.
12751275
// Then this function returns `true` if `self` may emerge from a macro *after* that
12761276
// in some later round and screw up our previously found resolution.
1277-
fn may_appear_after(&self, _invoc_id: Mark, _binding: &NameBinding) -> bool {
1278-
// FIXME: This is a very conservative estimation.
1279-
self.expansion != Mark::root()
1277+
fn may_appear_after(&self, invoc_id: Mark, binding: &NameBinding) -> bool {
1278+
// self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding)
1279+
// Expansions are partially ordered, so "may appear after" is an inversion of
1280+
// "certainly appears before or simultaneously" and includes unordered cases.
1281+
let self_parent_expansion = self.expansion;
1282+
let other_parent_expansion = binding.expansion;
1283+
let invoc_parent_expansion = invoc_id.parent();
1284+
let certainly_before_other_or_simultaneously =
1285+
other_parent_expansion.is_descendant_of(self_parent_expansion);
1286+
let certainly_before_invoc_or_simultaneously =
1287+
invoc_parent_expansion.is_descendant_of(self_parent_expansion);
1288+
!(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
12801289
}
12811290
}
12821291

src/libunwind/libunwind.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![allow(nonstandard_style)]
1212

13-
macro_rules! cfg_if2 {
13+
macro_rules! cfg_if {
1414
( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
1515
( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
1616
}
@@ -92,7 +92,7 @@ extern "C" {
9292
pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
9393
}
9494

95-
cfg_if2! {
95+
cfg_if! {
9696
if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] {
9797
// Not ARM EHABI
9898
#[repr(C)]
@@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
238238
_Unwind_SjLj_RaiseException(exc)
239239
}
240240
}
241-
} // cfg_if2!
241+
} // cfg_if!

src/test/ui/macros/auxiliary/macro-in-other-crate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ macro_rules! mac {
1717
macro_rules! inline {
1818
() => ()
1919
}
20+
21+
#[macro_export]
22+
macro_rules! from_prelude {
23+
() => ()
24+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-pass
12+
// aux-build:macro-in-other-crate.rs
13+
14+
#![feature(decl_macro)]
15+
16+
macro_rules! my_include {() => {
17+
// Outer
18+
macro m() {}
19+
#[macro_use(from_prelude)] extern crate macro_in_other_crate;
20+
21+
fn inner() {
22+
// Inner
23+
macro m() {}
24+
macro_rules! from_prelude { () => {} }
25+
26+
// OK, both `m` and `from_prelude` are macro-expanded,
27+
// but no more macro-expanded than their counterpart from outer scope.
28+
m!();
29+
from_prelude!();
30+
}
31+
}}
32+
33+
my_include!();
34+
35+
fn main() {}

src/test/ui/macros/macro-shadowing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous
2828

2929
macro_rules! m2 { () => {
3030
macro_rules! foo { () => {} }
31-
foo!(); //~ ERROR `foo` is ambiguous
31+
foo!();
3232
}}
3333
m2!();
3434
//^ Since `foo` is not used outside this expansion, it is not a shadowing error.

src/test/ui/macros/macro-shadowing.stderr

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,6 @@ LL | macro_rules! foo { () => {} }
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3131
= note: macro-expanded macros do not shadow
3232

33-
error[E0659]: `foo` is ambiguous
34-
--> $DIR/macro-shadowing.rs:31:5
35-
|
36-
LL | foo!(); //~ ERROR `foo` is ambiguous
37-
| ^^^
38-
|
39-
note: `foo` could refer to the name defined here
40-
--> $DIR/macro-shadowing.rs:30:5
41-
|
42-
LL | macro_rules! foo { () => {} }
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44-
...
45-
LL | m2!();
46-
| ------ in this macro invocation
47-
note: `foo` could also refer to the name defined here
48-
--> $DIR/macro-shadowing.rs:20:5
49-
|
50-
LL | macro_rules! foo { () => {} }
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52-
...
53-
LL | m1!();
54-
| ------ in this macro invocation
55-
= note: macro-expanded macros do not shadow
56-
57-
error: aborting due to 3 previous errors
33+
error: aborting due to 2 previous errors
5834

5935
For more information about this error, try `rustc --explain E0659`.

0 commit comments

Comments
 (0)