about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_resolve/macros.rs18
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs27
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs25
3 files changed, 69 insertions, 1 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 9ce1e21d0d0..024506ed7f8 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -385,6 +385,22 @@ impl<'a> Resolver<'a> {
             Err(Determinacy::Determined) => {}
         }
 
+        // Ok at this point we've determined that the `attr` above doesn't
+        // actually resolve at this time, so we may want to report an error.
+        // It could be the case, though, that `attr` won't ever resolve! If
+        // there's a custom derive that could be used it might declare `attr` as
+        // a custom attribute accepted by the derive. In this case we don't want
+        // to report this particular invocation as unresolved, but rather we'd
+        // want to move on to the next invocation.
+        //
+        // This loop here looks through all of the derive annotations in scope
+        // and tries to resolve them. If they themselves successfully resolve
+        // *and* the resolve mentions that this attribute's name is a registered
+        // custom attribute then we flag this attribute as known and update
+        // `invoc` above to point to the next invocation.
+        //
+        // By then returning `Undetermined` we should continue resolution to
+        // resolve the next attribute.
         let attr_name = match path.segments.len() {
             1 => path.segments[0].ident.name,
             _ => return Err(determinacy),
@@ -406,8 +422,8 @@ impl<'a> Resolver<'a> {
                             attrs.push(inert_attr);
                             attrs
                         });
+                        return Err(Determinacy::Undetermined)
                     }
-                    return Err(Determinacy::Undetermined);
                 },
                 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
                 Err(Determinacy::Determined) => {}
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs
new file mode 100644
index 00000000000..4609f57bddf
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(Foo)]
+pub fn foo(a: TokenStream) -> TokenStream {
+    "".parse().unwrap()
+}
+
+#[proc_macro_derive(Bar, attributes(custom))]
+pub fn bar(a: TokenStream) -> TokenStream {
+    "".parse().unwrap()
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs b/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs
new file mode 100644
index 00000000000..3b2833a4bcf
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs
@@ -0,0 +1,25 @@
+// Copyright 2018 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.
+
+// aux-build:custom-attr-only-one-derive.rs
+
+#![feature(rust_2018_preview)]
+
+#[macro_use]
+extern crate custom_attr_only_one_derive;
+
+#[derive(Bar, Foo)]
+#[custom = "test"]
+pub enum A {
+    B,
+    C,
+}
+
+fn main() {}