From: Antonio Gomes <antoniospg...@gmail.com>

gcc/rust/ChangeLog:
        * expand/rust-cfg-strip.cc:
        Strip struct expr fields and strip fields in struct definition
        * expand/rust-cfg-strip.h:
        Signatures for new function maybe_strip_struct_expr_fields

gcc/testsuite/ChangeLog:
        * rust/compile/macro-issue2983_2984.rs:
        Add test to check for correct stripped fields

Signed-off-by: Antonio Gomes <antoniospg...@gmail.com>
---
 gcc/rust/expand/rust-cfg-strip.cc             | 26 ++++++++++++++++++
 gcc/rust/expand/rust-cfg-strip.h              |  2 ++
 .../rust/compile/macro-issue2983_2984.rs      | 27 +++++++++++++++++++
 3 files changed, 55 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/macro-issue2983_2984.rs

diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index 8abc5cb766e..4e6a8ac2b5f 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -194,6 +194,26 @@ CfgStrip::maybe_strip_struct_fields 
(std::vector<AST::StructField> &fields)
     }
 }
 
+void
+CfgStrip::maybe_strip_struct_expr_fields (
+  std::vector<std::unique_ptr<AST::StructExprField>> &fields)
+{
+  for (auto it = fields.begin (); it != fields.end ();)
+    {
+      auto &field = *it;
+
+      auto &field_attrs = field->get_outer_attrs ();
+      expand_cfg_attrs (field_attrs);
+      if (fails_cfg_with_expand (field_attrs))
+       {
+         it = fields.erase (it);
+         continue;
+       }
+
+      ++it;
+    }
+}
+
 void
 CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
 {
@@ -962,6 +982,8 @@ CfgStrip::visit (AST::StructExprStructFields &expr)
                       "cannot strip expression in this position - outer "
                       "attributes not allowed");
     }
+
+  maybe_strip_struct_expr_fields (expr.get_fields ());
 }
 
 void
@@ -1852,6 +1874,10 @@ CfgStrip::visit (AST::StructStruct &struct_item)
     }
 
   AST::DefaultASTVisitor::visit (struct_item);
+
+  /* strip struct fields if required - this is presumably
+   * allowed by spec */
+  maybe_strip_struct_fields (struct_item.get_fields ());
 }
 void
 CfgStrip::visit (AST::TupleStruct &tuple_struct)
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 773bfdeaf8c..4900ae893ed 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -36,6 +36,8 @@ public:
   void go (AST::Crate &crate);
 
   void maybe_strip_struct_fields (std::vector<AST::StructField> &fields);
+  void maybe_strip_struct_expr_fields (
+    std::vector<std::unique_ptr<AST::StructExprField>> &fields);
   void maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields);
   void maybe_strip_function_params (
     std::vector<std::unique_ptr<AST::Param>> &params);
diff --git a/gcc/testsuite/rust/compile/macro-issue2983_2984.rs 
b/gcc/testsuite/rust/compile/macro-issue2983_2984.rs
new file mode 100644
index 00000000000..637d5728c50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue2983_2984.rs
@@ -0,0 +1,27 @@
+pub struct ReadDir {
+    pub inner: i32,
+    #[cfg(not(A))]
+    pub end_of_stream: bool,
+    #[cfg(A)]
+    pub end_of_stream_but_different: bool,
+}
+
+fn main() {
+    // Success
+    let _ = ReadDir {
+        inner: 14,
+        #[cfg(not(A))]
+        end_of_stream: false,
+        #[cfg(A)]
+        end_of_stream_but_different: false,
+    };
+
+    // Error
+    let _ = ReadDir {
+        inner: 14,
+        end_of_stream: false,
+        end_of_stream_but_different: false, // { dg-error "failed to resolve 
type for field" }
+        // { dg-error "unknown field" "" { target *-*-* } .-1 }
+        // { dg-prune-output "compilation terminated" }
+    };
+}
-- 
2.45.2

Reply via email to