Skip to content

Continue cfg syntax transition #17963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,10 +952,10 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
to_lower(line).as_slice().starts_with(to_lower(prefix).as_slice())
}

#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "dragonfly")]
#[cfg(any(target_os = "linux",
target_os = "macos",
target_os = "freebsd",
target_os = "dragonfly"))]
fn prefix_matches( line : &str, prefix : &str ) -> bool {
line.starts_with( prefix )
}
Expand Down Expand Up @@ -1356,10 +1356,10 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
}

// Linux and mac don't require adjusting the library search path
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "dragonfly")]
#[cfg(any(target_os = "linux",
target_os = "macos",
target_os = "freebsd",
target_os = "dragonfly"))]
fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String {
format!("{} {}", prog, args.connect(" "))
}
Expand Down
2 changes: 1 addition & 1 deletion src/doc/guide-ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ conventions. Rust provides a way to tell the compiler which convention to use:
~~~~
extern crate libc;

#[cfg(target_os = "win32", target_arch = "x86")]
#[cfg(all(target_os = "win32", target_arch = "x86"))]
#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "stdcall" {
Expand Down
16 changes: 7 additions & 9 deletions src/doc/guide-unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,15 @@ literal string (i.e `""`)
```
#![feature(asm)]

#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn foo() {
unsafe {
asm!("NOP");
}
}

// other platforms
#[cfg(not(target_arch = "x86"),
not(target_arch = "x86_64"))]
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn foo() { /* ... */ }

fn main() {
Expand All @@ -340,7 +338,7 @@ but you must add the right number of `:` if you skip them:

```
# #![feature(asm)]
# #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
# fn main() { unsafe {
asm!("xor %eax, %eax"
:
Expand All @@ -354,7 +352,7 @@ Whitespace also doesn't matter:

```
# #![feature(asm)]
# #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
# fn main() { unsafe {
asm!("xor %eax, %eax" ::: "eax");
# } }
Expand All @@ -368,7 +366,7 @@ expressions must be mutable lvalues:

```
# #![feature(asm)]
# #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn add(a: int, b: int) -> int {
let mut c = 0;
unsafe {
Expand All @@ -379,7 +377,7 @@ fn add(a: int, b: int) -> int {
}
c
}
# #[cfg(not(target_arch = "x86"), not(target_arch = "x86_64"))]
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
# fn add(a: int, b: int) -> int { a + b }

fn main() {
Expand All @@ -396,7 +394,7 @@ stay valid.

```
# #![feature(asm)]
# #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
# fn main() { unsafe {
// Put the value 0x200 in eax
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
Expand Down
18 changes: 10 additions & 8 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2066,26 +2066,28 @@ fn macos_only() {
}

// This function is only included when either foo or bar is defined
#[cfg(foo)]
#[cfg(bar)]
#[cfg(any(foo, bar))]
fn needs_foo_or_bar() {
// ...
}

// This function is only included when compiling for a unixish OS with a 32-bit
// architecture
#[cfg(unix, target_word_size = "32")]
#[cfg(all(unix, target_word_size = "32"))]
fn on_32bit_unix() {
// ...
}

// This function is only included when foo is not defined
#[cfg(not(foo))]
fn needs_not_foo() {
// ...
}
```

This illustrates some conditional compilation can be achieved using the
`#[cfg(...)]` attribute. Note that `#[cfg(foo, bar)]` is a condition that needs
both `foo` and `bar` to be defined while `#[cfg(foo)] #[cfg(bar)]` only needs
one of `foo` and `bar` to be defined (this resembles in the disjunctive normal
form). Additionally, one can reverse a condition by enclosing it in a
`not(...)`, like e. g. `#[cfg(not(target_os = "win32"))]`.
`#[cfg(...)]` attribute. `any`, `all` and `not` can be used to assemble
arbitrarily complex configurations through nesting.

The following configurations must be defined by the implementation:

Expand Down
16 changes: 8 additions & 8 deletions src/libcoretest/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ fn size_of_basic() {
}

#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
#[cfg(any(target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
target_arch = "mipsel"))]
fn size_of_32() {
assert_eq!(size_of::<uint>(), 4u);
assert_eq!(size_of::<*const uint>(), 4u);
Expand Down Expand Up @@ -51,10 +51,10 @@ fn align_of_basic() {
}

#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
#[cfg(any(target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
target_arch = "mipsel"))]
fn align_of_32() {
assert_eq!(align_of::<uint>(), 4u);
assert_eq!(align_of::<*const uint>(), 4u);
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_back/rpath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ mod test {
}

#[test]
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(any(target_os = "linux", target_os = "android"))]
fn test_rpath_relative() {
let config = &mut RPathConfig {
os: abi::OsLinux,
Expand Down
57 changes: 3 additions & 54 deletions src/libsyntax/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,10 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::Me
mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
ast::MetaList(ref pred, ref mis) if pred.get() == "not" => {
if mis.len() != 1 {
diagnostic.span_warn(cfg.span, "the use of multiple cfgs in the same `not` \
statement is deprecated. Change `not(a, b)` to \
`not(all(a, b))`.");
diagnostic.span_err(cfg.span, "expected 1 cfg-pattern");
return false;
}
!mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi))
!cfg_matches(diagnostic, cfgs, &*mis[0])
}
ast::MetaList(ref pred, _) => {
diagnostic.span_err(cfg.span, format!("invalid predicate `{}`", pred).as_slice());
Expand All @@ -330,56 +329,6 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::Me
}
}

/// Tests if any `cfg(...)` meta items in `metas` match `cfg`. e.g.
///
/// test_cfg(`[foo="a", bar]`, `[cfg(foo), cfg(bar)]`) == true
/// test_cfg(`[foo="a", bar]`, `[cfg(not(bar))]`) == false
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false
pub fn test_cfg<'a, AM: AttrMetaMethods, It: Iterator<&'a AM>>
(cfg: &[P<MetaItem>], mut metas: It) -> bool {
// having no #[cfg(...)] attributes counts as matching.
let mut no_cfgs = true;

// this would be much nicer as a chain of iterator adaptors, but
// this doesn't work.
let some_cfg_matches = metas.fold(false, |matches, mi| {
debug!("testing name: {}", mi.name());
let this_matches = if mi.check_name("cfg") { // it is a #[cfg()] attribute
debug!("is cfg");
no_cfgs = false;
// only #[cfg(...)] ones are understood.
match mi.meta_item_list() {
Some(cfg_meta) => {
debug!("is cfg(...)");
cfg_meta.iter().all(|cfg_mi| {
debug!("cfg({}[...])", cfg_mi.name());
match cfg_mi.node {
ast::MetaList(ref s, ref not_cfgs)
if s.equiv(&("not")) => {
debug!("not!");
// inside #[cfg(not(...))], so these need to all
// not match.
!not_cfgs.iter().all(|mi| {
debug!("cfg(not({}[...]))", mi.name());
contains(cfg, &**mi)
})
}
_ => contains(cfg, &**cfg_mi)
}
})
}
None => false
}
} else {
false
};
matches || this_matches
});
debug!("test_cfg (no_cfgs={}, some_cfg_matches={})", no_cfgs, some_cfg_matches);
no_cfgs || some_cfg_matches
}

/// Represents the #[deprecated="foo"] and friends attributes.
#[deriving(Encodable,Decodable,Clone,Show)]
pub struct Stability {
Expand Down
16 changes: 8 additions & 8 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,20 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
};

if mis.len() != 1 {
diagnostic.span_warn(attr.span, "The use of multiple cfgs in the top level of \
`#[cfg(..)]` is deprecated. Change `#[cfg(a, b)]` to \
`#[cfg(all(a, b))]`.");
diagnostic.span_err(attr.span, "expected 1 cfg-pattern");
return false;
}

if seen_cfg {
diagnostic.span_warn(attr.span, "The semantics of multiple `#[cfg(..)]` attributes on \
same item are changing from the union of the cfgs to \
the intersection of the cfgs. Change `#[cfg(a)] \
#[cfg(b)]` to `#[cfg(any(a, b))]`.");
diagnostic.span_err(attr.span, "The semantics of multiple `#[cfg(..)]` attributes on \
same item are changing from the union of the cfgs to \
the intersection of the cfgs. Change `#[cfg(a)] \
#[cfg(b)]` to `#[cfg(any(a, b))]`.");
return false;
}

seen_cfg = true;
in_cfg |= mis.iter().all(|mi| attr::cfg_matches(diagnostic, cfg, &**mi));
in_cfg |= attr::cfg_matches(diagnostic, cfg, &*mis[0]);
}
in_cfg | !seen_cfg
}
Expand Down
28 changes: 8 additions & 20 deletions src/libsyntax/ext/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/**
The compiler code necessary to support the cfg! extension, which
expands to a literal `true` or `false` based on whether the given cfgs
match the current compilation environment.
*/
/// The compiler code necessary to support the cfg! extension, which expands to
/// a literal `true` or `false` based on whether the given cfg matches the
/// current compilation environment.

use ast;
use codemap::Span;
Expand All @@ -24,28 +22,18 @@ use attr::*;
use parse::attr::ParserAttr;
use parse::token;


pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
sp: Span,
tts: &[ast::TokenTree])
-> Box<base::MacResult+'static> {
let mut p = cx.new_parser_from_tts(tts);
let mut cfgs = Vec::new();
// parse `cfg!(meta_item, meta_item(x,y), meta_item="foo", ...)`
while p.token != token::EOF {
cfgs.push(p.parse_meta_item());
if p.eat(&token::EOF) { break } // trailing comma is optional,.
p.expect(&token::COMMA);
}
let cfg = p.parse_meta_item();

if cfgs.len() != 1 {
cx.span_warn(sp, "The use of multiple cfgs at the top level of `cfg!` \
is deprecated. Change `cfg!(a, b)` to \
`cfg!(all(a, b))`.");
if !p.eat(&token::EOF) {
cx.span_err(sp, "expected 1 cfg-pattern");
return DummyResult::expr(sp);
}

let matches_cfg = cfgs.iter().all(|cfg| attr::cfg_matches(&cx.parse_sess.span_diagnostic,
cx.cfg.as_slice(), &**cfg));

let matches_cfg = attr::cfg_matches(&cx.parse_sess.span_diagnostic, cx.cfg.as_slice(), &*cfg);
MacExpr::new(cx.expr_bool(sp, matches_cfg))
}
20 changes: 3 additions & 17 deletions src/libsyntax/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
span: i.span,
path: self.cx.path.clone(),
bench: is_bench_fn(&self.cx, &*i),
ignore: is_ignored(&self.cx, &*i),
ignore: is_ignored(&*i),
should_fail: should_fail(&*i)
};
self.cx.testfns.push(test);
Expand Down Expand Up @@ -343,22 +343,8 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
return has_bench_attr && has_test_signature(i);
}

fn is_ignored(cx: &TestCtxt, i: &ast::Item) -> bool {
i.attrs.iter().any(|attr| {
// 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
}
})
fn is_ignored(i: &ast::Item) -> bool {
i.attrs.iter().any(|attr| attr.check_name("ignore"))
}

fn should_fail(i: &ast::Item) -> bool {
Expand Down
3 changes: 1 addition & 2 deletions src/test/auxiliary/extern_calling_convention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ pub extern "win64" fn foo(a: int, b: int, c: int, d: int) {
}

#[inline(never)]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(any(target_arch = "x86", target_arch = "arm"))]
pub extern fn foo(a: int, b: int, c: int, d: int) {
assert!(a == 1);
assert!(b == 2);
Expand Down
4 changes: 2 additions & 2 deletions src/test/run-make/test-harness/test-ignore-cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
// except according to those terms.

#[test]
#[ignore(cfg(ignorecfg))]
#[cfg_attr(ignorecfg, ignore)]
fn shouldignore() {
}

#[test]
#[ignore(cfg(noignorecfg))]
#[cfg_attr(noignorecfg, ignore)]
fn shouldnotignore() {
}
Loading