Repository: rust-lang/rust-bindgen (Rust)

Issue:
Dyn keyword is not escaped.
<!-- Thanks for filing a bindgen issue! We appreciate it :-) -->

### Input C/C++ Header

```C++
struct pf_addr_wrap {
	union {
		struct {
			struct pf_addr		 addr;
			struct pf_addr		 mask;
		}			 a;
		char			 ifname[IFNAMSIZ];
		char			 tblname[PF_TABLE_NAME_SIZE];
		char			 rtlabelname[RTLABEL_LEN];
		u_int32_t		 rtlabel;
	}			 v;
	union {
#ifdef KERNEL
		struct pfi_dynaddr	*dyn	__attribute__((aligned(8)));
		struct pfr_ktable	*tbl	__attribute__((aligned(8)));
#else /* !KERNEL */
		void			*dyn	__attribute__((aligned(8)));
		void			*tbl	__attribute__((aligned(8)));
#endif /* !KERNEL */
		int			 dyncnt __attribute__((aligned(8)));
		int			 tblcnt __attribute__((aligned(8)));
	}			 p __attribute__((aligned(8)));
	u_int8_t		 type;		/* PF_ADDR_* */
	u_int8_t		 iflags;	/* PFI_AFLAG_* */
};
```

### Bindgen Invocation

<!-- Place either the `bindgen::Builder` or the command line flags used here. -->

```Rust
bindgen::Builder::default()
    .header("input.h")
    .generate()
    .unwrap()
```

or

```
$ bindgen input.h --whatever --flags
```

### Actual Results

```
error: expected identifier, found keyword `dyn`
   --> src/ffi/pfvar.rs:581:9
    |
581 |     pub dyn: *mut ::std::os::raw::c_void,
    |         ^^^ expected identifier, found keyword
    |
help: you can escape reserved keywords to use them as identifiers
    |
581 |     pub r#dyn: *mut ::std::os::raw::c_void,
    |         ^^^^^

error: unions cannot have zero fields
   --> src/ffi/pfvar.rs:580:1
    |
580 | / pub union pf_addr_wrap__bindgen_ty_2 {
581 | |     pub dyn: *mut ::std::os::raw::c_void,
582 | |     pub tbl: *mut ::std::os::raw::c_void,
583 | |     pub dyncnt: ::std::os::raw::c_int,
584 | |     pub tblcnt: ::std::os::raw::c_int,
585 | |     _bindgen_union_align: u64,
586 | | }
    | |_^
```

and/or

```rust
// Insert the (incorrect/buggy) generated bindings here
```

and/or

```
Insert compilation errors generated when compiling the bindings with rustc here
```

### Expected Results

<!--
Replace this with a description of what you expected instead of the actual
results. The more precise, the better! For example, if a struct in the generated
bindings is missing a field that exists in the C/C++ struct, note that here.
-->



Discussion:
Nice catch, easy enough :)

https://github.com/rust-lang/rust-bindgen/pull/1951



Patch:
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 1a54375779..0207547a54 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -807,9 +807,9 @@ If you encounter an error missing from this list, please file an issue or a PR!"
             match name {
                 "abstract" | "alignof" | "as" | "async" | "become" |
                 "box" | "break" | "const" | "continue" | "crate" | "do" |
-                "else" | "enum" | "extern" | "false" | "final" | "fn" |
-                "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" |
-                "match" | "mod" | "move" | "mut" | "offsetof" |
+                "dyn" | "else" | "enum" | "extern" | "false" | "final" |
+                "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" |
+                "macro" | "match" | "mod" | "move" | "mut" | "offsetof" |
                 "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
                 "return" | "Self" | "self" | "sizeof" | "static" |
                 "struct" | "super" | "trait" | "true" | "type" | "typeof" |


Test patch:
diff --git a/tests/expectations/tests/keywords.rs b/tests/expectations/tests/keywords.rs
index 129351912e..f77bda0bc2 100644
--- a/tests/expectations/tests/keywords.rs
+++ b/tests/expectations/tests/keywords.rs
@@ -61,6 +61,10 @@ extern "C" {
     #[link_name = "\u{1}str"]
     pub static mut str_: ::std::os::raw::c_int;
 }
+extern "C" {
+    #[link_name = "\u{1}dyn"]
+    pub static mut dyn_: ::std::os::raw::c_int;
+}
 extern "C" {
     #[link_name = "\u{1}as"]
     pub static mut as_: ::std::os::raw::c_int;
diff --git a/tests/headers/keywords.h b/tests/headers/keywords.h
index 0e492316bb..78ad278473 100644
--- a/tests/headers/keywords.h
+++ b/tests/headers/keywords.h
@@ -12,6 +12,7 @@ int usize;
 int isize;
 int bool;
 int str;
+int dyn;
 
 int as;
 int box;