Repository: dtolnay/cxx (language: rust)

Issue:
cxxbridge can't parse modules with inner attributes
Reproduction:

Put this code into `test.rs`:

```rust
#[cxx::bridge]
mod ffi {
    extern "Rust" {
        fn temp();
    }
}

mod c_ffi {
    #![allow(dead_code)]
    fn may_not_be_called() {}
}
```

Then:
```
cd cxx/gen/cmd
cargo run -- test.rs
```

Problem occurs:

```
error[cxxbridge]: expected square brackets
   ┌─ ../../build/rust/tests/bindgen_test/src/lib.rs:14:6
   │
14 │     #![allow(dead_code)]
   │      ^ expected square brackets

```

This seems to be because `gen/cmd/src/gen/file.rs` line 24 uses only parse_outer, as far as I can tell.

This problem is also known as https://issues.chromium.org/issues/372062067. It's not clear that inner attributes should actually be in use here, but also, cxxbridge probably shouldn't be the thing which gets upset about them.
Support for parsing modules with inner attributes
Fixes: #1378 .


Discussion / hints:
Hello, I have a query. In the test.rs you gave, mod c_ffi is not modified with #[cxx::bridge], but as per the execution error report, the cxxbridge tool still checks mod c_ffi?
Yes. The cxx parser has to parse all the mods to check for the relevant attributes.
Thanks a lot for the quick reply! 
It may be rare to use inner attributes when using cxx, but it will provide users with more flexibility if we introduce it.
Just found a related issue #903 , so parsing modules with inner attributes is indeed necessary if we intend to support `#![cxx:bridge]`.


Fix patch:
diff --git a/gen/src/file.rs b/gen/src/file.rs
index d55021aaa..c1ed30480 100644
--- a/gen/src/file.rs
+++ b/gen/src/file.rs
@@ -11,13 +11,14 @@ pub(crate) struct File {
 impl Parse for File {
     fn parse(input: ParseStream) -> Result<Self> {
         let mut modules = Vec::new();
-        input.call(Attribute::parse_inner)?;
         parse(input, &mut modules)?;
         Ok(File { modules })
     }
 }
 
 fn parse(input: ParseStream, modules: &mut Vec<Module>) -> Result<()> {
+    input.call(Attribute::parse_inner)?;
+
     while !input.is_empty() {
         let mut cxx_bridge = false;
         let mut namespace = Namespace::ROOT;
@@ -60,6 +61,7 @@ fn parse(input: ParseStream, modules: &mut Vec<Module>) -> Result<()> {
             }
         }
     }
+
     Ok(())
 }
 


Test patch: