about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-03-21 17:51:29 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-03-23 11:40:58 +0300
commitc3c0a097a7c6a68c0fcaee3cc3b8fda119f3c5a4 (patch)
treea2422e0a4140ef0f26c31feb2324675503ce38fc
parent37c945dd6178cb520eb1e450a795f8c3b3cc5a3b (diff)
downloadrust-c3c0a097a7c6a68c0fcaee3cc3b8fda119f3c5a4.tar.gz
rust-c3c0a097a7c6a68c0fcaee3cc3b8fda119f3c5a4.zip
resolve: Do not resolve visibilities on proc macro definitions twice
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs9
-rw-r--r--src/test/ui/proc-macro/visibility-path.rs25
-rw-r--r--src/test/ui/proc-macro/visibility-path.stderr14
3 files changed, 47 insertions, 1 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 77d6e4560ab..db500a8b1fd 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1149,7 +1149,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             }))
         } else {
             let module = parent_scope.module;
-            let vis = self.resolve_visibility(&item.vis);
+            let vis = match item.kind {
+                // Visibilities must not be resolved non-speculatively twice
+                // and we already resolved this one as a `fn` item visibility.
+                ItemKind::Fn(..) => self
+                    .resolve_visibility_speculative(&item.vis, true)
+                    .unwrap_or(ty::Visibility::Public),
+                _ => self.resolve_visibility(&item.vis),
+            };
             if vis != ty::Visibility::Public {
                 self.insert_unused_macro(ident, item.id, span);
             }
diff --git a/src/test/ui/proc-macro/visibility-path.rs b/src/test/ui/proc-macro/visibility-path.rs
new file mode 100644
index 00000000000..a73430db2c1
--- /dev/null
+++ b/src/test/ui/proc-macro/visibility-path.rs
@@ -0,0 +1,25 @@
+// Proc macro defined with `pub(path)` doesn't ICEs due to resolving the `path` (issue #68921).
+
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub(self) fn outer(input: TokenStream) -> TokenStream {
+    //~^ ERROR functions tagged with `#[proc_macro]` must be `pub`
+    input
+}
+
+mod m {
+    use proc_macro::*;
+
+    #[proc_macro]
+    pub(super) fn inner(input: TokenStream) -> TokenStream {
+        //~^ ERROR functions tagged with `#[proc_macro]` must currently reside in the root
+        input
+    }
+}
diff --git a/src/test/ui/proc-macro/visibility-path.stderr b/src/test/ui/proc-macro/visibility-path.stderr
new file mode 100644
index 00000000000..1a73cc1963f
--- /dev/null
+++ b/src/test/ui/proc-macro/visibility-path.stderr
@@ -0,0 +1,14 @@
+error: functions tagged with `#[proc_macro]` must be `pub`
+  --> $DIR/visibility-path.rs:12:1
+   |
+LL | pub(self) fn outer(input: TokenStream) -> TokenStream {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions tagged with `#[proc_macro]` must currently reside in the root of the crate
+  --> $DIR/visibility-path.rs:21:5
+   |
+LL |     pub(super) fn inner(input: TokenStream) -> TokenStream {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+