diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 03f3fa9fcf6b..2eb44ba6815e 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -208,11 +208,11 @@ actual:\n\ testfile: &Path, src: ~str) -> ProcRes { compose_and_run_compiler( config, props, testfile, - make_typecheck_args(config, testfile), + make_typecheck_args(config, props, testfile), Some(src)) } - fn make_typecheck_args(config: config, testfile: &Path) -> ProcArgs { + fn make_typecheck_args(config: config, props: TestProps, testfile: &Path) -> ProcArgs { let prog = config.rustc_path; let mut args = ~[~"-", ~"--no-trans", ~"--lib", @@ -220,6 +220,7 @@ actual:\n\ ~"-L", aux_output_dir_name(config, testfile).to_str()]; args += split_maybe_args(config.rustcflags); + args += split_maybe_args(props.compile_flags); return ProcArgs {prog: prog.to_str(), args: args}; } } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index bb0080ba5357..39a1fda2c929 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -185,18 +185,19 @@ pub fn metas_in_cfg(cfg: ast::crate_cfg, // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // so we can match against them. This is the list of configurations for // which the item is valid - let cfg_metas = - vec::concat( - vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i))); - - let has_cfg_metas = vec::len(cfg_metas) > 0u; - if !has_cfg_metas { return true; } - - for cfg_metas.each |cfg_mi| { - if attr::contains(cfg, *cfg_mi) { return true; } - } - - return false; + let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i)); + + if cfg_metas.all(|c| c.is_empty()) { return true; } + + cfg_metas.any(|cfg_meta| { + cfg_meta.all(|cfg_mi| { + match cfg_mi.node { + ast::meta_list(s, ref it) if *s == ~"not" + => it.all(|mi| !attr::contains(cfg, *mi)), + _ => attr::contains(cfg, *cfg_mi) + } + }) + }) } diff --git a/src/test/compile-fail/test-cfg.rs b/src/test/compile-fail/test-cfg.rs new file mode 100644 index 000000000000..a090dd9de5d1 --- /dev/null +++ b/src/test/compile-fail/test-cfg.rs @@ -0,0 +1,18 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --cfg foo + +#[cfg(foo, bar)] // foo AND bar +fn foo() {} + +fn main() { + foo(); //~ ERROR unresolved name: `foo`. +} diff --git a/src/test/run-pass/cfgs-on-items.rs b/src/test/run-pass/cfgs-on-items.rs new file mode 100644 index 000000000000..47aa683ecd22 --- /dev/null +++ b/src/test/run-pass/cfgs-on-items.rs @@ -0,0 +1,31 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// compile-flags: --cfg fooA --cfg fooB + +// fooA AND !bar +#[cfg(fooA, not(bar))] +fn foo1() -> int { 1 } + +// !fooA AND !bar +#[cfg(not(fooA, bar))] +fn foo2() -> int { 2 } + +// fooC OR (fooB AND !bar) +#[cfg(fooC)] +#[cfg(fooB, not(bar))] +fn foo2() -> int { 3 } + + +fn main() { + fail_unless!(1 == foo1()); + fail_unless!(3 == foo2()); +}