Skip to content

Commit bbc8a54

Browse files
committed
rollup merge of rust-lang#22116: kmcallister/cfg_attr
Fixes rust-lang#22070. Fixes rust-lang#19372. r? @sfackler
2 parents c33acf6 + 5354317 commit bbc8a54

File tree

10 files changed

+133
-54
lines changed

10 files changed

+133
-54
lines changed

src/libsyntax/config.rs

+48-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use attr::AttrMetaMethods;
1212
use diagnostic::SpanHandler;
1313
use fold::Folder;
1414
use {ast, fold, attr};
15-
use codemap::Spanned;
15+
use codemap::{Spanned, respan};
1616
use ptr::P;
1717

1818
use util::small_vector::SmallVector;
@@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
2626
// Support conditional compilation by transforming the AST, stripping out
2727
// any items that do not belong in the current configuration
2828
pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
29+
let krate = process_cfg_attr(diagnostic, krate);
2930
let config = krate.config.clone();
3031
strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs))
3132
}
@@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
281282
attr::cfg_matches(diagnostic, cfg, &*mis[0])
282283
})
283284
}
285+
286+
struct CfgAttrFolder<'a> {
287+
diag: &'a SpanHandler,
288+
config: ast::CrateConfig,
289+
}
290+
291+
// Process `#[cfg_attr]`.
292+
fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
293+
let mut fld = CfgAttrFolder {
294+
diag: diagnostic,
295+
config: krate.config.clone(),
296+
};
297+
fld.fold_crate(krate)
298+
}
299+
300+
impl<'a> fold::Folder for CfgAttrFolder<'a> {
301+
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
302+
if !attr.check_name("cfg_attr") {
303+
return fold::noop_fold_attribute(attr, self);
304+
}
305+
306+
let (cfg, mi) = match attr.meta_item_list() {
307+
Some([ref cfg, ref mi]) => (cfg, mi),
308+
_ => {
309+
self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
310+
return None;
311+
}
312+
};
313+
314+
if attr::cfg_matches(self.diag, &self.config[], &cfg) {
315+
Some(respan(mi.span, ast::Attribute_ {
316+
id: attr::mk_attr_id(),
317+
style: attr.node.style,
318+
value: mi.clone(),
319+
is_sugared_doc: false,
320+
}))
321+
} else {
322+
None
323+
}
324+
}
325+
326+
// Need the ability to run pre-expansion.
327+
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
328+
fold::noop_fold_mac(mac, self)
329+
}
330+
}

src/libsyntax/ext/base.rs

-2
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,6 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
528528
syntax_expanders.insert(intern("cfg"),
529529
builtin_normal_expander(
530530
ext::cfg::expand_cfg));
531-
syntax_expanders.insert(intern("cfg_attr"),
532-
Modifier(box ext::cfg_attr::expand));
533531
syntax_expanders.insert(intern("trace_macros"),
534532
builtin_normal_expander(
535533
ext::trace_macros::expand_trace_macros));

src/libsyntax/ext/cfg_attr.rs

-34
This file was deleted.

src/libsyntax/ext/expand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
844844
arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
845845
let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
846846
ast::Arm {
847-
attrs: arm.attrs.move_map(|x| fld.fold_attribute(x)),
847+
attrs: fold::fold_attrs(arm.attrs, fld),
848848
pats: rewritten_pats,
849849
guard: rewritten_guard,
850850
body: rewritten_body,
@@ -1273,7 +1273,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
12731273
let (rewritten_fn_decl, rewritten_body)
12741274
= expand_and_rename_fn_decl_and_block(decl, body, fld);
12751275
SmallVector::one(P(ast::Method {
1276-
attrs: m.attrs.move_map(|a| fld.fold_attribute(a)),
1276+
attrs: fold::fold_attrs(m.attrs, fld),
12771277
id: id,
12781278
span: fld.new_span(m.span),
12791279
node: ast::MethDecl(fld.fold_ident(ident),

src/libsyntax/fold.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ pub trait Folder : Sized {
223223
noop_fold_lifetime_def(l, self)
224224
}
225225

226-
fn fold_attribute(&mut self, at: Attribute) -> Attribute {
226+
fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> {
227227
noop_fold_attribute(at, self)
228228
}
229229

@@ -373,9 +373,13 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
373373
})
374374
}
375375

376+
pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
377+
attrs.into_iter().flat_map(|x| fld.fold_attribute(x).into_iter()).collect()
378+
}
379+
376380
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
377381
Arm {
378-
attrs: attrs.move_map(|x| fld.fold_attribute(x)),
382+
attrs: fold_attrs(attrs, fld),
379383
pats: pats.move_map(|x| fld.fold_pat(x)),
380384
guard: guard.map(|x| fld.fold_expr(x)),
381385
body: fld.fold_expr(body),
@@ -475,7 +479,7 @@ pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
475479
node: Variant_ {
476480
id: fld.new_id(id),
477481
name: name,
478-
attrs: attrs.move_map(|x| fld.fold_attribute(x)),
482+
attrs: fold_attrs(attrs, fld),
479483
kind: match kind {
480484
TupleVariantKind(variant_args) => {
481485
TupleVariantKind(variant_args.move_map(|x|
@@ -553,17 +557,17 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
553557
})
554558
}
555559

556-
pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
560+
pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> {
557561
let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at;
558-
Spanned {
562+
Some(Spanned {
559563
node: Attribute_ {
560564
id: id,
561565
style: style,
562566
value: fld.fold_meta_item(value),
563567
is_sugared_doc: is_sugared_doc
564568
},
565569
span: fld.new_span(span)
566-
}
570+
})
567571
}
568572

569573
pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_, fld: &mut T)
@@ -845,8 +849,8 @@ pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
845849
where T: Folder {
846850
let new_id = folder.new_id(t.id);
847851
let new_span = folder.new_span(t.span);
848-
let new_attrs = t.attrs.iter().map(|attr| {
849-
folder.fold_attribute((*attr).clone())
852+
let new_attrs = t.attrs.iter().flat_map(|attr| {
853+
folder.fold_attribute((*attr).clone()).into_iter()
850854
}).collect();
851855
let new_ident = folder.fold_ident(t.ident);
852856
let new_type = folder.fold_ty(t.typ);
@@ -866,7 +870,7 @@ pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
866870
{
867871
let new_attrs = at.attrs
868872
.iter()
869-
.map(|attr| folder.fold_attribute((*attr).clone()))
873+
.flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
870874
.collect();
871875
let new_param = folder.fold_ty_param(at.ty_param);
872876
ast::AssociatedType {
@@ -909,7 +913,7 @@ pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructF
909913
id: fld.new_id(id),
910914
kind: kind,
911915
ty: fld.fold_ty(ty),
912-
attrs: attrs.move_map(|a| fld.fold_attribute(a))
916+
attrs: fold_attrs(attrs, fld),
913917
},
914918
span: fld.new_span(span)
915919
}
@@ -1072,7 +1076,7 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
10721076
TypeMethod {
10731077
id: fld.new_id(id),
10741078
ident: fld.fold_ident(ident),
1075-
attrs: attrs.move_map(|a| fld.fold_attribute(a)),
1079+
attrs: fold_attrs(attrs, fld),
10761080
unsafety: unsafety,
10771081
abi: abi,
10781082
decl: fld.fold_fn_decl(decl),
@@ -1154,7 +1158,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
11541158
Item {
11551159
id: id,
11561160
ident: folder.fold_ident(ident),
1157-
attrs: attrs.move_map(|e| folder.fold_attribute(e)),
1161+
attrs: fold_attrs(attrs, folder),
11581162
node: node,
11591163
vis: vis,
11601164
span: folder.new_span(span)
@@ -1165,7 +1169,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
11651169
ni.map(|ForeignItem {id, ident, attrs, node, span, vis}| ForeignItem {
11661170
id: folder.new_id(id),
11671171
ident: folder.fold_ident(ident),
1168-
attrs: attrs.move_map(|x| folder.fold_attribute(x)),
1172+
attrs: fold_attrs(attrs, folder),
11691173
node: match node {
11701174
ForeignItemFn(fdec, generics) => {
11711175
ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
@@ -1184,7 +1188,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
11841188
pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> {
11851189
SmallVector::one(m.map(|Method {id, attrs, node, span}| Method {
11861190
id: folder.new_id(id),
1187-
attrs: attrs.move_map(|a| folder.fold_attribute(a)),
1191+
attrs: fold_attrs(attrs, folder),
11881192
node: match node {
11891193
MethDecl(ident,
11901194
generics,

src/libsyntax/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ pub mod ext {
9696
pub mod base;
9797
pub mod build;
9898
pub mod cfg;
99-
pub mod cfg_attr;
10099
pub mod concat;
101100
pub mod concat_idents;
102101
pub mod deriving;
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2015 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+
// compile-flags: --cfg foo
13+
14+
// main is conditionally compiled, but the conditional compilation
15+
// is conditional too!
16+
17+
#[cfg_attr(foo, cfg(bar))]
18+
fn main() { }
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2015 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 broken
12+
13+
// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
14+
15+
#![cfg_attr(broken, no_std)] //~ ERROR no_std is experimental
16+
17+
fn main() { }

src/test/run-pass/cfg-attr-cfg.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2015 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+
// main is conditionally compiled, but the conditional compilation
12+
// is conditional too!
13+
14+
#[cfg_attr(foo, cfg(bar))]
15+
fn main() { }

src/test/run-pass/cfg-attr-crate.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2015 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+
// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
12+
13+
#![cfg_attr(not_used, no_std)]
14+
15+
fn main() { }

0 commit comments

Comments
 (0)