about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/front/config.rs38
-rw-r--r--src/test/run-pass/issue-11085.rs55
2 files changed, 92 insertions, 1 deletions
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index 58e7963ca90..1ddc2cf6696 100644
--- a/src/librustc/front/config.rs
+++ b/src/librustc/front/config.rs
@@ -11,6 +11,7 @@
 
 use syntax::fold::ast_fold;
 use syntax::{ast, fold, attr};
+use syntax::codemap;
 
 struct Context<'a> {
     in_cfg: 'a |attrs: &[ast::Attribute]| -> bool,
@@ -109,12 +110,47 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::item_) -> ast::item_ {
                                  .collect();
             ast::item_trait((*a).clone(), (*b).clone(), methods)
         }
-        ref item => (*item).clone(),
+        ast::item_struct(def, ref generics) => {
+            ast::item_struct(fold_struct(cx, def), generics.clone())
+        }
+        ast::item_enum(ref def, ref generics) => {
+            let mut variants = def.variants.iter().map(|c| c.clone()).filter(|m| {
+                (cx.in_cfg)(m.node.attrs)
+            }).map(|v| {
+                match v.node.kind {
+                    ast::tuple_variant_kind(..) => v,
+                    ast::struct_variant_kind(def) => {
+                        let def = fold_struct(cx, def);
+                        @codemap::Spanned {
+                            node: ast::variant_ {
+                                kind: ast::struct_variant_kind(def),
+                                ..v.node.clone()
+                            },
+                            ..*v
+                        }
+                    }
+                }
+            });
+            ast::item_enum(ast::enum_def {
+                variants: variants.collect(),
+            }, generics.clone())
+        }
+        ref item => item.clone(),
     };
 
     fold::noop_fold_item_underscore(&item, cx)
 }
 
+fn fold_struct(cx: &Context, def: &ast::struct_def) -> @ast::struct_def {
+    let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
+        (cx.in_cfg)(m.node.attrs)
+    });
+    @ast::struct_def {
+        fields: fields.collect(),
+        ctor_id: def.ctor_id,
+    }
+}
+
 fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
     match stmt.node {
       ast::StmtDecl(decl, _) => {
diff --git a/src/test/run-pass/issue-11085.rs b/src/test/run-pass/issue-11085.rs
new file mode 100644
index 00000000000..9d7eab050d8
--- /dev/null
+++ b/src/test/run-pass/issue-11085.rs
@@ -0,0 +1,55 @@
+// Copyright 2012-2013 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 foo
+// xfail-fast
+
+#[feature(struct_variant)];
+
+struct Foo {
+    #[cfg(fail)]
+    bar: baz,
+    foo: int,
+}
+
+struct Foo2 {
+    #[cfg(foo)]
+    foo: int,
+}
+
+enum Bar1 {
+    Bar1_1,
+    #[cfg(fail)]
+    Bar1_2(NotAType),
+}
+
+enum Bar2 {
+    #[cfg(fail)]
+    Bar2_1(NotAType),
+}
+
+enum Bar3 {
+    Bar3_1 {
+        #[cfg(fail)]
+        foo: int,
+        bar: int,
+    }
+}
+
+fn main() {
+    let _f = Foo { foo: 3 };
+    let _f = Foo2 { foo: 3 };
+
+    match Bar1_1 {
+        Bar1_1 => {}
+    }
+
+    let _f = Bar3_1 { bar: 3 };
+}