about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_resolve/lib.rs15
-rw-r--r--src/libunwind/libunwind.rs6
-rw-r--r--src/test/ui/macros/auxiliary/macro-in-other-crate.rs5
-rw-r--r--src/test/ui/macros/macro-shadowing-relaxed.rs35
-rw-r--r--src/test/ui/macros/macro-shadowing.rs2
-rw-r--r--src/test/ui/macros/macro-shadowing.stderr26
6 files changed, 57 insertions, 32 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e1f532232f5..b690f305f16 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1274,9 +1274,18 @@ impl<'a> NameBinding<'a> {
     // expansion round `max(invoc_id, binding)` when they both emerged from macros.
     // Then this function returns `true` if `self` may emerge from a macro *after* that
     // in some later round and screw up our previously found resolution.
-    fn may_appear_after(&self, _invoc_id: Mark, _binding: &NameBinding) -> bool {
-        // FIXME: This is a very conservative estimation.
-        self.expansion != Mark::root()
+    fn may_appear_after(&self, invoc_id: Mark, binding: &NameBinding) -> bool {
+        // self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding)
+        // Expansions are partially ordered, so "may appear after" is an inversion of
+        // "certainly appears before or simultaneously" and includes unordered cases.
+        let self_parent_expansion = self.expansion;
+        let other_parent_expansion = binding.expansion;
+        let invoc_parent_expansion = invoc_id.parent();
+        let certainly_before_other_or_simultaneously =
+            other_parent_expansion.is_descendant_of(self_parent_expansion);
+        let certainly_before_invoc_or_simultaneously =
+            invoc_parent_expansion.is_descendant_of(self_parent_expansion);
+        !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
     }
 }
 
diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
index d9c18408ac9..43c3e1e7666 100644
--- a/src/libunwind/libunwind.rs
+++ b/src/libunwind/libunwind.rs
@@ -10,7 +10,7 @@
 
 #![allow(nonstandard_style)]
 
-macro_rules! cfg_if2 {
+macro_rules! cfg_if {
     ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
         ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
 }
@@ -92,7 +92,7 @@ extern "C" {
     pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
 }
 
-cfg_if2! {
+cfg_if! {
 if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] {
     // Not ARM EHABI
     #[repr(C)]
@@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
         _Unwind_SjLj_RaiseException(exc)
     }
 }
-} // cfg_if2!
+} // cfg_if!
diff --git a/src/test/ui/macros/auxiliary/macro-in-other-crate.rs b/src/test/ui/macros/auxiliary/macro-in-other-crate.rs
index c787cedc2d0..7f716c5012e 100644
--- a/src/test/ui/macros/auxiliary/macro-in-other-crate.rs
+++ b/src/test/ui/macros/auxiliary/macro-in-other-crate.rs
@@ -17,3 +17,8 @@ macro_rules! mac {
 macro_rules! inline {
     () => ()
 }
+
+#[macro_export]
+macro_rules! from_prelude {
+    () => ()
+}
diff --git a/src/test/ui/macros/macro-shadowing-relaxed.rs b/src/test/ui/macros/macro-shadowing-relaxed.rs
new file mode 100644
index 00000000000..8d5b03b098f
--- /dev/null
+++ b/src/test/ui/macros/macro-shadowing-relaxed.rs
@@ -0,0 +1,35 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+// aux-build:macro-in-other-crate.rs
+
+#![feature(decl_macro)]
+
+macro_rules! my_include {() => {
+    // Outer
+    macro m() {}
+    #[macro_use(from_prelude)] extern crate macro_in_other_crate;
+
+    fn inner() {
+        // Inner
+        macro m() {}
+        macro_rules! from_prelude { () => {} }
+
+        // OK, both `m` and `from_prelude` are macro-expanded,
+        // but no more macro-expanded than their counterpart from outer scope.
+        m!();
+        from_prelude!();
+    }
+}}
+
+my_include!();
+
+fn main() {}
diff --git a/src/test/ui/macros/macro-shadowing.rs b/src/test/ui/macros/macro-shadowing.rs
index 85d8f29fe28..bf0a7fa21d3 100644
--- a/src/test/ui/macros/macro-shadowing.rs
+++ b/src/test/ui/macros/macro-shadowing.rs
@@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous
 
 macro_rules! m2 { () => {
     macro_rules! foo { () => {} }
-    foo!(); //~ ERROR `foo` is ambiguous
+    foo!();
 }}
 m2!();
 //^ Since `foo` is not used outside this expansion, it is not a shadowing error.
diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr
index 0f28f123b43..04f4abc4013 100644
--- a/src/test/ui/macros/macro-shadowing.stderr
+++ b/src/test/ui/macros/macro-shadowing.stderr
@@ -30,30 +30,6 @@ LL | macro_rules! foo { () => {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: macro-expanded macros do not shadow
 
-error[E0659]: `foo` is ambiguous
-  --> $DIR/macro-shadowing.rs:31:5
-   |
-LL |     foo!(); //~ ERROR `foo` is ambiguous
-   |     ^^^
-   |
-note: `foo` could refer to the name defined here
-  --> $DIR/macro-shadowing.rs:30:5
-   |
-LL |     macro_rules! foo { () => {} }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | m2!();
-   | ------ in this macro invocation
-note: `foo` could also refer to the name defined here
-  --> $DIR/macro-shadowing.rs:20:5
-   |
-LL |     macro_rules! foo { () => {} }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | m1!();
-   | ------ in this macro invocation
-   = note: macro-expanded macros do not shadow
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0659`.