]> git.lizzy.rs Git - rust.git/commitdiff
cfg_attr_multi: Feature gate
authorHavvy (Ryan Scheel) <ryan.havvy@gmail.com>
Thu, 4 Oct 2018 11:55:47 +0000 (04:55 -0700)
committerHavvy (Ryan Scheel) <ryan.havvy@gmail.com>
Sun, 7 Oct 2018 09:08:24 +0000 (02:08 -0700)
16 files changed:
src/doc/unstable-book/src/language-features/cfg-attr-multi.md [new file with mode: 0644]
src/libsyntax/config.rs
src/libsyntax/feature_gate.rs
src/test/ui/conditional-compilation/cfg-attr-multi-false.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs [new file with mode: 0644]

diff --git a/src/doc/unstable-book/src/language-features/cfg-attr-multi.md b/src/doc/unstable-book/src/language-features/cfg-attr-multi.md
new file mode 100644 (file)
index 0000000..759a28c
--- /dev/null
@@ -0,0 +1,20 @@
+# `cfg_attr_multi`
+
+The tracking issue for this feature is: [#555666]
+The RFC for this feature is: [#2539]
+
+[#555666]: https://github.com/rust-lang/rust/issues/555666
+[#2539]: https://github.com/rust-lang/rfcs/pull/2539
+
+------------------------
+
+This feature flag lets you put multiple attributes into a `cfg_attr` attribute.
+
+Example:
+
+```rust,ignore
+#[cfg_attr(all(), must_use, optimize)]
+```
+
+Because `cfg_attr` resolves before procedural macros, this does not affect
+macro resolution at all.
\ No newline at end of file
index 7a85f6285364101840865d58ab015f7ecfc7888c..e611eb86dc1b3214eb5637d5acb685f4a33881e2 100644 (file)
@@ -9,7 +9,14 @@
 // except according to those terms.
 
 use attr::HasAttrs;
-use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue};
+use feature_gate::{
+    feature_err,
+    EXPLAIN_STMT_ATTR_SYNTAX,
+    Features,
+    get_features,
+    GateIssue,
+    emit_feature_err,
+};
 use {fold, attr};
 use ast;
 use source_map::Spanned;
@@ -97,6 +104,13 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
             return vec![attr];
         }
 
+        let gate_cfg_attr_multi = if let Some(ref features) = self.features {
+            !features.cfg_attr_multi
+        } else {
+            false
+        };
+        let cfg_attr_span = attr.span;
+
         let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
             parser.expect(&token::OpenDelim(token::Paren))?;
 
@@ -123,6 +137,26 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
             }
         };
 
+        // Check feature gate and lint on zero attributes in source. Even if the feature is gated,
+        // we still compute as if it wasn't, since the emitted error will stop compilation futher
+        // along the compilation.
+        match (expanded_attrs.len(), gate_cfg_attr_multi) {
+            (0, false) => {
+                // FIXME: Emit unused attribute lint here.
+            },
+            (1, _) => {},
+            (_, true) => {
+                emit_feature_err(
+                    self.sess,
+                    "cfg_attr_multi",
+                    cfg_attr_span,
+                    GateIssue::Language,
+                    "cfg_attr with zero or more than one attributes is experimental",
+                );
+            },
+            (_, false) => {}
+        }
+
         if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
             // We call `process_cfg_attr` recursively in case there's a
             // `cfg_attr` inside of another `cfg_attr`. E.g.
index adbe2f9d4393f52f1f6ef426b56a778b6f8d0fbd..7707bbaa8b0e073deaa8cd8c5f0faf4cf5c575e5 100644 (file)
@@ -515,6 +515,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // Allows `impl Trait` in bindings (`let`, `const`, `static`)
     (active, impl_trait_in_bindings, "1.30.0", Some(34511), None),
+
+    // #[cfg_attr(predicate, multiple, attributes, here)]
+    (active, cfg_attr_multi, "1.31.0", Some(555666), None),
 );
 
 declare_features! (
index ff7a47e0839401e8eaf742763db21a47beb48ad3..84bd33fc0e7d3ce5541f4252bd64328891a18137 100644 (file)
@@ -4,6 +4,7 @@
 // compile-pass
 
 #![warn(unused_must_use)]
+#![feature(cfg_attr_multi)]
 
 #[cfg_attr(any(), deprecated, must_use)]
 struct Struct {}
index a9ddbf7d80d3eb07d49d0c2e4858f2f9f6a62ebf..d4c3186a6ebbb6dc544dfffe21059f548d1ce7b4 100644 (file)
@@ -10,6 +10,7 @@
 //
 // compile-flags: --cfg broken
 
+#![feature(cfg_attr_multi)]
 #![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
 
 fn main() { }
index 344a05a4fecbb1bffe983a8241ac59c87198f98a..bf68d92cc0bbd410d69c5f03f96c35bbc31281f7 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: no_core is experimental (see issue #29639)
-  --> $DIR/cfg-attr-multi-invalid-1.rs:13:21
+  --> $DIR/cfg-attr-multi-invalid-1.rs:14:21
    |
 LL | #![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
    |                     ^^^^^^^
index 211eb08f08e288e7fe77c6991b9976a286855ea0..bee6b7d4886bd110eba2d42a62fefd25fb5c5905 100644 (file)
@@ -10,6 +10,7 @@
 //
 // compile-flags: --cfg broken
 
+#![feature(cfg_attr_multi)]
 #![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
 
 fn main() { }
index 54854d2e29d53c696bdad7097cbc442846b163d8..5c72a400e0bae031d8f85fa2bcc8137db9d96d82 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: no_core is experimental (see issue #29639)
-  --> $DIR/cfg-attr-multi-invalid-2.rs:13:29
+  --> $DIR/cfg-attr-multi-invalid-2.rs:14:29
    |
 LL | #![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
    |                             ^^^^^^^
index 4b9a8d46b9b1f722220ebf12d831ccbbe2933826..a31dde00c7cf5f6d33eed4151b5c56ddb68d5c65 100644 (file)
@@ -5,6 +5,7 @@
 // compile-pass
 
 #![warn(unused_must_use)]
+#![feature(cfg_attr_multi)]
 
 #[cfg_attr(all(), deprecated, must_use)]
 struct MustUseDeprecated {}
index 21634ee4f26b80b2840b7a850d2f89c61e0fa8f8..37cb3de06c04f75288847cdaa974c65096d95419 100644 (file)
@@ -1,5 +1,5 @@
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:12:6
+  --> $DIR/cfg-attr-multi-true.rs:13:6
    |
 LL | impl MustUseDeprecated { //~ warning: use of deprecated item
    |      ^^^^^^^^^^^^^^^^^
@@ -7,25 +7,25 @@ LL | impl MustUseDeprecated { //~ warning: use of deprecated item
    = note: #[warn(deprecated)] on by default
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:19:5
+  --> $DIR/cfg-attr-multi-true.rs:20:5
    |
 LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:13:17
+  --> $DIR/cfg-attr-multi-true.rs:14:17
    |
 LL |     fn new() -> MustUseDeprecated { //~ warning: use of deprecated item
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:14:9
+  --> $DIR/cfg-attr-multi-true.rs:15:9
    |
 LL |         MustUseDeprecated {} //~ warning: use of deprecated item
    |         ^^^^^^^^^^^^^^^^^
 
 warning: unused `MustUseDeprecated` which must be used
-  --> $DIR/cfg-attr-multi-true.rs:19:5
+  --> $DIR/cfg-attr-multi-true.rs:20:5
    |
 LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs
new file mode 100644 (file)
index 0000000..9515380
--- /dev/null
@@ -0,0 +1,5 @@
+// gate-test-cfg_attr_multi
+
+#![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
+//~^ ERROR cfg_attr with zero or more than one attributes is experimental
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr
new file mode 100644 (file)
index 0000000..23c09c9
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #555666)
+  --> $DIR/feature-gate-cfg-attr-multi-1.rs:3:1
+   |
+LL | #![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(cfg_attr_multi)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs
new file mode 100644 (file)
index 0000000..cf02432
--- /dev/null
@@ -0,0 +1,3 @@
+#![cfg_attr(all(),)]
+//~^ ERROR cfg_attr with zero or more than one attributes is experimental
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr
new file mode 100644 (file)
index 0000000..d8f4acd
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #555666)
+  --> $DIR/feature-gate-cfg-attr-multi-2.rs:1:1
+   |
+LL | #![cfg_attr(all(),)]
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(cfg_attr_multi)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs
new file mode 100644 (file)
index 0000000..e473792
--- /dev/null
@@ -0,0 +1,7 @@
+// Test that settingt the featute gate while using its functionality doesn't error.
+
+// compile-pass
+
+#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs
new file mode 100644 (file)
index 0000000..df74054
--- /dev/null
@@ -0,0 +1,9 @@
+// Test that settingt the featute gate while using its functionality doesn't error.
+// Specifically, if there's a cfg-attr *before* the feature gate.
+
+// compile-pass
+
+#![cfg_attr(all(),)]
+#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
+
+fn main() {}