about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-09-19 01:46:18 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-10-05 11:40:40 +0400
commit8994c6d417e25eba3cd077c0dce5760cfd05d576 (patch)
tree853afa3e3ea0e7eda630137e8c39183c29259e98
parent60a1d4e6c2b23eeed79ea7ca2cbc43713d10197e (diff)
downloadrust-8994c6d417e25eba3cd077c0dce5760cfd05d576.tar.gz
rust-8994c6d417e25eba3cd077c0dce5760cfd05d576.zip
expansion: Remove restriction on use of macro attributes with test/bench
The restrictions were introduced in https://github.com/rust-lang/rust/pull/54277 and no longer necessary now because legacy plugins are now expanded in usual left-to-right order
-rw-r--r--src/librustc_resolve/macros.rs23
-rw-r--r--src/libsyntax/ext/expand.rs73
-rw-r--r--src/libsyntax/feature_gate.rs4
-rw-r--r--src/libsyntax_ext/test.rs8
-rw-r--r--src/test/run-pass-fulldeps/macro-crate.rs2
-rw-r--r--src/test/ui-fulldeps/attribute-order-restricted.rs20
-rw-r--r--src/test/ui-fulldeps/attribute-order-restricted.stderr28
7 files changed, 44 insertions, 114 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index e0ef286a43e..b9f51786e86 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -24,7 +24,7 @@ use syntax::attr;
 use syntax::errors::DiagnosticBuilder;
 use syntax::ext::base::{self, Determinacy};
 use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
-use syntax::ext::expand::{AstFragment, Invocation, InvocationKind, TogetherWith};
+use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
 use syntax::ext::hygiene::{self, Mark};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{self, feature_err, emit_feature_err, is_builtin_attr_name, GateIssue};
@@ -313,29 +313,24 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
-        let (path, kind, derives_in_scope, together_with) = match invoc.kind {
+        let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
             InvocationKind::Attr { attr: None, .. } =>
                 return Ok(None),
-            InvocationKind::Attr { attr: Some(ref attr), ref traits, together_with, .. } =>
-                (&attr.path, MacroKind::Attr, traits.clone(), together_with),
+            InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } =>
+                (&attr.path, MacroKind::Attr, traits.clone(), after_derive),
             InvocationKind::Bang { ref mac, .. } =>
-                (&mac.node.path, MacroKind::Bang, Vec::new(), TogetherWith::None),
+                (&mac.node.path, MacroKind::Bang, Vec::new(), false),
             InvocationKind::Derive { ref path, .. } =>
-                (path, MacroKind::Derive, Vec::new(), TogetherWith::None),
+                (path, MacroKind::Derive, Vec::new(), false),
         };
 
         let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
         let (def, ext) = self.resolve_macro_to_def(path, kind, &parent_scope, force)?;
 
         if let Def::Macro(def_id, _) = def {
-            match together_with {
-                TogetherWith::Derive =>
-                    self.session.span_err(invoc.span(),
-                        "macro attributes must be placed before `#[derive]`"),
-                TogetherWith::TestBench if !self.session.features_untracked().plugin =>
-                    self.session.span_err(invoc.span(),
-                        "macro attributes cannot be used together with `#[test]` or `#[bench]`"),
-                _ => {}
+            if after_derive {
+                self.session.span_err(invoc.span(),
+                                      "macro attributes must be placed before `#[derive]`");
             }
             self.macro_defs.insert(invoc.expansion_data.mark, def_id);
             let normal_module_def_id =
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 52322e98d46..e6e34dc8569 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -220,14 +220,6 @@ pub struct Invocation {
     pub expansion_data: ExpansionData,
 }
 
-// Needed for feature-gating attributes used after derives or together with test/bench
-#[derive(Clone, Copy, PartialEq)]
-pub enum TogetherWith {
-    None,
-    Derive,
-    TestBench,
-}
-
 pub enum InvocationKind {
     Bang {
         mac: ast::Mac,
@@ -238,7 +230,8 @@ pub enum InvocationKind {
         attr: Option<ast::Attribute>,
         traits: Vec<Path>,
         item: Annotatable,
-        together_with: TogetherWith,
+        // We temporarily report errors for attribute macros placed after derives
+        after_derive: bool,
     },
     Derive {
         path: Path,
@@ -1084,19 +1077,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                     traits: Vec<Path>,
                     item: Annotatable,
                     kind: AstFragmentKind,
-                    together_with: TogetherWith)
+                    after_derive: bool)
                     -> AstFragment {
-        self.collect(kind, InvocationKind::Attr { attr, traits, item, together_with })
+        self.collect(kind, InvocationKind::Attr { attr, traits, item, after_derive })
     }
 
-    fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, together_with: &mut TogetherWith)
+    fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bool)
                        -> Option<ast::Attribute> {
         let attr = attrs.iter()
                         .position(|a| {
                             if a.path == "derive" {
-                                *together_with = TogetherWith::Derive
-                            } else if a.path == "rustc_test_marker2" {
-                                *together_with = TogetherWith::TestBench
+                                *after_derive = true;
                             }
                             !attr::is_known(a) && !is_builtin_attr(a)
                         })
@@ -1109,19 +1100,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                                  "non-builtin inner attributes are unstable");
             }
         }
-        if together_with == &TogetherWith::None &&
-           attrs.iter().any(|a| a.path == "rustc_test_marker2") {
-            *together_with = TogetherWith::TestBench;
-        }
         attr
     }
 
     /// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
     fn classify_item<T>(&mut self, mut item: T)
-                        -> (Option<ast::Attribute>, Vec<Path>, T, TogetherWith)
+                        -> (Option<ast::Attribute>, Vec<Path>, T, /* after_derive */ bool)
         where T: HasAttrs,
     {
-        let (mut attr, mut traits, mut together_with) = (None, Vec::new(), TogetherWith::None);
+        let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
 
         item = item.map_attrs(|mut attrs| {
             if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
@@ -1130,20 +1117,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                 return attrs;
             }
 
-            attr = self.find_attr_invoc(&mut attrs, &mut together_with);
+            attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
             traits = collect_derives(&mut self.cx, &mut attrs);
             attrs
         });
 
-        (attr, traits, item, together_with)
+        (attr, traits, item, after_derive)
     }
 
     /// Alternative of `classify_item()` that ignores `#[derive]` so invocations fallthrough
     /// to the unused-attributes lint (making it an error on statements and expressions
     /// is a breaking change)
     fn classify_nonitem<T: HasAttrs>(&mut self, mut item: T)
-                                     -> (Option<ast::Attribute>, T, TogetherWith) {
-        let (mut attr, mut together_with) = (None, TogetherWith::None);
+                                     -> (Option<ast::Attribute>, T, /* after_derive */ bool) {
+        let (mut attr, mut after_derive) = (None, false);
 
         item = item.map_attrs(|mut attrs| {
             if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
@@ -1152,11 +1139,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                 return attrs;
             }
 
-            attr = self.find_attr_invoc(&mut attrs, &mut together_with);
+            attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
             attrs
         });
 
-        (attr, item, together_with)
+        (attr, item, after_derive)
     }
 
     fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
@@ -1195,7 +1182,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
         expr.node = self.cfg.configure_expr_kind(expr.node);
 
         // ignore derives so they remain unused
-        let (attr, expr, together_with) = self.classify_nonitem(expr);
+        let (attr, expr, after_derive) = self.classify_nonitem(expr);
 
         if attr.is_some() {
             // collect the invoc regardless of whether or not attributes are permitted here
@@ -1204,7 +1191,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
 
             // AstFragmentKind::Expr requires the macro to emit an expression
             return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::Expr, together_with).make_expr();
+                                     AstFragmentKind::Expr, after_derive).make_expr();
         }
 
         if let ast::ExprKind::Mac(mac) = expr.node {
@@ -1220,13 +1207,13 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
         expr.node = self.cfg.configure_expr_kind(expr.node);
 
         // ignore derives so they remain unused
-        let (attr, expr, together_with) = self.classify_nonitem(expr);
+        let (attr, expr, after_derive) = self.classify_nonitem(expr);
 
         if attr.is_some() {
             attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
             return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::OptExpr, together_with).make_opt_expr();
+                                     AstFragmentKind::OptExpr, after_derive).make_opt_expr();
         }
 
         if let ast::ExprKind::Mac(mac) = expr.node {
@@ -1258,18 +1245,18 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
 
         // we'll expand attributes on expressions separately
         if !stmt.is_expr() {
-            let (attr, derives, stmt_, together_with) = if stmt.is_item() {
+            let (attr, derives, stmt_, after_derive) = if stmt.is_item() {
                 self.classify_item(stmt)
             } else {
                 // ignore derives on non-item statements so it falls through
                 // to the unused-attributes lint
-                let (attr, stmt, together_with) = self.classify_nonitem(stmt);
-                (attr, vec![], stmt, together_with)
+                let (attr, stmt, after_derive) = self.classify_nonitem(stmt);
+                (attr, vec![], stmt, after_derive)
             };
 
             if attr.is_some() || !derives.is_empty() {
                 return self.collect_attr(attr, derives, Annotatable::Stmt(P(stmt_)),
-                                         AstFragmentKind::Stmts, together_with).make_stmts();
+                                         AstFragmentKind::Stmts, after_derive).make_stmts();
             }
 
             stmt = stmt_;
@@ -1311,10 +1298,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
         let item = configure!(self, item);
 
-        let (attr, traits, item, together_with) = self.classify_item(item);
+        let (attr, traits, item, after_derive) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             return self.collect_attr(attr, traits, Annotatable::Item(item),
-                                     AstFragmentKind::Items, together_with).make_items();
+                                     AstFragmentKind::Items, after_derive).make_items();
         }
 
         match item.node {
@@ -1386,10 +1373,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
         let item = configure!(self, item);
 
-        let (attr, traits, item, together_with) = self.classify_item(item);
+        let (attr, traits, item, after_derive) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             return self.collect_attr(attr, traits, Annotatable::TraitItem(P(item)),
-                                     AstFragmentKind::TraitItems, together_with).make_trait_items()
+                                     AstFragmentKind::TraitItems, after_derive).make_trait_items()
         }
 
         match item.node {
@@ -1405,10 +1392,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
         let item = configure!(self, item);
 
-        let (attr, traits, item, together_with) = self.classify_item(item);
+        let (attr, traits, item, after_derive) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             return self.collect_attr(attr, traits, Annotatable::ImplItem(P(item)),
-                                     AstFragmentKind::ImplItems, together_with).make_impl_items();
+                                     AstFragmentKind::ImplItems, after_derive).make_impl_items();
         }
 
         match item.node {
@@ -1440,11 +1427,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_foreign_item(&mut self, foreign_item: ast::ForeignItem)
         -> SmallVec<[ast::ForeignItem; 1]>
     {
-        let (attr, traits, foreign_item, together_with) = self.classify_item(foreign_item);
+        let (attr, traits, foreign_item, after_derive) = self.classify_item(foreign_item);
 
         if attr.is_some() || !traits.is_empty() {
             return self.collect_attr(attr, traits, Annotatable::ForeignItem(P(foreign_item)),
-                                     AstFragmentKind::ForeignItems, together_with)
+                                     AstFragmentKind::ForeignItems, after_derive)
                                      .make_foreign_items();
         }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index adbe2f9d439..0cc3ef60cee 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -990,10 +990,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                      "the `#[rustc_test_marker]` attribute \
                                       is used internally to track tests",
                                      cfg_fn!(rustc_attrs))),
-    ("rustc_test_marker2", Normal, Gated(Stability::Unstable,
-                                         "rustc_attrs",
-                                         "temporarily used by rustc to report some errors",
-                                         cfg_fn!(rustc_attrs))),
     ("rustc_transparent_macro", Whitelisted, Gated(Stability::Unstable,
                                                    "rustc_attrs",
                                                    "used internally for testing macro hygiene",
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 8ddfb1d9cba..be3485cfa7c 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -49,7 +49,7 @@ pub fn expand_test_or_bench(
     // If we're not in test configuration, remove the annotated item
     if !cx.ecfg.should_test { return vec![]; }
 
-    let mut item =
+    let item =
         if let Annotatable::Item(i) = item { i }
         else {
             cx.parse_sess.span_diagnostic.span_fatal(item.span(),
@@ -192,12 +192,6 @@ pub fn expand_test_or_bench(
 
     debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
 
-    // Temporarily add another marker to the original item for error reporting
-    let marker2 = cx.attribute(
-        attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker2"))
-    );
-    item.attrs.push(marker2);
-
     vec![
         // Access to libtest under a gensymed name
         Annotatable::Item(test_extern),
diff --git a/src/test/run-pass-fulldeps/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs
index c3e7787cf7f..f51a6aae068 100644
--- a/src/test/run-pass-fulldeps/macro-crate.rs
+++ b/src/test/run-pass-fulldeps/macro-crate.rs
@@ -19,8 +19,8 @@
 #[macro_use] #[no_link]
 extern crate macro_crate_test;
 
-#[derive(PartialEq, Clone, Debug)]
 #[rustc_into_multi_foo]
+#[derive(PartialEq, Clone, Debug)]
 fn foo() -> AnotherFakeTypeThatHadBetterGoAway {}
 
 // Check that the `#[into_multi_foo]`-generated `foo2` is configured away
diff --git a/src/test/ui-fulldeps/attribute-order-restricted.rs b/src/test/ui-fulldeps/attribute-order-restricted.rs
index 553cd86e620..7b1eecd1558 100644
--- a/src/test/ui-fulldeps/attribute-order-restricted.rs
+++ b/src/test/ui-fulldeps/attribute-order-restricted.rs
@@ -1,9 +1,5 @@
 // aux-build:attr_proc_macro.rs
-// compile-flags:--test
 
-#![feature(test)]
-
-extern crate test;
 extern crate attr_proc_macro;
 use attr_proc_macro::*;
 
@@ -15,18 +11,4 @@ struct Before;
 #[attr_proc_macro] //~ ERROR macro attributes must be placed before `#[derive]`
 struct After;
 
-#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-#[test]
-fn test_before() {}
-
-#[test]
-#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-fn test_after() {}
-
-#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-#[bench]
-fn bench_before(b: &mut test::Bencher) {}
-
-#[bench]
-#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-fn bench_after(b: &mut test::Bencher) {}
+fn main() {}
diff --git a/src/test/ui-fulldeps/attribute-order-restricted.stderr b/src/test/ui-fulldeps/attribute-order-restricted.stderr
index 841fc630b22..a4f165cd1b5 100644
--- a/src/test/ui-fulldeps/attribute-order-restricted.stderr
+++ b/src/test/ui-fulldeps/attribute-order-restricted.stderr
@@ -1,32 +1,8 @@
 error: macro attributes must be placed before `#[derive]`
-  --> $DIR/attribute-order-restricted.rs:15:1
+  --> $DIR/attribute-order-restricted.rs:11:1
    |
 LL | #[attr_proc_macro] //~ ERROR macro attributes must be placed before `#[derive]`
    | ^^^^^^^^^^^^^^^^^^
 
-error: macro attributes cannot be used together with `#[test]` or `#[bench]`
-  --> $DIR/attribute-order-restricted.rs:18:1
-   |
-LL | #[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-   | ^^^^^^^^^^^^^^^^^^
-
-error: macro attributes cannot be used together with `#[test]` or `#[bench]`
-  --> $DIR/attribute-order-restricted.rs:23:1
-   |
-LL | #[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-   | ^^^^^^^^^^^^^^^^^^
-
-error: macro attributes cannot be used together with `#[test]` or `#[bench]`
-  --> $DIR/attribute-order-restricted.rs:26:1
-   |
-LL | #[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-   | ^^^^^^^^^^^^^^^^^^
-
-error: macro attributes cannot be used together with `#[test]` or `#[bench]`
-  --> $DIR/attribute-order-restricted.rs:31:1
-   |
-LL | #[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
-   | ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 5 previous errors
+error: aborting due to previous error