]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Introduce two sub-namespaces in macro namespace
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 8 Sep 2018 19:19:53 +0000 (22:19 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Thu, 13 Sep 2018 11:48:50 +0000 (14:48 +0300)
src/librustc_resolve/macros.rs
src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed-2.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/derive-helper-shadowed.rs [new file with mode: 0644]
src/test/ui/issues/issue-11692-2.rs
src/test/ui/issues/issue-11692-2.stderr
src/test/ui/macros/macro-path-prelude-fail-3.rs
src/test/ui/macros/macro-path-prelude-fail-3.stderr
src/test/ui/macros/macro-path-prelude-fail-4.rs [new file with mode: 0644]
src/test/ui/macros/macro-path-prelude-fail-4.stderr [new file with mode: 0644]

index f687e022a412cf646215307bf1c0dda60705c971..cf5a53b63188b2f2c473209030aee4314728443b 100644 (file)
@@ -118,11 +118,21 @@ pub struct ProcMacError {
     warn_msg: &'static str,
 }
 
-// For compatibility bang macros are skipped when resolving potentially built-in attributes.
-fn macro_kind_mismatch(name: Name, requirement: Option<MacroKind>, candidate: Option<MacroKind>)
-                       -> bool {
-    requirement == Some(MacroKind::Attr) && candidate == Some(MacroKind::Bang) &&
-    (name == "test" || name == "bench" || is_builtin_attr_name(name))
+// Macro namespace is separated into two sub-namespaces, one for bang macros and
+// one for attribute-like macros (attributes, derives).
+// We ignore resolutions from one sub-namespace when searching names in scope for another.
+fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<MacroKind>) -> bool {
+    #[derive(PartialEq)]
+    enum SubNS { Bang, AttrLike }
+    let sub_ns = |kind| match kind {
+        MacroKind::Bang => Some(SubNS::Bang),
+        MacroKind::Attr | MacroKind::Derive => Some(SubNS::AttrLike),
+        MacroKind::ProcMacroStub => None,
+    };
+    let requirement = requirement.and_then(|kind| sub_ns(kind));
+    let candidate = candidate.and_then(|kind| sub_ns(kind));
+    // "No specific sub-namespace" means "matches anything" for both requirements and candidates.
+    candidate.is_some() && requirement.is_some() && candidate != requirement
 }
 
 impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
@@ -641,10 +651,7 @@ enum WhereToResolve<'a> {
                     }
                 }
                 WhereToResolve::BuiltinAttrs => {
-                    // FIXME: Only built-in attributes are not considered as candidates for
-                    // non-attributes to fight off regressions on stable channel (#53205).
-                    // We need to come up with some more principled approach instead.
-                    if kind == Some(MacroKind::Attr) && is_builtin_attr_name(ident.name) {
+                    if is_builtin_attr_name(ident.name) {
                         let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
                                        ty::Visibility::Public, ident.span, Mark::root())
                                        .to_name_binding(self.arenas);
@@ -765,7 +772,7 @@ macro_rules! continue_search { () => {
 
             match result {
                 Ok(result) => {
-                    if macro_kind_mismatch(ident.name, kind, result.0.macro_kind()) {
+                    if sub_namespace_mismatch(kind, result.0.macro_kind()) {
                         continue_search!();
                     }
 
@@ -829,7 +836,7 @@ fn resolve_legacy_scope(
         parent_scope: &ParentScope<'a>,
         record_used: bool,
     ) -> Option<&'a NameBinding<'a>> {
-        if macro_kind_mismatch(ident.name, kind, Some(MacroKind::Bang)) {
+        if sub_namespace_mismatch(kind, Some(MacroKind::Bang)) {
             return None;
         }
 
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed-2.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed-2.rs
new file mode 100644 (file)
index 0000000..9912a89
--- /dev/null
@@ -0,0 +1,2 @@
+#[macro_export]
+macro_rules! my_attr { () => () }
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs
new file mode 100644 (file)
index 0000000..4e70171
--- /dev/null
@@ -0,0 +1,11 @@
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_derive(MyTrait, attributes(my_attr))]
+pub fn foo(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowed.rs b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowed.rs
new file mode 100644 (file)
index 0000000..792b54b
--- /dev/null
@@ -0,0 +1,16 @@
+// compile-pass
+// aux-build:derive-helper-shadowed.rs
+// aux-build:derive-helper-shadowed-2.rs
+
+#[macro_use]
+extern crate derive_helper_shadowed;
+#[macro_use(my_attr)]
+extern crate derive_helper_shadowed_2;
+
+macro_rules! my_attr { () => () }
+
+#[derive(MyTrait)]
+#[my_attr] // OK
+struct S;
+
+fn main() {}
index 2e94a27838e433bb6b75fe90a5c5bddef6546656..a4b8b48384d7aa59213dd67d81ca73053fb6ed70 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    concat!(test!()); //~ ERROR `test` can only be used in attributes
+    concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
 }
index 186c59a61493d68a9863569436759baa8bffea62..85f600dbff24e85712d7d16a428242cbe33e4459 100644 (file)
@@ -1,7 +1,7 @@
-error: `test` can only be used in attributes
+error: cannot find macro `test!` in this scope
   --> $DIR/issue-11692-2.rs:12:13
    |
-LL |     concat!(test!()); //~ ERROR `test` can only be used in attributes
+LL |     concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
    |             ^^^^
 
 error: aborting due to previous error
index c706b8f613dd7a78e4c63539b07de81aaead4c2c..597053d625134d831fa6f6c73a2a97ba1d670a51 100644 (file)
@@ -1,16 +1,3 @@
-// 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.
-
-#[derive(inline)] //~ ERROR cannot find derive macro `inline` in this scope
-struct S;
-
 fn main() {
     inline!(); //~ ERROR cannot find macro `inline!` in this scope
 }
index a8edf54d2204851045c74700ca826144a2e3cd96..1772325118174e88fd2c4051f33d1976b0302659 100644 (file)
@@ -1,14 +1,8 @@
-error: cannot find derive macro `inline` in this scope
-  --> $DIR/macro-path-prelude-fail-3.rs:11:10
-   |
-LL | #[derive(inline)] //~ ERROR cannot find derive macro `inline` in this scope
-   |          ^^^^^^
-
 error: cannot find macro `inline!` in this scope
-  --> $DIR/macro-path-prelude-fail-3.rs:15:5
+  --> $DIR/macro-path-prelude-fail-3.rs:2:5
    |
 LL |     inline!(); //~ ERROR cannot find macro `inline!` in this scope
    |     ^^^^^^ help: you could try the macro: `line`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.rs b/src/test/ui/macros/macro-path-prelude-fail-4.rs
new file mode 100644 (file)
index 0000000..283427b
--- /dev/null
@@ -0,0 +1,4 @@
+#[derive(inline)] //~ ERROR expected a macro, found built-in attribute
+struct S;
+
+fn main() {}
diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.stderr b/src/test/ui/macros/macro-path-prelude-fail-4.stderr
new file mode 100644 (file)
index 0000000..e354f34
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected a macro, found built-in attribute
+  --> $DIR/macro-path-prelude-fail-4.rs:1:10
+   |
+LL | #[derive(inline)] //~ ERROR expected a macro, found built-in attribute
+   |          ^^^^^^
+
+error: aborting due to previous error
+