about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-09-27 01:37:53 +0000
committerbors <bors@rust-lang.org>2014-09-27 01:37:53 +0000
commit43d7d7c15e964c1cb506cbce90bb4b32b57281b8 (patch)
treece3d1c405d06461fb8de8ba58b7f62440be5d199
parentd64b4103d688f38c2e9e2daf966d50beeb383f1e (diff)
parentdcdbdc10036b444ef39c329e9440d4acc6975fda (diff)
downloadrust-43d7d7c15e964c1cb506cbce90bb4b32b57281b8.tar.gz
rust-43d7d7c15e964c1cb506cbce90bb4b32b57281b8.zip
auto merge of #17506 : sfackler/rust/cfg-attr, r=alexcrichton
cc #17490 

Reopening of #16230
-rw-r--r--src/doc/guide-testing.md4
-rw-r--r--src/libnative/io/file_unix.rs2
-rw-r--r--src/libnum/complex.rs2
-rw-r--r--src/librustuv/net.rs2
-rw-r--r--src/libserialize/json.rs6
-rw-r--r--src/libstd/dynamic_lib.rs3
-rw-r--r--src/libstd/io/net/pipe.rs2
-rw-r--r--src/libstd/io/net/tcp.rs2
-rw-r--r--src/libstd/io/net/udp.rs2
-rw-r--r--src/libstd/num/f32.rs2
-rw-r--r--src/libstd/num/f64.rs2
-rw-r--r--src/libsync/deque.rs2
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/cfg_attr.rs57
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/test.rs6
-rw-r--r--src/libtest/lib.rs3
-rw-r--r--src/libtime/lib.rs2
-rw-r--r--src/test/run-pass/cfg_attr.rs59
-rw-r--r--src/test/run-pass/tcp-connect-timeouts.rs2
20 files changed, 143 insertions, 20 deletions
diff --git a/src/doc/guide-testing.md b/src/doc/guide-testing.md
index 6fb198fbd2b..07813855d9b 100644
--- a/src/doc/guide-testing.md
+++ b/src/doc/guide-testing.md
@@ -72,8 +72,8 @@ is not used.
 Tests that should not be run can be annotated with the `ignore`
 attribute. The existence of these tests will be noted in the test
 runner output, but the test will not be run. Tests can also be ignored
-by configuration so, for example, to ignore a test on windows you can
-write `#[ignore(cfg(target_os = "win32"))]`.
+by configuration using the `cfg_attr` attribute so, for example, to ignore a
+test on windows you can write `#[cfg_attr(windows, ignore)]`.
 
 Tests that are intended to fail can be annotated with the
 `should_fail` attribute. The test will be run, and if it causes its
diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs
index 90fbc7729d4..1688b009ad7 100644
--- a/src/libnative/io/file_unix.rs
+++ b/src/libnative/io/file_unix.rs
@@ -506,7 +506,7 @@ mod tests {
     use std::os;
     use std::rt::rtio::{RtioFileStream, SeekSet};
 
-    #[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
+    #[cfg_attr(target_os = "freebsd", ignore)] // hmm, maybe pipes have a tiny buffer
     #[test]
     fn test_file_desc() {
         // Run this test with some pipes so we don't have to mess around with
diff --git a/src/libnum/complex.rs b/src/libnum/complex.rs
index 24c99a38bd9..0e70527cdca 100644
--- a/src/libnum/complex.rs
+++ b/src/libnum/complex.rs
@@ -219,7 +219,7 @@ mod test {
     }
 
     #[test]
-    #[ignore(cfg(target_arch = "x86"))]
+    #[cfg_attr(target_arch = "x86", ignore)]
     // FIXME #7158: (maybe?) currently failing on x86.
     fn test_norm() {
         fn test(c: Complex64, ns: f64) {
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index d572d8ce58a..3531d162db0 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -1085,7 +1085,7 @@ mod test {
     }
 
     #[test]
-    #[ignore(cfg(windows))] // FIXME(#10102) server never sees second packet
+    #[cfg_attr(windows, ignore)] // FIXME(#10102) server never sees second packet
     fn test_udp_twice() {
         let server_addr = ::next_test_ip4();
         let client_addr = ::next_test_ip4();
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 4d9bb87d133..b936dde6fe4 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -3352,7 +3352,7 @@ mod tests {
         }
     }
     #[test]
-    #[ignore(cfg(target_word_size = "32"))] // FIXME(#14064)
+    #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064)
     fn test_streaming_parser() {
         assert_stream_equal(
             r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#,
@@ -3388,7 +3388,7 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(target_word_size = "32"))] // FIXME(#14064)
+    #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064)
     fn test_read_object_streaming() {
         assert_eq!(last_event("{ "),      Error(SyntaxError(EOFWhileParsingObject, 1, 3)));
         assert_eq!(last_event("{1"),      Error(SyntaxError(KeyMustBeAString,      1, 2)));
@@ -3461,7 +3461,7 @@ mod tests {
         );
     }
     #[test]
-    #[ignore(cfg(target_word_size = "32"))] // FIXME(#14064)
+    #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064)
     fn test_read_list_streaming() {
         assert_stream_equal(
             "[]",
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index e8d570f30e6..a88448f47e0 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -162,8 +162,7 @@ mod test {
     use mem;
 
     #[test]
-    #[ignore(cfg(windows))] // FIXME #8818
-    #[ignore(cfg(target_os="android"))] // FIXME(#10379)
+    #[cfg_attr(any(windows, target_os = "android"), ignore)] // FIXME #8818, #10379
     fn test_loading_cosine() {
         // The math library does not need to be loaded since it is already
         // statically linked in
diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs
index 35d97df0c37..a7ce18c40ef 100644
--- a/src/libstd/io/net/pipe.rs
+++ b/src/libstd/io/net/pipe.rs
@@ -320,7 +320,7 @@ mod tests {
         }, proc(_client) {
             // drop the client
         })
-    } #[ignore(cfg(windows))]) // FIXME(#12516)
+    } #[cfg_attr(windows, ignore)]) // FIXME(#12516)
 
     iotest!(fn write_begone() {
         smalltest(proc(mut server) {
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index d787f0e9854..65d8f1c9c77 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -533,7 +533,7 @@ mod test {
             Ok(..) => fail!(),
             Err(e) => assert_eq!(e.kind, PermissionDenied),
         }
-    } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
+    } #[cfg_attr(any(windows, target_os = "android"), ignore)])
 
     iotest!(fn connect_error() {
         match TcpStream::connect("0.0.0.0", 1) {
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 840fcff95f1..ab61d2a4d91 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -273,7 +273,7 @@ mod test {
             Ok(..) => fail!(),
             Err(e) => assert_eq!(e.kind, PermissionDenied),
         }
-    } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
+    } #[cfg_attr(any(windows, target_os = "android"), ignore)])
 
     iotest!(fn socket_smoke_test_ip4() {
         let server_ip = next_test_ip4();
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index d91f5579c0d..b2a9f1b7b20 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -766,7 +766,7 @@ mod tests {
         assert_eq!((-0f32).frexp(), (-0f32, 0));
     }
 
-    #[test] #[ignore(cfg(windows))] // FIXME #8755
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
     fn test_frexp_nowin() {
         let inf: f32 = Float::infinity();
         let neg_inf: f32 = Float::neg_infinity();
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index d8d118a6721..6fe9fcad2aa 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -768,7 +768,7 @@ mod tests {
         assert_eq!((-0f64).frexp(), (-0f64, 0));
     }
 
-    #[test] #[ignore(cfg(windows))] // FIXME #8755
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
     fn test_frexp_nowin() {
         let inf: f64 = Float::infinity();
         let neg_inf: f64 = Float::neg_infinity();
diff --git a/src/libsync/deque.rs b/src/libsync/deque.rs
index 6204b54fba4..15c0c14b28a 100644
--- a/src/libsync/deque.rs
+++ b/src/libsync/deque.rs
@@ -600,7 +600,7 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))] // apparently windows scheduling is weird?
+    #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird?
     fn no_starvation() {
         static AMT: int = 10000;
         static NTHREADS: int = 4;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b35a9456757..8bf13e20fed 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -439,6 +439,8 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
     syntax_expanders.insert(intern("cfg"),
                             builtin_normal_expander(
                                     ext::cfg::expand_cfg));
+    syntax_expanders.insert(intern("cfg_attr"),
+                            Modifier(box ext::cfg_attr::expand));
     syntax_expanders.insert(intern("trace_macros"),
                             builtin_normal_expander(
                                     ext::trace_macros::expand_trace_macros));
diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs
new file mode 100644
index 00000000000..ad02b50f248
--- /dev/null
+++ b/src/libsyntax/ext/cfg_attr.rs
@@ -0,0 +1,57 @@
+// Copyright 2014 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.
+
+use ast;
+use attr;
+use codemap::Span;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
+use ptr::P;
+
+pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> {
+    let (cfg, attr) = match mi.node {
+        ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]),
+        _ => {
+            cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
+            return it;
+        }
+    };
+
+    let mut out = (*it).clone();
+    if cfg_matches(cx, &**cfg) {
+        out.attrs.push(cx.attribute(attr.span, attr.clone()));
+    }
+
+    P(out)
+}
+
+fn cfg_matches(cx: &mut ExtCtxt, cfg: &ast::MetaItem) -> bool {
+    match cfg.node {
+        ast::MetaList(ref pred, ref mis) if pred.get() == "any" =>
+            mis.iter().any(|mi| cfg_matches(cx, &**mi)),
+        ast::MetaList(ref pred, ref mis) if pred.get() == "all" =>
+            mis.iter().all(|mi| cfg_matches(cx, &**mi)),
+        ast::MetaList(ref pred, ref mis) if pred.get() == "not" => {
+            if mis.len() != 1 {
+                cx.span_err(cfg.span, format!("expected 1 value, got {}",
+                                              mis.len()).as_slice());
+                return false;
+            }
+            !cfg_matches(cx, &*mis[0])
+        }
+        ast::MetaList(ref pred, _) => {
+            cx.span_err(cfg.span,
+                        format!("invalid predicate `{}`", pred).as_slice());
+            false
+        },
+        ast::MetaWord(_) | ast::MetaNameValue(..) =>
+            attr::contains(cx.cfg.as_slice(), cfg),
+    }
+}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 153b3cc90d6..7a504d22c1e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -83,6 +83,7 @@ pub mod ext {
     pub mod build;
     pub mod bytes;
     pub mod cfg;
+    pub mod cfg_attr;
     pub mod concat;
     pub mod concat_idents;
     pub mod deriving;
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index f0e69712714..091b0ce8ed9 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -339,6 +339,12 @@ fn is_ignored(cx: &TestCtxt, i: &ast::Item) -> bool {
         // check ignore(cfg(foo, bar))
         attr.check_name("ignore") && match attr.meta_item_list() {
             Some(ref cfgs) => {
+                if cfgs.iter().any(|cfg| cfg.check_name("cfg")) {
+                    cx.span_diagnostic.span_warn(attr.span,
+                            "The use of cfg filters in #[ignore] is \
+                             deprecated. Use #[cfg_attr(<cfg pattern>, \
+                             ignore)] instead.");
+                }
                 attr::test_cfg(cx.config.as_slice(), cfgs.iter())
             }
             None => true
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 43a1899f45e..04489d78027 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -356,8 +356,7 @@ Test Attributes:
     #[ignore]      - When applied to a function which is already attributed as a
                      test, then the test runner will ignore these tests during
                      normal test runs. Running with --ignored will run these
-                     tests. This may also be written as #[ignore(cfg(...))] to
-                     ignore the test on certain configurations.",
+                     tests.",
              usage = getopts::usage(message.as_slice(),
                                     optgroups().as_slice()));
 }
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index abf6fc5f255..9cec71104d4 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -1564,7 +1564,7 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(target_os = "android"))] // FIXME #10958
+    #[cfg_attr(target_os = "android", ignore)] // FIXME #10958
     fn run_tests() {
         // The tests race on tzset. So instead of having many independent
         // tests, we will just call the functions now.
diff --git a/src/test/run-pass/cfg_attr.rs b/src/test/run-pass/cfg_attr.rs
new file mode 100644
index 00000000000..15d3f4a04d5
--- /dev/null
+++ b/src/test/run-pass/cfg_attr.rs
@@ -0,0 +1,59 @@
+// Copyright 2014 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.
+
+// compile-flags:--cfg set1 --cfg set2
+#![allow(dead_code)]
+use std::fmt::Show;
+
+struct NotShowable;
+
+#[cfg_attr(set1, deriving(Show))]
+struct Set1;
+
+#[cfg_attr(notset, deriving(Show))]
+struct Notset(NotShowable);
+
+#[cfg_attr(not(notset), deriving(Show))]
+struct NotNotset;
+
+#[cfg_attr(not(set1), deriving(Show))]
+struct NotSet1(NotShowable);
+
+#[cfg_attr(all(set1, set2), deriving(Show))]
+struct AllSet1Set2;
+
+#[cfg_attr(all(set1, notset), deriving(Show))]
+struct AllSet1Notset(NotShowable);
+
+#[cfg_attr(any(set1, notset), deriving(Show))]
+struct AnySet1Notset;
+
+#[cfg_attr(any(notset, notset2), deriving(Show))]
+struct AnyNotsetNotset2(NotShowable);
+
+#[cfg_attr(all(not(notset), any(set1, notset)), deriving(Show))]
+struct Complex;
+
+#[cfg_attr(any(notset, not(any(set1, notset))), deriving(Show))]
+struct ComplexNot(NotShowable);
+
+#[cfg_attr(any(target_endian = "little", target_endian = "big"), deriving(Show))]
+struct KeyValue;
+
+fn is_show<T: Show>() {}
+
+fn main() {
+    is_show::<Set1>();
+    is_show::<NotNotset>();
+    is_show::<AllSet1Set2>();
+    is_show::<AnySet1Notset>();
+    is_show::<Complex>();
+    is_show::<KeyValue>();
+}
diff --git a/src/test/run-pass/tcp-connect-timeouts.rs b/src/test/run-pass/tcp-connect-timeouts.rs
index c1d93033ab6..00906004dbf 100644
--- a/src/test/run-pass/tcp-connect-timeouts.rs
+++ b/src/test/run-pass/tcp-connect-timeouts.rs
@@ -80,7 +80,7 @@ iotest!(fn eventual_timeout() {
         }
     }
     fail!("never timed out!");
-} #[ignore(cfg(target_os = "freebsd"))])
+} #[cfg_attr(target_os = "freebsd", ignore)])
 
 iotest!(fn timeout_success() {
     let addr = next_test_ip4();