about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-08-29 03:23:28 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-09-08 14:15:11 +0300
commitc057d579abb3a6614e38fa6f93f7f5f22a5e7f13 (patch)
tree533d78bc75fec79e00d31b7ed8b08658e0b6dce6 /src/librustc_resolve
parent27235698f5c73b12539e4765e8dccfec8e27c533 (diff)
downloadrust-c057d579abb3a6614e38fa6f93f7f5f22a5e7f13.tar.gz
rust-c057d579abb3a6614e38fa6f93f7f5f22a5e7f13.zip
resolve: Relax shadowing restriction on macro-expanded macros
... for both legacy and modern macros.
Fix previously introduced regressions, add tests.
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/lib.rs15
1 files changed, 12 insertions, 3 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)
     }
 }