Skip to content

Commit 2816735

Browse files
committed
auto merge of #18634 : alexcrichton/rust/cfg-attr-crate-level, r=sfackler
This commit implements processing these two attributes at the crate level as well as at the item level. When #[cfg] is applied at the crate level, then the entire crate will be omitted if the cfg doesn't match. The #[cfg_attr] attribute is processed as usual in that the attribute is included or not depending on whether the cfg matches. This was spurred on by motivations of #18585 where #[cfg_attr] annotations will be applied at the crate-level. cc #18585
2 parents 0b48001 + dd9e355 commit 2816735

File tree

11 files changed

+126
-23
lines changed

11 files changed

+126
-23
lines changed

src/librustc/driver/driver.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
212212
*ty == config::CrateTypeExecutable
213213
});
214214

215-
krate = time(time_passes, "crate injection", krate, |krate|
216-
syntax::std_inject::maybe_inject_crates_ref(krate,
217-
sess.opts.alt_std_name.clone(),
218-
any_exe));
219-
220215
// strip before expansion to allow macros to depend on
221216
// configuration variables e.g/ in
222217
//
@@ -228,6 +223,11 @@ pub fn phase_2_configure_and_expand(sess: &Session,
228223
krate = time(time_passes, "configuration 1", krate, |krate|
229224
syntax::config::strip_unconfigured_items(sess.diagnostic(), krate));
230225

226+
krate = time(time_passes, "crate injection", krate, |krate|
227+
syntax::std_inject::maybe_inject_crates_ref(krate,
228+
sess.opts.alt_std_name.clone(),
229+
any_exe));
230+
231231
let mut addl_plugins = Some(addl_plugins);
232232
let Plugins { macros, registrars }
233233
= time(time_passes, "plugin loading", (), |_|

src/libsyntax/config.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use {ast, fold, attr};
1515
use codemap::Spanned;
1616
use ptr::P;
1717

18+
use util::small_vector::SmallVector;
19+
1820
/// A folder that strips out items that do not belong in the current
1921
/// configuration.
2022
struct Context<'a> {
@@ -47,6 +49,9 @@ impl<'a> fold::Folder for Context<'a> {
4749
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
4850
fold::noop_fold_mac(mac, self)
4951
}
52+
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
53+
fold_item(self, item)
54+
}
5055
}
5156

5257
pub fn strip_items(krate: ast::Crate,
@@ -72,13 +77,9 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) ->
7277
view_items: view_items.into_iter().filter_map(|a| {
7378
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
7479
}).collect(),
75-
items: items.into_iter().filter_map(|a| {
76-
if item_in_cfg(cx, &*a) {
77-
Some(cx.fold_item(a))
78-
} else {
79-
None
80-
}
81-
}).flat_map(|x| x.into_iter()).collect()
80+
items: items.into_iter().flat_map(|a| {
81+
cx.fold_item(a).into_iter()
82+
}).collect()
8283
}
8384
}
8485

@@ -104,6 +105,14 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}:
104105
}
105106
}
106107

108+
fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
109+
if item_in_cfg(cx, &*item) {
110+
SmallVector::one(item.map(|i| cx.fold_item_simple(i)))
111+
} else {
112+
SmallVector::zero()
113+
}
114+
}
115+
107116
fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
108117
let item = match item {
109118
ast::ItemImpl(a, b, c, impl_items) => {

src/libsyntax/fold.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -1061,12 +1061,41 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mu
10611061

10621062
pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, exported_macros, span}: Crate,
10631063
folder: &mut T) -> Crate {
1064+
let config = folder.fold_meta_items(config);
1065+
1066+
let mut items = folder.fold_item(P(ast::Item {
1067+
ident: token::special_idents::invalid,
1068+
attrs: attrs,
1069+
id: ast::DUMMY_NODE_ID,
1070+
vis: ast::Public,
1071+
span: span,
1072+
node: ast::ItemMod(module),
1073+
})).into_iter();
1074+
1075+
let (module, attrs, span) = match items.next() {
1076+
Some(item) => {
1077+
assert!(items.next().is_none(),
1078+
"a crate cannot expand to more than one item");
1079+
item.and_then(|ast::Item { attrs, span, node, .. }| {
1080+
match node {
1081+
ast::ItemMod(m) => (m, attrs, span),
1082+
_ => panic!("fold converted a module to not a module"),
1083+
}
1084+
})
1085+
}
1086+
None => (ast::Mod {
1087+
inner: span,
1088+
view_items: Vec::new(),
1089+
items: Vec::new(),
1090+
}, Vec::new(), span)
1091+
};
1092+
10641093
Crate {
1065-
module: folder.fold_mod(module),
1066-
attrs: attrs.move_map(|x| folder.fold_attribute(x)),
1067-
config: folder.fold_meta_items(config),
1094+
module: module,
1095+
attrs: attrs,
1096+
config: config,
10681097
exported_macros: exported_macros,
1069-
span: folder.new_span(span)
1098+
span: span,
10701099
}
10711100
}
10721101

src/libsyntax/test.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
108108
}
109109

110110
fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
111-
self.cx.path.push(i.ident);
111+
let ident = i.ident;
112+
if ident.name != token::special_idents::invalid.name {
113+
self.cx.path.push(ident);
114+
}
112115
debug!("current path: {}",
113116
ast_util::path_name_i(self.cx.path.as_slice()));
114117

@@ -143,7 +146,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
143146
ast::ItemMod(..) => fold::noop_fold_item(i, self),
144147
_ => SmallVector::one(i),
145148
};
146-
self.cx.path.pop();
149+
if ident.name != token::special_idents::invalid.name {
150+
self.cx.path.pop();
151+
}
147152
res
148153
}
149154

src/test/auxiliary/stability_cfg1.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![cfg_attr(foo, experimental)]
12+
#![cfg_attr(not(foo), stable)]

src/test/auxiliary/stability_cfg2.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags:--cfg foo
12+
13+
#![cfg_attr(foo, experimental)]
14+
#![cfg_attr(not(foo), stable)]
15+
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// error-pattern:main function not found
12+
13+
#![cfg(bar)]

src/test/compile-fail/lint-stability.rs

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// aux-build:lint_stability.rs
1212
// aux-build:inherited_stability.rs
13+
// aux-build:stability_cfg1.rs
14+
// aux-build:stability_cfg2.rs
1315

1416
#![feature(globs, phase)]
1517
#![deny(unstable)]
@@ -18,6 +20,9 @@
1820
#![allow(dead_code)]
1921

2022
mod cross_crate {
23+
extern crate stability_cfg1;
24+
extern crate stability_cfg2; //~ ERROR: use of experimental item
25+
2126
#[phase(plugin, link)]
2227
extern crate lint_stability; //~ ERROR: use of unmarked item
2328
use self::lint_stability::*;

src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ digraph block {
22
N0[label="entry"];
33
N1[label="exit"];
44
N2[label="expr 3i"];
5-
N3[label="expr 33i"];
6-
N4[label="expr 3i + 33i"];
7-
N5[label="stmt 3i + 33i;"];
8-
N6[label="block { 3i + 33i; }"];
5+
N3[label="expr 4"];
6+
N4[label="expr 3i + 4"];
7+
N5[label="stmt 3i + 4;"];
8+
N6[label="block { 3i + 4; }"];
99
N0 -> N2;
1010
N2 -> N3;
1111
N3 -> N4;

src/test/run-make/graphviz-flowgraph/f03.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// except according to those terms.
1010

1111
pub fn expr_add_3() {
12-
3i + 33i;
12+
3i + 4;
1313
}

src/test/run-pass/cfg-in-crate-1.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: --cfg bar -D warnings
12+
13+
#![cfg(bar)]
14+
15+
fn main() {}

0 commit comments

Comments
 (0)