Skip to content

Commit

Permalink
Process cfg_attr right before stripping cfg
Browse files Browse the repository at this point in the history
Fixes #22070.
Fixes #19372.
  • Loading branch information
Keegan McAllister committed Feb 9, 2015
1 parent 0110f5e commit 5354317
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 38 deletions.
49 changes: 48 additions & 1 deletion src/libsyntax/config.rs
Expand Up @@ -12,7 +12,7 @@ use attr::AttrMetaMethods;
use diagnostic::SpanHandler;
use fold::Folder;
use {ast, fold, attr};
use codemap::Spanned;
use codemap::{Spanned, respan};
use ptr::P;

use util::small_vector::SmallVector;
Expand All @@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
let krate = process_cfg_attr(diagnostic, krate);
let config = krate.config.clone();
strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs))
}
Expand Down Expand Up @@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
attr::cfg_matches(diagnostic, cfg, &*mis[0])
})
}

struct CfgAttrFolder<'a> {
diag: &'a SpanHandler,
config: ast::CrateConfig,
}

// Process `#[cfg_attr]`.
fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
let mut fld = CfgAttrFolder {
diag: diagnostic,
config: krate.config.clone(),
};
fld.fold_crate(krate)
}

impl<'a> fold::Folder for CfgAttrFolder<'a> {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
if !attr.check_name("cfg_attr") {
return fold::noop_fold_attribute(attr, self);
}

let (cfg, mi) = match attr.meta_item_list() {
Some([ref cfg, ref mi]) => (cfg, mi),
_ => {
self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
return None;
}
};

if attr::cfg_matches(self.diag, &self.config[], &cfg) {
Some(respan(mi.span, ast::Attribute_ {
id: attr::mk_attr_id(),
style: attr.node.style,
value: mi.clone(),
is_sugared_doc: false,
}))
} else {
None
}
}

// Need the ability to run pre-expansion.
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}
2 changes: 0 additions & 2 deletions src/libsyntax/ext/base.rs
Expand Up @@ -528,8 +528,6 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> 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));
Expand Down
34 changes: 0 additions & 34 deletions src/libsyntax/ext/cfg_attr.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/libsyntax/lib.rs
Expand Up @@ -96,7 +96,6 @@ pub mod ext {
pub mod base;
pub mod build;
pub mod cfg;
pub mod cfg_attr;
pub mod concat;
pub mod concat_idents;
pub mod deriving;
Expand Down
18 changes: 18 additions & 0 deletions src/test/compile-fail/cfg-attr-cfg-2.rs
@@ -0,0 +1,18 @@
// Copyright 2015 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.
//
// error-pattern: main function not found
// compile-flags: --cfg foo

// main is conditionally compiled, but the conditional compilation
// is conditional too!

#[cfg_attr(foo, cfg(bar))]
fn main() { }
17 changes: 17 additions & 0 deletions src/test/compile-fail/cfg-attr-crate-2.rs
@@ -0,0 +1,17 @@
// Copyright 2015 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 broken

// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044

#![cfg_attr(broken, no_std)] //~ ERROR no_std is experimental

fn main() { }
15 changes: 15 additions & 0 deletions src/test/run-pass/cfg-attr-cfg.rs
@@ -0,0 +1,15 @@
// Copyright 2015 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.

// main is conditionally compiled, but the conditional compilation
// is conditional too!

#[cfg_attr(foo, cfg(bar))]
fn main() { }
15 changes: 15 additions & 0 deletions src/test/run-pass/cfg-attr-crate.rs
@@ -0,0 +1,15 @@
// Copyright 2015 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.

// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044

#![cfg_attr(not_used, no_std)]

fn main() { }

0 comments on commit 5354317

Please sign in to comment.