diff options
author | David LeGare <legare@google.com> | 2022-03-02 21:48:47 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-03-02 21:48:47 +0000 |
commit | 9462220143e9a759de1a3e30f6c2f92e5d42d4bf (patch) | |
tree | 66ee953affacd8924e3499ef6e55bb58871733ab | |
parent | 753c0498a954a000638b16c023f89e5347fd9978 (diff) | |
parent | 06227d3ba6dc639fd974cfce199d604400056019 (diff) | |
download | bindgen-android13-qpr1-s8-release.tar.gz |
Update bindgen to 0.59.2 am: 19fbac68e6 am: 22c064f569 am: 06227d3ba6t_frc_odp_330442040t_frc_odp_330442000t_frc_ase_330444010android-13.0.0_r83android-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android-13.0.0_r57android-13.0.0_r56android-13.0.0_r55android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android-13.0.0_r49android-13.0.0_r48android-13.0.0_r47android-13.0.0_r46android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android-13.0.0_r30android-13.0.0_r29android-13.0.0_r28android-13.0.0_r27android-13.0.0_r24android-13.0.0_r23android-13.0.0_r22android-13.0.0_r21android-13.0.0_r20android-13.0.0_r19android-13.0.0_r18android-13.0.0_r17android-13.0.0_r16aml_go_odp_330912000aml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-releaseandroid13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-releaseandroid13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-releaseandroid13-qpr1-s8-releaseandroid13-qpr1-s7-releaseandroid13-qpr1-s6-releaseandroid13-qpr1-s5-releaseandroid13-qpr1-s4-releaseandroid13-qpr1-s3-releaseandroid13-qpr1-s2-releaseandroid13-qpr1-s1-releaseandroid13-qpr1-releaseandroid13-mainline-go-adservices-releaseandroid13-frc-odp-releaseandroid13-devandroid13-d4-s2-releaseandroid13-d4-s1-releaseandroid13-d4-releaseandroid13-d3-s1-releaseandroid13-d2-release
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/bindgen/+/2005111
Change-Id: Idebbfdaba156a78c76936407abf7f5c36c579d90
38 files changed, 798 insertions, 791 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 7298dd9..f1c8552 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "9a9438f3d6a3523c69d7bc890e8608b63dbe38a5" + "sha1": "89032649044d875983a851fff6fbde2d4e2ceaeb" } } @@ -46,7 +46,7 @@ rust_binary_host { // has rustc warnings crate_name: "bindgen", cargo_env_compat: true, - cargo_pkg_version: "0.59.1", + cargo_pkg_version: "0.59.2", srcs: [ "src/main.rs", ":copy_bindgen_build_out", @@ -82,7 +82,7 @@ rust_library_host { // has rustc warnings crate_name: "bindgen", cargo_env_compat: true, - cargo_pkg_version: "0.59.1", + cargo_pkg_version: "0.59.2", srcs: [ "src/lib.rs", ":copy_bindgen_build_out", @@ -33,7 +33,7 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.59.1" +version = "0.59.2" dependencies = [ "bitflags", "cexpr", @@ -61,43 +61,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "bitvec" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] name = "cexpr" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] [[package]] name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.0.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0659001ab56b791be01d4b729c44376edc6718cf389a502e579b77b758f3296c" +checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" dependencies = [ "glob", "libc", @@ -126,10 +108,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" [[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] name = "env_logger" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", "humantime", @@ -139,18 +127,12 @@ dependencies = [ ] [[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - -[[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -163,18 +145,18 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hermit-abi" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "humantime" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "lazy_static" @@ -190,27 +172,27 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "libloading" -version = "0.6.5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1090080fe06ec2648d0da3881d9453d97e71a45f00eb179af7fdd7e3f686fdb0" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "winapi", ] [[package]] name = "log" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", ] [[package]] @@ -220,14 +202,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] +name = "minimal-lexical" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" + +[[package]] name = "nom" -version = "6.2.1" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" +checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" dependencies = [ - "bitvec", - "funty", "memchr", + "minimal-lexical", "version_check", ] @@ -245,33 +232,27 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] -name = "radium" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" - -[[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", @@ -281,9 +262,9 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", @@ -291,48 +272,47 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ "rand_core", ] [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" @@ -362,18 +342,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] name = "tempfile" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", @@ -383,9 +357,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] @@ -400,15 +374,6 @@ dependencies = [ ] [[package]] -name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - -[[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -416,9 +381,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "vec_map" @@ -428,9 +393,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "wasi" @@ -440,10 +405,12 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "which" -version = "3.1.1" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +checksum = "7cc009ab82a2afc94b9e467ab4214aee9cad1356cd9191264203d7d72006e00d" dependencies = [ + "either", + "lazy_static", "libc", ] @@ -477,9 +444,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "bindgen" -version = "0.59.1" +version = "0.59.2" authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"] build = "build.rs" include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"] @@ -38,7 +37,7 @@ required-features = ["clap"] version = "1.0.3" [dependencies.cexpr] -version = "0.5" +version = "0.6" [dependencies.clang-sys] version = "1" @@ -49,7 +48,7 @@ version = "2" optional = true [dependencies.env_logger] -version = "0.8" +version = "0.9.0" optional = true [dependencies.lazy_static] @@ -85,7 +84,7 @@ version = "1.0.1" version = "1" [dependencies.which] -version = "3.0" +version = "4.2.1" optional = true default-features = false [dev-dependencies.clap] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 7cf5953..ba41a22 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -14,7 +14,7 @@ readme = "README.md" repository = "https://github.com/rust-lang/rust-bindgen" documentation = "https://docs.rs/bindgen" homepage = "https://rust-lang.github.io/rust-bindgen/" -version = "0.59.1" +version = "0.59.2" edition = "2018" build = "build.rs" @@ -47,7 +47,7 @@ tempfile = "3" [dependencies] bitflags = "1.0.3" -cexpr = "0.5" +cexpr = "0.6" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 clap = { version = "2", optional = true } clang-sys = { version = "1", features = ["clang_6_0"] } @@ -56,14 +56,14 @@ lazy_static = "1" peeking_take_while = "0.1.2" quote = { version = "1", default-features = false } regex = { version = "1.0", default-features = false , features = [ "std", "unicode"]} -which = { version = "3.0", optional = true, default-features = false } +which = { version = "4.2.1", optional = true, default-features = false } shlex = "1" rustc-hash = "1.0.1" proc-macro2 = { version = "1", default-features = false } [dependencies.env_logger] optional = true -version = "0.8" +version = "0.9.0" [dependencies.log] optional = true @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/bindgen/bindgen-0.59.1.crate" + value: "https://static.crates.io/crates/bindgen/bindgen-0.59.2.crate" } - version: "0.59.1" + version: "0.59.2" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 8 - day: 9 + year: 2022 + month: 3 + day: 1 } } @@ -39,7 +39,7 @@ extern "C" { ## MSRV -The minimum supported Rust version is **1.44**. +The minimum supported Rust version is **1.46**. No MSRV bump policy has been established yet, so MSRV may increase in any release. diff --git a/src/clang.rs b/src/clang.rs index db6467e..074d459 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -4,9 +4,7 @@ #![allow(non_upper_case_globals, dead_code)] use crate::ir::context::BindgenContext; -use cexpr; use clang_sys::*; -use regex; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; @@ -85,7 +83,7 @@ impl Cursor { let mut result = Vec::with_capacity(count); for i in 0..count { - let string_ptr = (*manglings).Strings.offset(i as isize); + let string_ptr = (*manglings).Strings.add(i); result.push(cxstring_to_string_leaky(*string_ptr)); } clang_disposeStringSet(manglings); @@ -223,12 +221,12 @@ impl Cursor { /// not tracking the type declaration but the location of the cursor, given /// clang doesn't expose a proper declaration for these types. pub fn is_template_like(&self) -> bool { - match self.kind() { + matches!( + self.kind(), CXCursor_ClassTemplate | - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl => true, - _ => false, - } + CXCursor_ClassTemplatePartialSpecialization | + CXCursor_TypeAliasTemplateDecl + ) } /// Is this Cursor pointing to a function-like macro definition? @@ -275,7 +273,7 @@ impl Cursor { return parent.is_in_non_fully_specialized_template(); } - return true; + true } /// Is this cursor pointing a valid referent? @@ -402,12 +400,9 @@ impl Cursor { where Visitor: FnMut(Cursor) -> CXChildVisitResult, { + let data = &mut visitor as *mut Visitor; unsafe { - clang_visitChildren( - self.x, - visit_children::<Visitor>, - mem::transmute(&mut visitor), - ); + clang_visitChildren(self.x, visit_children::<Visitor>, data.cast()); } } @@ -900,7 +895,7 @@ extern "C" fn visit_children<Visitor>( where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let func: &mut Visitor = unsafe { mem::transmute(data) }; + let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) }; let child = Cursor { x: cur }; (*func)(child) @@ -1027,7 +1022,7 @@ impl Type { let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }; // Clang 5.0 introduced changes in the spelling API so it returned the // full qualified name. Let's undo that here. - if s.split("::").all(|s| is_valid_identifier(s)) { + if s.split("::").all(is_valid_identifier) { if let Some(s) = s.split("::").last() { return s.to_owned(); } @@ -1055,7 +1050,7 @@ impl Type { ctx.target_pointer_size() as c_longlong } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => return -6, + CXType_Auto if self.is_non_deductible_auto_type() => -6, _ => unsafe { clang_Type_getSizeOf(self.x) }, } } @@ -1068,7 +1063,7 @@ impl Type { ctx.target_pointer_size() as c_longlong } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => return -6, + CXType_Auto if self.is_non_deductible_auto_type() => -6, _ => unsafe { clang_Type_getAlignOf(self.x) }, } } @@ -1286,12 +1281,12 @@ impl Type { // nasty... But can happen in <type_traits>. Unfortunately I couldn't // reduce it enough :( self.template_args().map_or(false, |args| args.len() > 0) && - match self.declaration().kind() { + !matches!( + self.declaration().kind(), CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl | - CXCursor_TemplateTemplateParameter => false, - _ => true, - } + CXCursor_TypeAliasTemplateDecl | + CXCursor_TemplateTemplateParameter + ) } /// Is this type an associated template type? Eg `T::Associated` in @@ -1406,6 +1401,12 @@ impl fmt::Display for SourceLocation { } } +impl fmt::Debug for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self) + } +} + /// A comment in the source text. /// /// Comments are sort of parsed by Clang, and have a tree structure. @@ -1704,11 +1705,7 @@ impl UnsavedFile { Contents: contents.as_ptr(), Length: contents.as_bytes().len() as c_ulong, }; - UnsavedFile { - x: x, - name: name, - contents: contents, - } + UnsavedFile { x, name, contents } } } @@ -1819,7 +1816,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { if let Some(refd) = c.referenced() { if refd != *c { - println!(""); + println!(); print_cursor( depth, String::from(prefix) + "referenced.", @@ -1830,7 +1827,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let canonical = c.canonical(); if canonical != *c { - println!(""); + println!(); print_cursor( depth, String::from(prefix) + "canonical.", @@ -1840,7 +1837,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { if let Some(specialized) = c.specialized() { if specialized != *c { - println!(""); + println!(); print_cursor( depth, String::from(prefix) + "specialized.", @@ -1850,7 +1847,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { } if let Some(parent) = c.fallible_semantic_parent() { - println!(""); + println!(); print_cursor( depth, String::from(prefix) + "semantic-parent.", @@ -1898,34 +1895,34 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let canonical = ty.canonical_type(); if canonical != *ty { - println!(""); + println!(); print_type(depth, String::from(prefix) + "canonical.", &canonical); } if let Some(pointee) = ty.pointee_type() { if pointee != *ty { - println!(""); + println!(); print_type(depth, String::from(prefix) + "pointee.", &pointee); } } if let Some(elem) = ty.elem_type() { if elem != *ty { - println!(""); + println!(); print_type(depth, String::from(prefix) + "elements.", &elem); } } if let Some(ret) = ty.ret_type() { if ret != *ty { - println!(""); + println!(); print_type(depth, String::from(prefix) + "return.", &ret); } } let named = ty.named(); if named != *ty && named.is_valid() { - println!(""); + println!(); print_type(depth, String::from(prefix) + "named.", &named); } } @@ -1933,13 +1930,13 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { print_indent(depth, "("); print_cursor(depth, "", c); - println!(""); + println!(); let ty = c.cur_type(); print_type(depth, "type.", &ty); let declaration = ty.declaration(); if declaration != *c && declaration.kind() != CXCursor_NoDeclFound { - println!(""); + println!(); print_cursor(depth, "type.declaration.", &declaration); } @@ -1947,7 +1944,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let mut found_children = false; c.visit(|s| { if !found_children { - println!(""); + println!(); found_children = true; } ast_dump(&s, depth + 1) diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index 205995b..2ce6894 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -230,14 +230,14 @@ pub mod ast_ty { } pub fn byte_array_expr(bytes: &[u8]) -> TokenStream { - let mut bytes: Vec<_> = bytes.iter().cloned().collect(); + let mut bytes: Vec<_> = bytes.to_vec(); bytes.push(0); quote! { [ #(#bytes),* ] } } pub fn cstr_expr(mut string: String) -> TokenStream { string.push('\0'); - let b = proc_macro2::Literal::byte_string(&string.as_bytes()); + let b = proc_macro2::Literal::byte_string(string.as_bytes()); quote! { #b } @@ -271,7 +271,7 @@ pub mod ast_ty { } warn!("Unknown non-finite float number: {:?}", f); - return Err(()); + Err(()) } pub fn arguments_from_signature( diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 661711e..0e2cd33 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -2,7 +2,6 @@ use crate::ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName}; use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; -use proc_macro2; pub fn gen_debug_impl( ctx: &BindgenContext, @@ -23,8 +22,8 @@ pub fn gen_debug_impl( } CompKind::Struct => { let processed_fields = fields.iter().filter_map(|f| match f { - &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), - &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), + Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), + Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), }); for (i, (fstring, toks)) in processed_fields.enumerate() { @@ -186,24 +185,22 @@ impl<'a> ImplDebug<'a> for Item { { // The simple case debug_print(name, quote! { #name_ident }) + } else if ctx.options().use_core { + // There is no String in core; reducing field visibility to avoid breaking + // no_std setups. + Some((format!("{}: [...]", name), vec![])) } else { - if ctx.options().use_core { - // There is no String in core; reducing field visibility to avoid breaking - // no_std setups. - Some((format!("{}: [...]", name), vec![])) - } else { - // Let's implement our own print function - Some(( - format!("{}: [{{}}]", name), - vec![quote! { - self.#name_ident - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::<String>() - }], - )) - } + // Let's implement our own print function + Some(( + format!("{}: [{{}}]", name), + vec![quote! { + self.#name_ident + .iter() + .enumerate() + .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) + .collect::<String>() + }], + )) } } TypeKind::Vector(_, len) => { diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index 5a1ba3f..960306f 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -2,7 +2,6 @@ use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{IsOpaque, Item}; use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; -use proc_macro2; /// Generate a manual implementation of `PartialEq` trait for the /// specified compound type. @@ -51,7 +50,7 @@ pub fn gen_partialeq_impl( } Field::Bitfields(ref bu) => { for bitfield in bu.bitfields() { - if let Some(_) = bitfield.name() { + if bitfield.name().is_some() { let getter_name = bitfield.getter_name(); let name_ident = ctx.rust_ident_raw(getter_name); tokens.push(quote! { @@ -104,7 +103,7 @@ fn gen_field( TypeKind::Opaque => quote_equals(name_ident), TypeKind::TemplateInstantiation(ref inst) => { - if inst.is_opaque(ctx, &ty_item) { + if inst.is_opaque(ctx, ty_item) { quote! { &self. #name_ident [..] == &other. #name_ident [..] } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 0f3337a..19886e3 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -48,7 +48,6 @@ use proc_macro2::{self, Ident, Span}; use quote::TokenStreamExt; use crate::{Entry, HashMap, HashSet}; -use std; use std::borrow::Cow; use std::cell::Cell; use std::collections::VecDeque; @@ -58,7 +57,7 @@ use std::ops; use std::str::FromStr; // Name of type defined in constified enum module -pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type"; +pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type"; fn top_level_path( ctx: &BindgenContext, @@ -666,10 +665,21 @@ impl CodeGenerator for Var { match String::from_utf8(bytes.clone()) { Ok(string) => { let cstr = helpers::ast_ty::cstr_expr(string); - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : &'static #ty = #cstr ; - }); + if ctx + .options() + .rust_features + .static_lifetime_elision + { + result.push(quote! { + #(#attrs)* + pub const #canonical_ident : &#ty = #cstr ; + }); + } else { + result.push(quote! { + #(#attrs)* + pub const #canonical_ident : &'static #ty = #cstr ; + }); + } } Err(..) => { let bytes = helpers::ast_ty::byte_array_expr(bytes); @@ -681,12 +691,11 @@ impl CodeGenerator for Var { } } VarType::Float(f) => { - match helpers::ast_ty::float_expr(ctx, f) { - Ok(expr) => result.push(quote! { + if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) { + result.push(quote! { #(#attrs)* pub const #canonical_ident : #ty = #expr ; - }), - Err(..) => return, + }); } } VarType::Char(c) => { @@ -698,7 +707,7 @@ impl CodeGenerator for Var { } } else { // If necessary, apply a `#[link_name]` attribute - let link_name = self.mangled_name().unwrap_or(self.name()); + let link_name = self.mangled_name().unwrap_or_else(|| self.name()); if !utils::names_will_be_identical_after_mangling( &canonical_name, link_name, @@ -756,7 +765,6 @@ impl CodeGenerator for Type { // converted to rust types in fields, arguments, and such. // NOTE(emilio): If you add to this list, make sure to also add // it to BindgenContext::compute_allowlisted_and_codegen_items. - return; } TypeKind::TemplateInstantiation(ref inst) => { inst.codegen(ctx, result, item) @@ -886,12 +894,9 @@ impl CodeGenerator for Type { // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 - if inner_rust_type.to_string().chars().all(|c| match c { - // These are the only characters allowed in simple - // paths, eg `good::dogs::Bront`. - 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ' => true, - _ => false, - }) && outer_params.is_empty() && + // These are the only characters allowed in simple + // paths, eg `good::dogs::Bront`. + if inner_rust_type.to_string().chars().all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ')) && outer_params.is_empty() && !is_opaque && alias_style == AliasVariation::TypeAlias && inner_item.expect_type().canonical_type(ctx).is_enum() @@ -1767,7 +1772,7 @@ impl CodeGenerator for CompInfo { let inner_item = ctx.resolve_item(base.ty); let mut inner = inner_item.to_rust_ty_or_opaque(ctx, &()); - inner.append_implicit_template_params(ctx, &inner_item); + inner.append_implicit_template_params(ctx, inner_item); let field_name = ctx.rust_ident(&base.field_name); struct_layout.saw_base(inner_item.expect_type()); @@ -2023,6 +2028,11 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::derives(&derives)) } + if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) + { + attributes.push(attributes::must_use()); + } + let mut tokens = if is_union && struct_layout.is_rust_union() { quote! { #( #attributes )* @@ -2121,11 +2131,11 @@ impl CodeGenerator for CompInfo { }) .flat_map(|field| { let name = field.name().unwrap(); - field.offset().and_then(|offset| { + field.offset().map(|offset| { let field_offset = offset / 8; let field_name = ctx.rust_ident(name); - Some(quote! { + quote! { assert_eq!( unsafe { &(*(::#prefix::ptr::null::<#canonical_ident>())).#field_name as *const _ as usize @@ -2133,7 +2143,7 @@ impl CodeGenerator for CompInfo { #field_offset, concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name)) ); - }) + } }) }) .collect::<Vec<proc_macro2::TokenStream>>(); @@ -2343,7 +2353,7 @@ impl MethodCodegen for Method { return; } let function = function_item.expect_function(); - let times_seen = function.codegen(ctx, result, &function_item); + let times_seen = function.codegen(ctx, result, function_item); let times_seen = match times_seen { Some(seen) => seen, None => return, @@ -2409,7 +2419,7 @@ impl MethodCodegen for Method { } let mut exprs = - helpers::ast_ty::arguments_from_signature(&signature, ctx); + helpers::ast_ty::arguments_from_signature(signature, ctx); let mut stmts = vec![]; @@ -2466,8 +2476,7 @@ impl MethodCodegen for Method { #( #stmts );* }; - let mut attrs = vec![]; - attrs.push(attributes::inline()); + let mut attrs = vec![attributes::inline()]; if signature.must_use() && ctx.options().rust_features().must_use_function @@ -2508,19 +2517,13 @@ pub enum EnumVariation { impl EnumVariation { fn is_rust(&self) -> bool { - match *self { - EnumVariation::Rust { .. } => true, - _ => false, - } + matches!(*self, EnumVariation::Rust { .. }) } /// Both the `Const` and `ModuleConsts` variants will cause this to return /// true. fn is_const(&self) -> bool { - match *self { - EnumVariation::Consts | EnumVariation::ModuleConsts => true, - _ => false, - } + matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts) } } @@ -2598,10 +2601,7 @@ impl<'a> EnumBuilder<'a> { /// Returns true if the builder is for a rustified enum. fn is_rust_enum(&self) -> bool { - match *self { - EnumBuilder::Rust { .. } => true, - _ => false, - } + matches!(*self, EnumBuilder::Rust { .. }) } /// Create a new enum given an item builder, a canonical name, a name for @@ -2998,18 +2998,43 @@ impl CodeGenerator for Enum { attrs.push(attributes::doc(comment)); } + if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) + { + attrs.push(attributes::must_use()); + } + if !variation.is_const() { let mut derives = derives_of_item(item, ctx); - // For backwards compat, enums always derive Clone/Eq/PartialEq/Hash, even + // For backwards compat, enums always derive Debug/Clone/Eq/PartialEq/Hash, even // if we don't generate those by default. + if !item.annotations().disallow_debug() { + derives.insert(DerivableTraits::DEBUG); + } + if !item.annotations().disallow_copy() { + derives.insert(DerivableTraits::COPY); + } derives.insert( DerivableTraits::CLONE | - DerivableTraits::COPY | DerivableTraits::HASH | DerivableTraits::PARTIAL_EQ | DerivableTraits::EQ, ); - let derives: Vec<_> = derives.into(); + let mut derives: Vec<_> = derives.into(); + for derive in item.annotations().derives().iter() { + if !derives.contains(&derive.as_str()) { + derives.push(derive); + } + } + + // The custom derives callback may return a list of derive attributes; + // add them to the end of the list. + let custom_derives; + if let Some(cb) = &ctx.options().parse_callbacks { + custom_derives = cb.add_derives(&name); + // In most cases this will be a no-op, since custom_derives will be empty. + derives.extend(custom_derives.iter().map(|s| s.as_str())); + }; + attrs.push(attributes::derives(&derives)); } @@ -3067,7 +3092,7 @@ impl CodeGenerator for Enum { let constant_mangling_prefix = if ctx.options().prepend_enum_name { if enum_ty.name().is_none() { - parent_canonical_name.as_ref().map(|n| &**n) + parent_canonical_name.as_deref() } else { Some(&*name) } @@ -3626,13 +3651,12 @@ impl TryToRustTy for Type { let void = c_void(ctx); return Ok(void.to_ptr(/* is_const = */ false)); } - let template_params = item - .used_template_params(ctx) - .into_iter() - .filter(|param| param.is_template_param(ctx, &())) - .collect::<Vec<_>>(); - if item.is_opaque(ctx, &()) && !template_params.is_empty() { + if item.is_opaque(ctx, &()) && + item.used_template_params(ctx) + .into_iter() + .any(|param| param.is_template_param(ctx, &())) + { self.try_to_opaque(ctx, item) } else if let Some(ty) = self .name() @@ -3661,10 +3685,8 @@ impl TryToRustTy for Type { inner.into_resolver().through_type_refs().resolve(ctx); let inner_ty = inner.expect_type(); - let is_objc_pointer = match inner_ty.kind() { - TypeKind::ObjCInterface(..) => true, - _ => false, - }; + let is_objc_pointer = + matches!(inner_ty.kind(), TypeKind::ObjCInterface(..)); // Regardless if we can properly represent the inner type, we // should always generate a proper pointer here, so use @@ -3797,8 +3819,8 @@ impl TryToRustTy for FunctionSig { _: &(), ) -> error::Result<proc_macro2::TokenStream> { // TODO: we might want to consider ignoring the reference return value. - let ret = utils::fnsig_return_ty(ctx, &self); - let arguments = utils::fnsig_arguments(ctx, &self); + let ret = utils::fnsig_return_ty(ctx, self); + let arguments = utils::fnsig_arguments(ctx, self); let abi = self.abi(); match abi { @@ -4040,12 +4062,12 @@ impl CodeGenerator for ObjCInterface { impl_items.push(impl_item); } - let instance_method_names: Vec<_> = - self.methods().iter().map(|m| m.rust_name()).collect(); - for class_method in self.class_methods() { - let ambiquity = - instance_method_names.contains(&class_method.rust_name()); + let ambiquity = self + .methods() + .iter() + .map(|m| m.rust_name()) + .any(|x| x == class_method.rust_name()); let prefix = if ambiquity { "class_" } else { "" }; let impl_item = objc_method_codegen( ctx, @@ -4637,7 +4659,7 @@ pub mod utils { TypeKind::Array(t, _) => { let stream = if ctx.options().array_pointers_in_arguments { - arg_ty.to_rust_ty_or_opaque(ctx, &arg_item) + arg_ty.to_rust_ty_or_opaque(ctx, arg_item) } else { t.to_rust_ty_or_opaque(ctx, &()) }; diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 1c6b977..657be0b 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -279,6 +279,11 @@ impl<'a> StructLayoutTracker<'a> { return None; } + // Padding doesn't make sense for rust unions. + if self.is_rust_union { + return None; + } + if self.latest_offset == comp_layout.size { // This struct does not contain tail padding. return None; @@ -428,6 +433,6 @@ impl<'a> StructLayoutTracker<'a> { // Else, just align the obvious way. self.latest_offset += self.padding_bytes(layout); - return false; + false } } diff --git a/src/features.rs b/src/features.rs index 99b789e..a786f07 100644 --- a/src/features.rs +++ b/src/features.rs @@ -87,8 +87,9 @@ macro_rules! rust_target_base { $x_macro!( /// Rust stable 1.0 => Stable_1_0 => 1.0; - /// Rust stable 1.1 - => Stable_1_1 => 1.1; + /// Rust stable 1.17 + /// * Static lifetime elision ([RFC 1623](https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md)) + => Stable_1_17 => 1.17; /// Rust stable 1.19 /// * Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md)) => Stable_1_19 => 1.19; @@ -191,6 +192,9 @@ macro_rules! rust_feature_def { // documentation for the relevant variant in the rust_target_base macro // definition. rust_feature_def!( + Stable_1_17 { + => static_lifetime_elision; + } Stable_1_19 { => untagged_union; } @@ -249,7 +253,8 @@ mod test { fn target_features() { let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0); assert!( - !f_1_0.core_ffi_c_void && + !f_1_0.static_lifetime_elision && + !f_1_0.core_ffi_c_void && !f_1_0.untagged_union && !f_1_0.associated_const && !f_1_0.builtin_clone_impls && @@ -258,7 +263,8 @@ mod test { ); let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21); assert!( - !f_1_21.core_ffi_c_void && + f_1_21.static_lifetime_elision && + !f_1_21.core_ffi_c_void && f_1_21.untagged_union && f_1_21.associated_const && f_1_21.builtin_clone_impls && @@ -267,7 +273,8 @@ mod test { ); let f_nightly = RustFeatures::from(RustTarget::Nightly); assert!( - f_nightly.core_ffi_c_void && + f_nightly.static_lifetime_elision && + f_nightly.core_ffi_c_void && f_nightly.untagged_union && f_nightly.associated_const && f_nightly.builtin_clone_impls && @@ -286,6 +293,7 @@ mod test { #[test] fn str_to_target() { test_target("1.0", RustTarget::Stable_1_0); + test_target("1.17", RustTarget::Stable_1_17); test_target("1.19", RustTarget::Stable_1_19); test_target("1.21", RustTarget::Stable_1_21); test_target("1.25", RustTarget::Stable_1_25); diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs index 44e6702..f63458e 100644 --- a/src/ir/analysis/derive.rs +++ b/src/ir/analysis/derive.rs @@ -9,6 +9,7 @@ use crate::ir::context::{BindgenContext, ItemId}; use crate::ir::derive::CanDerive; use crate::ir::function::FunctionSig; use crate::ir::item::{IsOpaque, Item}; +use crate::ir::layout::Layout; use crate::ir::template::TemplateParameters; use crate::ir::traversal::{EdgeKind, Trace}; use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; @@ -159,7 +160,7 @@ impl<'ctx> CannotDerive<'ctx> { return can_derive; } - if self.derive_trait.not_by_name(self.ctx, &item) { + if self.derive_trait.not_by_name(self.ctx, item) { trace!( " cannot derive {} for explicitly excluded type", self.derive_trait @@ -223,13 +224,13 @@ impl<'ctx> CannotDerive<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - return self.derive_trait.can_derive_fnptr(sig); + self.derive_trait.can_derive_fnptr(sig) } else { - return self.derive_trait.can_derive_pointer(); + self.derive_trait.can_derive_pointer() } } TypeKind::Function(ref sig) => { - return self.derive_trait.can_derive_fnptr(sig) + self.derive_trait.can_derive_fnptr(sig) } // Complex cases need more information @@ -255,7 +256,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - if self.derive_trait.can_derive_large_array(&self.ctx) { + if self.derive_trait.can_derive_large_array(self.ctx) { trace!(" array can derive {}", self.derive_trait); return CanDerive::Yes; } @@ -270,7 +271,7 @@ impl<'ctx> CannotDerive<'ctx> { " array is small enough to derive {}", self.derive_trait ); - return CanDerive::Yes; + CanDerive::Yes } TypeKind::Vector(t, len) => { let inner_type = @@ -285,7 +286,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } assert_ne!(len, 0, "vectors cannot have zero length"); - return self.derive_trait.can_derive_vector(); + self.derive_trait.can_derive_vector() } TypeKind::Comp(ref info) => { @@ -377,7 +378,7 @@ impl<'ctx> CannotDerive<'ctx> { // Bitfield units are always represented as arrays of u8, but // they're not traced as arrays, so we need to check here // instead. - if !self.derive_trait.can_derive_large_array(&self.ctx) && + if !self.derive_trait.can_derive_large_array(self.ctx) && info.has_too_large_bitfield_unit() && !item.is_opaque(self.ctx, &()) { @@ -389,7 +390,7 @@ impl<'ctx> CannotDerive<'ctx> { } let pred = self.derive_trait.consider_edge_comp(); - return self.constrain_join(item, pred); + self.constrain_join(item, pred) } TypeKind::ResolvedTypeRef(..) | @@ -397,12 +398,12 @@ impl<'ctx> CannotDerive<'ctx> { TypeKind::Alias(..) | TypeKind::BlockPointer(..) => { let pred = self.derive_trait.consider_edge_typeref(); - return self.constrain_join(item, pred); + self.constrain_join(item, pred) } TypeKind::TemplateInstantiation(..) => { let pred = self.derive_trait.consider_edge_tmpl_inst(); - return self.constrain_join(item, pred); + self.constrain_join(item, pred) } TypeKind::Opaque => unreachable!( @@ -470,10 +471,7 @@ impl DeriveTrait { fn consider_edge_comp(&self) -> EdgePredicate { match self { DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, - _ => |kind| match kind { - EdgeKind::BaseMember | EdgeKind::Field => true, - _ => false, - }, + _ => |kind| matches!(kind, EdgeKind::BaseMember | EdgeKind::Field), } } @@ -498,53 +496,35 @@ impl DeriveTrait { fn can_derive_large_array(&self, ctx: &BindgenContext) -> bool { if ctx.options().rust_features().larger_arrays { - match self { - DeriveTrait::Default => false, - _ => true, - } + !matches!(self, DeriveTrait::Default) } else { - match self { - DeriveTrait::Copy => true, - _ => false, - } + matches!(self, DeriveTrait::Copy) } } fn can_derive_union(&self) -> bool { - match self { - DeriveTrait::Copy => true, - _ => false, - } + matches!(self, DeriveTrait::Copy) } fn can_derive_compound_with_destructor(&self) -> bool { - match self { - DeriveTrait::Copy => false, - _ => true, - } + !matches!(self, DeriveTrait::Copy) } fn can_derive_compound_with_vtable(&self) -> bool { - match self { - DeriveTrait::Default => false, - _ => true, - } + !matches!(self, DeriveTrait::Default) } fn can_derive_compound_forward_decl(&self) -> bool { - match self { - DeriveTrait::Copy | DeriveTrait::Debug => true, - _ => false, - } + matches!(self, DeriveTrait::Copy | DeriveTrait::Debug) } fn can_derive_incomplete_array(&self) -> bool { - match self { + !matches!( + self, DeriveTrait::Copy | - DeriveTrait::Hash | - DeriveTrait::PartialEqOrPartialOrd => false, - _ => true, - } + DeriveTrait::Hash | + DeriveTrait::PartialEqOrPartialOrd + ) } fn can_derive_fnptr(&self, f: &FunctionSig) -> CanDerive { @@ -693,10 +673,10 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { Some(ty) => { let mut can_derive = self.constrain_type(item, ty); if let CanDerive::Yes = can_derive { - if !self.derive_trait.can_derive_large_array(&self.ctx) && - ty.layout(self.ctx).map_or(false, |l| { - l.align > RUST_DERIVE_IN_ARRAY_LIMIT - }) + let is_reached_limit = + |l: Layout| l.align > RUST_DERIVE_IN_ARRAY_LIMIT; + if !self.derive_trait.can_derive_large_array(self.ctx) && + ty.layout(self.ctx).map_or(false, is_reached_limit) { // We have to be conservative: the struct *could* have enough // padding that we emit an array that is longer than diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 5fa22e3..74fd73d 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -41,16 +41,16 @@ pub struct HasDestructorAnalysis<'ctx> { impl<'ctx> HasDestructorAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - match kind { - // These are the only edges that can affect whether a type has a - // destructor or not. + // These are the only edges that can affect whether a type has a + // destructor or not. + matches!( + kind, EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::Field | - EdgeKind::TemplateArgument | - EdgeKind::TemplateDeclaration => true, - _ => false, - } + EdgeKind::BaseMember | + EdgeKind::Field | + EdgeKind::TemplateArgument | + EdgeKind::TemplateDeclaration + ) } fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult { diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index 7f5f911..8ac47a6 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -79,14 +79,14 @@ pub struct HasVtableAnalysis<'ctx> { impl<'ctx> HasVtableAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - match kind { - // These are the only edges that can affect whether a type has a - // vtable or not. + // These are the only edges that can affect whether a type has a + // vtable or not. + matches!( + kind, EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::TemplateDeclaration => true, - _ => false, - } + EdgeKind::BaseMember | + EdgeKind::TemplateDeclaration + ) } fn insert<Id: Into<ItemId>>( diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs index ec4d20f..eb9a1c0 100644 --- a/src/ir/analysis/mod.rs +++ b/src/ir/analysis/mod.rs @@ -184,7 +184,7 @@ where let mut dependencies = HashMap::default(); for &item in ctx.allowlisted_items() { - dependencies.entry(item).or_insert(vec![]); + dependencies.entry(item).or_insert_with(Vec::new); { // We reverse our natural IR graph edges to find dependencies @@ -197,7 +197,7 @@ where { dependencies .entry(sub_item) - .or_insert(vec![]) + .or_insert_with(Vec::new) .push(item); } }, diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs index a3ef753..251c374 100644 --- a/src/ir/analysis/sizedness.rs +++ b/src/ir/analysis/sizedness.rs @@ -112,17 +112,17 @@ pub struct SizednessAnalysis<'ctx> { impl<'ctx> SizednessAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - match kind { - // These are the only edges that can affect whether a type is - // zero-sized or not. + // These are the only edges that can affect whether a type is + // zero-sized or not. + matches!( + kind, EdgeKind::TemplateArgument | - EdgeKind::TemplateParameterDefinition | - EdgeKind::TemplateDeclaration | - EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::Field => true, - _ => false, - } + EdgeKind::TemplateParameterDefinition | + EdgeKind::TemplateDeclaration | + EdgeKind::TypeReference | + EdgeKind::BaseMember | + EdgeKind::Field + ) } /// Insert an incremental result, and return whether this updated our diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index c2f18b1..e88b774 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -239,7 +239,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { let args = instantiation .template_arguments() - .into_iter() + .iter() .map(|a| { a.into_resolver() .through_type_refs() @@ -399,8 +399,8 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { .collect(); for item in allowlisted_and_blocklisted_items { - dependencies.entry(item).or_insert(vec![]); - used.entry(item).or_insert(Some(ItemSet::new())); + dependencies.entry(item).or_insert_with(Vec::new); + used.entry(item).or_insert_with(|| Some(ItemSet::new())); { // We reverse our natural IR graph edges to find dependencies @@ -408,10 +408,11 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { item.trace( ctx, &mut |sub_item: ItemId, _| { - used.entry(sub_item).or_insert(Some(ItemSet::new())); + used.entry(sub_item) + .or_insert_with(|| Some(ItemSet::new())); dependencies .entry(sub_item) - .or_insert(vec![]) + .or_insert_with(Vec::new) .push(item); }, &(), @@ -421,39 +422,42 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // Additionally, whether a template instantiation's template // arguments are used depends on whether the template declaration's // generic template parameters are used. - ctx.resolve_item(item).as_type().map(|ty| match ty.kind() { - &TypeKind::TemplateInstantiation(ref inst) => { - let decl = ctx.resolve_type(inst.template_definition()); - let args = inst.template_arguments(); - - // Although template definitions should always have - // template parameters, there is a single exception: - // opaque templates. Hence the unwrap_or. - let params = decl.self_template_params(ctx); - - for (arg, param) in args.iter().zip(params.iter()) { - let arg = arg - .into_resolver() - .through_type_aliases() - .through_type_refs() - .resolve(ctx) - .id(); - - let param = param - .into_resolver() - .through_type_aliases() - .through_type_refs() - .resolve(ctx) - .id(); - - used.entry(arg).or_insert(Some(ItemSet::new())); - used.entry(param).or_insert(Some(ItemSet::new())); - - dependencies.entry(arg).or_insert(vec![]).push(param); - } + let item_kind = + ctx.resolve_item(item).as_type().map(|ty| ty.kind()); + if let Some(&TypeKind::TemplateInstantiation(ref inst)) = item_kind + { + let decl = ctx.resolve_type(inst.template_definition()); + let args = inst.template_arguments(); + + // Although template definitions should always have + // template parameters, there is a single exception: + // opaque templates. Hence the unwrap_or. + let params = decl.self_template_params(ctx); + + for (arg, param) in args.iter().zip(params.iter()) { + let arg = arg + .into_resolver() + .through_type_aliases() + .through_type_refs() + .resolve(ctx) + .id(); + + let param = param + .into_resolver() + .through_type_aliases() + .through_type_refs() + .resolve(ctx) + .id(); + + used.entry(arg).or_insert_with(|| Some(ItemSet::new())); + used.entry(param).or_insert_with(|| Some(ItemSet::new())); + + dependencies + .entry(arg) + .or_insert_with(Vec::new) + .push(param); } - _ => {} - }); + } } if cfg!(feature = "testing_only_extra_assertions") { @@ -482,10 +486,10 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { } UsedTemplateParameters { - ctx: ctx, - used: used, - dependencies: dependencies, - allowlisted_items: allowlisted_items, + ctx, + used, + dependencies, + allowlisted_items, } } diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs index 12664f6..9bcda50 100644 --- a/src/ir/annotations.rs +++ b/src/ir/annotations.rs @@ -25,7 +25,7 @@ pub enum FieldAccessorKind { /// documentation: /// /// http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html -#[derive(Clone, PartialEq, Debug)] +#[derive(Default, Clone, PartialEq, Debug)] pub struct Annotations { /// Whether this item is marked as opaque. Only applies to types. opaque: bool, @@ -42,6 +42,8 @@ pub struct Annotations { disallow_debug: bool, /// Manually disable deriving/implement default on this type. disallow_default: bool, + /// Whether to add a #[must_use] annotation to this type. + must_use_type: bool, /// Whether fields should be marked as private or not. You can set this on /// structs (it will apply to all the fields), or individual fields. private_fields: Option<bool>, @@ -75,23 +77,6 @@ fn parse_accessor(s: &str) -> FieldAccessorKind { } } -impl Default for Annotations { - fn default() -> Self { - Annotations { - opaque: false, - hide: false, - use_instead_of: None, - disallow_copy: false, - disallow_debug: false, - disallow_default: false, - private_fields: None, - accessor_kind: None, - constify_enum_variant: false, - derives: vec![], - } - } -} - impl Annotations { /// Construct new annotations for the given cursor and its bindgen comments /// (if any). @@ -140,7 +125,7 @@ impl Annotations { /// /// That is, code for `Foo` is used to generate `Bar`. pub fn use_instead_of(&self) -> Option<&[String]> { - self.use_instead_of.as_ref().map(|s| &**s) + self.use_instead_of.as_deref() } /// The list of derives that have been specified in this annotation. @@ -163,6 +148,11 @@ impl Annotations { self.disallow_default } + /// Should this type get a `#[must_use]` annotation? + pub fn must_use_type(&self) -> bool { + self.must_use_type + } + /// Should the fields be private? pub fn private_fields(&self) -> Option<bool> { self.private_fields @@ -190,6 +180,7 @@ impl Annotations { "nocopy" => self.disallow_copy = true, "nodebug" => self.disallow_debug = true, "nodefault" => self.disallow_default = true, + "mustusetype" => self.must_use_type = true, "replaces" => { self.use_instead_of = Some( attr.value.split("::").map(Into::into).collect(), diff --git a/src/ir/comment.rs b/src/ir/comment.rs index 4ebe19a..c96e3eb 100644 --- a/src/ir/comment.rs +++ b/src/ir/comment.rs @@ -1,7 +1,5 @@ //! Utilities for manipulating C/C++ comments. -use std::iter; - /// The type of a comment. #[derive(Debug, PartialEq, Eq)] enum Kind { @@ -15,7 +13,7 @@ enum Kind { /// Preprocesses a C/C++ comment so that it is a valid Rust comment. pub fn preprocess(comment: &str, indent: usize) -> String { - match self::kind(&comment) { + match self::kind(comment) { Some(Kind::SingleLines) => preprocess_single_lines(comment, indent), Some(Kind::MultiLine) => preprocess_multi_line(comment, indent), None => comment.to_owned(), @@ -35,7 +33,7 @@ fn kind(comment: &str) -> Option<Kind> { fn make_indent(indent: usize) -> String { const RUST_INDENTATION: usize = 4; - iter::repeat(' ').take(indent * RUST_INDENTATION).collect() + " ".repeat(indent * RUST_INDENTATION) } /// Preprocesses multiple single line comments. diff --git a/src/ir/comp.rs b/src/ir/comp.rs index e554f9a..a221e52 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -111,11 +111,10 @@ impl Method { /// Is this a virtual method? pub fn is_virtual(&self) -> bool { - match self.kind { - MethodKind::Virtual { .. } | - MethodKind::VirtualDestructor { .. } => true, - _ => false, - } + matches!( + self.kind, + MethodKind::Virtual { .. } | MethodKind::VirtualDestructor { .. } + ) } /// Is this a static method? @@ -630,7 +629,7 @@ where bitfield_unit_count, unit_size_in_bits, unit_align, - mem::replace(&mut bitfields_in_unit, vec![]), + mem::take(&mut bitfields_in_unit), packed, ); @@ -639,15 +638,12 @@ where offset = 0; unit_align = 0; } - } else { - if offset != 0 && - (bitfield_width == 0 || - (offset & (bitfield_align * 8 - 1)) + - bitfield_width > - bitfield_size * 8) - { - offset = align_to(offset, bitfield_align * 8); - } + } else if offset != 0 && + (bitfield_width == 0 || + (offset & (bitfield_align * 8 - 1)) + bitfield_width > + bitfield_size * 8) + { + offset = align_to(offset, bitfield_align * 8); } } @@ -706,24 +702,24 @@ where /// after. #[derive(Debug)] enum CompFields { - BeforeComputingBitfieldUnits(Vec<RawField>), - AfterComputingBitfieldUnits { + Before(Vec<RawField>), + After { fields: Vec<Field>, has_bitfield_units: bool, }, - ErrorComputingBitfieldUnits, + Error, } impl Default for CompFields { fn default() -> CompFields { - CompFields::BeforeComputingBitfieldUnits(vec![]) + CompFields::Before(vec![]) } } impl CompFields { fn append_raw_field(&mut self, raw: RawField) { match *self { - CompFields::BeforeComputingBitfieldUnits(ref mut raws) => { + CompFields::Before(ref mut raws) => { raws.push(raw); } _ => { @@ -736,9 +732,7 @@ impl CompFields { fn compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool) { let raws = match *self { - CompFields::BeforeComputingBitfieldUnits(ref mut raws) => { - mem::replace(raws, vec![]) - } + CompFields::Before(ref mut raws) => mem::take(raws), _ => { panic!("Already computed bitfield units"); } @@ -748,25 +742,23 @@ impl CompFields { match result { Ok((fields, has_bitfield_units)) => { - *self = CompFields::AfterComputingBitfieldUnits { + *self = CompFields::After { fields, has_bitfield_units, }; } Err(()) => { - *self = CompFields::ErrorComputingBitfieldUnits; + *self = CompFields::Error; } } } fn deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method]) { let fields = match *self { - CompFields::AfterComputingBitfieldUnits { - ref mut fields, .. - } => fields, + CompFields::After { ref mut fields, .. } => fields, // Nothing to do here. - CompFields::ErrorComputingBitfieldUnits => return, - CompFields::BeforeComputingBitfieldUnits(_) => { + CompFields::Error => return, + CompFields::Before(_) => { panic!("Not yet computed bitfield units."); } }; @@ -778,7 +770,7 @@ impl CompFields { ) -> bool { methods.iter().any(|method| { let method_name = ctx.resolve_func(method.signature()).name(); - method_name == name || ctx.rust_mangle(&method_name) == name + method_name == name || ctx.rust_mangle(method_name) == name }) } @@ -820,7 +812,7 @@ impl CompFields { for field in fields.iter_mut() { match *field { Field::DataMember(FieldData { ref mut name, .. }) => { - if let Some(_) = *name { + if name.is_some() { continue; } @@ -858,13 +850,13 @@ impl Trace for CompFields { T: Tracer, { match *self { - CompFields::ErrorComputingBitfieldUnits => {} - CompFields::BeforeComputingBitfieldUnits(ref fields) => { + CompFields::Error => {} + CompFields::Before(ref fields) => { for f in fields { tracer.visit_kind(f.ty().into(), EdgeKind::Field); } } - CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { + CompFields::After { ref fields, .. } => { for f in fields { f.trace(context, tracer, &()); } @@ -900,7 +892,7 @@ pub struct FieldData { impl FieldMethods for FieldData { fn name(&self) -> Option<&str> { - self.name.as_ref().map(|n| &**n) + self.name.as_deref() } fn ty(&self) -> TypeId { @@ -908,7 +900,7 @@ impl FieldMethods for FieldData { } fn comment(&self) -> Option<&str> { - self.comment.as_ref().map(|c| &**c) + self.comment.as_deref() } fn bitfield_width(&self) -> Option<u32> { @@ -1131,11 +1123,9 @@ impl CompInfo { /// Get this type's set of fields. pub fn fields(&self) -> &[Field] { match self.fields { - CompFields::ErrorComputingBitfieldUnits => &[], - CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { - fields - } - CompFields::BeforeComputingBitfieldUnits(..) => { + CompFields::Error => &[], + CompFields::After { ref fields, .. } => fields, + CompFields::Before(..) => { panic!("Should always have computed bitfield units first"); } } @@ -1143,13 +1133,9 @@ impl CompInfo { fn has_fields(&self) -> bool { match self.fields { - CompFields::ErrorComputingBitfieldUnits => false, - CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { - !fields.is_empty() - } - CompFields::BeforeComputingBitfieldUnits(ref raw_fields) => { - !raw_fields.is_empty() - } + CompFields::Error => false, + CompFields::After { ref fields, .. } => !fields.is_empty(), + CompFields::Before(ref raw_fields) => !raw_fields.is_empty(), } } @@ -1159,15 +1145,15 @@ impl CompInfo { mut callback: impl FnMut(Layout), ) { match self.fields { - CompFields::ErrorComputingBitfieldUnits => return, - CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { + CompFields::Error => {} + CompFields::After { ref fields, .. } => { for field in fields.iter() { if let Some(layout) = field.layout(ctx) { callback(layout); } } } - CompFields::BeforeComputingBitfieldUnits(ref raw_fields) => { + CompFields::Before(ref raw_fields) => { for field in raw_fields.iter() { let field_ty = ctx.resolve_type(field.0.ty); if let Some(layout) = field_ty.layout(ctx) { @@ -1180,12 +1166,11 @@ impl CompInfo { fn has_bitfields(&self) -> bool { match self.fields { - CompFields::ErrorComputingBitfieldUnits => false, - CompFields::AfterComputingBitfieldUnits { - has_bitfield_units, - .. + CompFields::Error => false, + CompFields::After { + has_bitfield_units, .. } => has_bitfield_units, - CompFields::BeforeComputingBitfieldUnits(_) => { + CompFields::Before(_) => { panic!("Should always have computed bitfield units first"); } } @@ -1408,21 +1393,26 @@ impl CompInfo { let inner = Item::parse(cur, Some(potential_id), ctx) .expect("Inner ClassDecl"); - let inner = inner.expect_type_id(ctx); + // If we avoided recursion parsing this type (in + // `Item::from_ty_with_id()`), then this might not be a + // valid type ID, so check and gracefully handle this. + if ctx.resolve_item_fallible(inner).is_some() { + let inner = inner.expect_type_id(ctx); - ci.inner_types.push(inner); + ci.inner_types.push(inner); - // A declaration of an union or a struct without name could - // also be an unnamed field, unfortunately. - if cur.spelling().is_empty() && - cur.kind() != CXCursor_EnumDecl - { - let ty = cur.cur_type(); - let public = cur.public_accessible(); - let offset = cur.offset_of_field().ok(); + // A declaration of an union or a struct without name + // could also be an unnamed field, unfortunately. + if cur.spelling().is_empty() && + cur.kind() != CXCursor_EnumDecl + { + let ty = cur.cur_type(); + let public = cur.public_accessible(); + let offset = cur.offset_of_field().ok(); - maybe_anonymous_struct_field = - Some((inner, ty, public, offset)); + maybe_anonymous_struct_field = + Some((inner, ty, public, offset)); + } } } CXCursor_PackedAttr => { @@ -1771,7 +1761,7 @@ impl IsOpaque for CompInfo { // is a type parameter), then we can't compute bitfield units. We are // left with no choice but to make the whole struct opaque, or else we // might generate structs with incorrect sizes and alignments. - if let CompFields::ErrorComputingBitfieldUnits = self.fields { + if let CompFields::Error = self.fields { return true; } diff --git a/src/ir/context.rs b/src/ir/context.rs index 72ce06b..a9e19fb 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -299,7 +299,7 @@ where /// types. #[derive(Eq, PartialEq, Hash, Debug)] enum TypeKey { - USR(String), + Usr(String), Declaration(Cursor), } @@ -640,7 +640,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Get the user-provided callbacks by reference, if any. pub fn parse_callbacks(&self) -> Option<&dyn ParseCallbacks> { - self.options().parse_callbacks.as_ref().map(|t| &**t) + self.options().parse_callbacks.as_deref() } /// Add another path to the set of included files. @@ -702,8 +702,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Unnamed items can have an USR, but they can't be referenced from // other sites explicitly and the USR can match if the unnamed items are // nested, so don't bother tracking them. - if is_type && !is_template_instantiation && declaration.is_some() { - let mut declaration = declaration.unwrap(); + if !is_type || is_template_instantiation { + return; + } + if let Some(mut declaration) = declaration { if !declaration.is_valid() { if let Some(location) = location { if location.is_template_like() { @@ -732,7 +734,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let key = if is_unnamed { TypeKey::Declaration(declaration) } else if let Some(usr) = declaration.usr() { - TypeKey::USR(usr) + TypeKey::Usr(usr) } else { warn!( "Valid declaration with no USR: {:?}, {:?}", @@ -829,31 +831,32 @@ If you encounter an error missing from this list, please file an issue or a PR!" // TODO: Move all this syntax crap to other part of the code. /// Mangles a name so it doesn't conflict with any keyword. + #[rustfmt::skip] pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> { - if name.contains("@") || - name.contains("?") || - name.contains("$") || - match name { + if name.contains('@') || + name.contains('?') || + name.contains('$') || + matches!( + name, "abstract" | "alignof" | "as" | "async" | "become" | - "box" | "break" | "const" | "continue" | "crate" | "do" | - "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" | - "unsafe" | "unsized" | "use" | "virtual" | "where" | - "while" | "yield" | "str" | "bool" | "f32" | "f64" | - "usize" | "isize" | "u128" | "i128" | "u64" | "i64" | - "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_" => true, - _ => false, - } + "box" | "break" | "const" | "continue" | "crate" | "do" | + "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" | "try" | "type" | "typeof" | + "unsafe" | "unsized" | "use" | "virtual" | "where" | + "while" | "yield" | "str" | "bool" | "f32" | "f64" | + "usize" | "isize" | "u128" | "i128" | "u64" | "i64" | + "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_" + ) { let mut s = name.to_owned(); s = s.replace("@", "_"); s = s.replace("?", "_"); s = s.replace("$", "_"); - s.push_str("_"); + s.push('_'); return Cow::Owned(s); } Cow::Borrowed(name) @@ -903,11 +906,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" None => continue, }; - match *ty.kind() { - TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => { - typerefs.push((id, ty.clone(), loc, parent_id)); - } - _ => {} + if let TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) = + *ty.kind() + { + typerefs.push((id, *ty, loc, parent_id)); }; } typerefs @@ -978,7 +980,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" assert!(self.collected_typerefs()); let need_bitfield_allocation = - mem::replace(&mut self.need_bitfield_allocation, vec![]); + mem::take(&mut self.need_bitfield_allocation); for id in need_bitfield_allocation { self.with_loaned_item(id, |ctx, item| { let ty = item.kind_mut().as_type_mut().unwrap(); @@ -1121,7 +1123,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" .ancestors(immut_self) .find(|id| immut_self.resolve_item(*id).is_module()) }; - let new_module = new_module.unwrap_or(self.root_module.into()); + let new_module = + new_module.unwrap_or_else(|| self.root_module.into()); if new_module == old_module { // Already in the correct module. @@ -1329,12 +1332,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" // any sense of template parameter usage, and you're on your own. let mut used_params = HashMap::default(); for &id in self.allowlisted_items() { - used_params.entry(id).or_insert( + used_params.entry(id).or_insert_with(|| { id.self_template_params(self) .into_iter() .map(|p| p.into()) - .collect(), - ); + .collect() + }); } self.used_template_parameters = Some(used_params); } @@ -1420,7 +1423,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" fn build_root_module(id: ItemId) -> Item { let module = Module::new(Some("root".into()), ModuleKind::Normal); - Item::new(id, None, None, id, ItemKind::Module(module)) + Item::new(id, None, None, id, ItemKind::Module(module), None) } /// Get the root module. @@ -1730,6 +1733,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(sub_ty), + Some(child.location()), ); // Bypass all the validations in add_item explicitly. @@ -1794,6 +1798,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(ty), + Some(location.location()), ); // Bypass all the validations in add_item explicitly. @@ -1815,7 +1820,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_else(|| { decl.cursor() .usr() - .and_then(|usr| self.types.get(&TypeKey::USR(usr))) + .and_then(|usr| self.types.get(&TypeKey::Usr(usr))) }) .cloned() } @@ -1848,32 +1853,32 @@ If you encounter an error missing from this list, please file an issue or a PR!" // of it, or // * we have already parsed and resolved this type, and // there's nothing left to do. - if decl.cursor().is_template_like() && - *ty != decl.cursor().cur_type() && - location.is_some() - { - let location = location.unwrap(); - - // For specialized type aliases, there's no way to get the - // template parameters as of this writing (for a struct - // specialization we wouldn't be in this branch anyway). - // - // Explicitly return `None` if there aren't any - // unspecialized parameters (contains any `TypeRef`) so we - // resolve the canonical type if there is one and it's - // exposed. - // - // This is _tricky_, I know :( - if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl && - !location.contains_cursor(CXCursor_TypeRef) && - ty.canonical_type().is_valid_and_exposed() + if let Some(location) = location { + if decl.cursor().is_template_like() && + *ty != decl.cursor().cur_type() { - return None; - } + // For specialized type aliases, there's no way to get the + // template parameters as of this writing (for a struct + // specialization we wouldn't be in this branch anyway). + // + // Explicitly return `None` if there aren't any + // unspecialized parameters (contains any `TypeRef`) so we + // resolve the canonical type if there is one and it's + // exposed. + // + // This is _tricky_, I know :( + if decl.cursor().kind() == + CXCursor_TypeAliasTemplateDecl && + !location.contains_cursor(CXCursor_TypeRef) && + ty.canonical_type().is_valid_and_exposed() + { + return None; + } - return self - .instantiate_template(with_id, id, ty, location) - .or_else(|| Some(id)); + return self + .instantiate_template(with_id, id, ty, location) + .or(Some(id)); + } } return Some(self.build_ty_wrapper(with_id, id, parent_id, ty)); @@ -1927,14 +1932,16 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) -> TypeId { let spelling = ty.spelling(); let layout = ty.fallible_layout(self).ok(); + let location = ty.declaration().location(); let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let item = Item::new( with_id, None, None, - parent_id.unwrap_or(self.current_module.into()), + parent_id.unwrap_or_else(|| self.current_module.into()), ItemKind::Type(ty), + Some(location), ); self.add_builtin_item(item); with_id.as_type_id_unchecked() @@ -1995,6 +2002,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout(self).ok(); + let location = ty.declaration().location(); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = self.next_item_id(); let item = Item::new( @@ -2003,6 +2011,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.root_module.into(), ItemKind::Type(ty), + Some(location), ); self.add_builtin_item(item); Some(id.as_type_id_unchecked()) @@ -2074,10 +2083,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" id: Id, ) -> bool { let id = id.into(); - match self.replacements.get(path) { - Some(replaced_by) if *replaced_by != id => true, - _ => false, - } + matches!(self.replacements.get(path), Some(replaced_by) if *replaced_by != id) } /// Is the type with the given `name` marked as opaque? @@ -2112,11 +2118,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" module_name = Some(spelling) } - let tokens = cursor.tokens(); - let mut iter = tokens.iter(); let mut kind = ModuleKind::Normal; let mut found_namespace_keyword = false; - while let Some(token) = iter.next() { + for token in cursor.tokens().iter() { match token.spelling() { b"inline" => { assert!(!found_namespace_keyword); @@ -2196,6 +2200,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Module(module), + Some(cursor.location()), ); let module_id = module.id().as_module_id_unchecked(); @@ -2243,11 +2248,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" assert!(self.in_codegen_phase()); assert!(self.current_module == self.root_module); - let cb = match self.options.parse_callbacks { - Some(ref cb) => cb, - None => return CanDerive::No, - }; - *self .blocklisted_types_implement_traits .borrow_mut() @@ -2257,8 +2257,27 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_insert_with(|| { item.expect_type() .name() - .and_then(|name| { - cb.blocklisted_type_implements_trait(name, derive_trait) + .and_then(|name| match self.options.parse_callbacks { + Some(ref cb) => cb.blocklisted_type_implements_trait( + name, + derive_trait, + ), + // Sized integer types from <stdint.h> get mapped to Rust primitive + // types regardless of whether they are blocklisted, so ensure that + // standard traits are considered derivable for them too. + None => match name { + "int8_t" | "uint8_t" | "int16_t" | "uint16_t" | + "int32_t" | "uint32_t" | "int64_t" | + "uint64_t" | "uintptr_t" | "intptr_t" | + "ptrdiff_t" => Some(CanDerive::Yes), + "size_t" if self.options.size_t_is_usize => { + Some(CanDerive::Yes) + } + "ssize_t" if self.options.size_t_is_usize => { + Some(CanDerive::Yes) + } + _ => Some(CanDerive::No), + }, }) .unwrap_or(CanDerive::No) }) @@ -2399,7 +2418,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let codegen_items = if self.options().allowlist_recursively { AllowlistedItemsTraversal::new( self, - roots.clone(), + roots, traversal::codegen_edges, ) .collect::<ItemSet>() @@ -2663,6 +2682,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" let name = item.path_for_allowlisting(self)[1..].join("::"); self.options().no_hash_types.matches(&name) } + + /// Check if `--must-use-type` flag is enabled for this item. + pub fn must_use_type_by_name(&self, item: &Item) -> bool { + let name = item.path_for_allowlisting(self)[1..].join("::"); + self.options().must_use_types.matches(&name) + } } /// A builder struct for configuring item resolution options. @@ -2694,7 +2719,7 @@ impl ItemResolver { pub fn new<Id: Into<ItemId>>(id: Id) -> ItemResolver { let id = id.into(); ItemResolver { - id: id, + id, through_type_refs: false, through_type_aliases: false, } @@ -2717,8 +2742,16 @@ impl ItemResolver { assert!(ctx.collected_typerefs()); let mut id = self.id; + let mut seen_ids = HashSet::default(); loop { let item = ctx.resolve_item(id); + + // Detect cycles and bail out. These can happen in certain cases + // involving incomplete qualified dependent types (#2085). + if !seen_ids.insert(id) { + return item; + } + let ty_kind = item.as_type().map(|t| t.kind()); match ty_kind { Some(&TypeKind::ResolvedTypeRef(next_id)) @@ -2753,7 +2786,7 @@ impl PartialType { /// Construct a new `PartialType`. pub fn new(decl: Cursor, id: ItemId) -> PartialType { // assert!(decl == decl.canonical()); - PartialType { decl: decl, id: id } + PartialType { decl, id } } /// The cursor pointing to this partial type's declaration location. diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index 15d4136..97455c9 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -86,7 +86,7 @@ impl Enum { } else { Some(type_name) }; - let type_name = type_name.as_ref().map(String::as_str); + let type_name = type_name.as_deref(); let definition = declaration.definition().unwrap_or(declaration); definition.visit(|cursor| { @@ -286,7 +286,7 @@ impl EnumVariant { /// Get this variant's documentation. pub fn comment(&self) -> Option<&str> { - self.comment.as_ref().map(|s| &**s) + self.comment.as_deref() } /// Returns whether this variant should be enforced to be a constant by code diff --git a/src/ir/function.rs b/src/ir/function.rs index 661ee59..a3a2bbf 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -123,7 +123,7 @@ impl Function { /// Get this function's name. pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_ref().map(|n| &**n) + self.mangled_name.as_deref() } /// Get this function's signature type. @@ -187,10 +187,7 @@ pub enum Abi { impl Abi { /// Returns whether this Abi is known or not. fn is_unknown(&self) -> bool { - match *self { - Abi::Unknown(..) => true, - _ => false, - } + matches!(*self, Abi::Unknown(..)) } } @@ -340,7 +337,7 @@ fn args_from_ty_and_cursor( }); let cursor = arg_cur.unwrap_or(*cursor); - let ty = arg_ty.unwrap_or(cursor.cur_type()); + let ty = arg_ty.unwrap_or_else(|| cursor.cur_type()); (name, Item::from_ty_or_ref(ty, cursor, None, ctx)) }) .collect() @@ -360,7 +357,7 @@ impl FunctionSig { argument_types, is_variadic, must_use, - abi: abi, + abi, } } @@ -411,7 +408,7 @@ impl FunctionSig { CXCursor_CXXMethod | CXCursor_ObjCInstanceMethodDecl | CXCursor_ObjCClassMethodDecl => { - args_from_ty_and_cursor(&ty, &cursor, ctx) + args_from_ty_and_cursor(ty, &cursor, ctx) } _ => { // For non-CXCursor_FunctionDecl, visiting the cursor's children @@ -434,7 +431,7 @@ impl FunctionSig { // right AST for functions tagged as stdcall and such... // // https://bugs.llvm.org/show_bug.cgi?id=45919 - args_from_ty_and_cursor(&ty, &cursor, ctx) + args_from_ty_and_cursor(ty, &cursor, ctx) } else { args } @@ -522,7 +519,7 @@ impl FunctionSig { warn!("Unknown calling convention: {:?}", call_conv); } - Ok(Self::new(ret.into(), args, ty.is_variadic(), must_use, abi)) + Ok(Self::new(ret, args, ty.is_variadic(), must_use, abi)) } /// Get this function signature's return type. @@ -567,10 +564,7 @@ impl FunctionSig { return false; } - match self.abi { - Abi::C | Abi::Unknown(..) => true, - _ => false, - } + matches!(self.abi, Abi::C | Abi::Unknown(..)) } } diff --git a/src/ir/item.rs b/src/ir/item.rs index 4e0ba80..8692575 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -417,6 +417,8 @@ pub struct Item { parent_id: ItemId, /// The item kind. kind: ItemKind, + /// The source location of the item. + location: Option<clang::SourceLocation>, } impl AsRef<ItemId> for Item { @@ -433,18 +435,20 @@ impl Item { annotations: Option<Annotations>, parent_id: ItemId, kind: ItemKind, + location: Option<clang::SourceLocation>, ) -> Self { debug_assert!(id != parent_id || kind.is_module()); Item { - id: id, + id, local_id: LazyCell::new(), next_child_local_id: Cell::new(1), canonical_name: LazyCell::new(), path_for_allowlisting: LazyCell::new(), - parent_id: parent_id, - comment: comment, + parent_id, + comment, annotations: annotations.unwrap_or_default(), - kind: kind, + kind, + location, } } @@ -454,10 +458,15 @@ impl Item { ty: &clang::Type, ctx: &mut BindgenContext, ) -> TypeId { + let location = ty.declaration().location(); let ty = Opaque::from_clang_ty(ty, ctx); let kind = ItemKind::Type(ty); let parent = ctx.root_module().into(); - ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None); + ctx.add_item( + Item::new(with_id, None, None, parent, kind, Some(location)), + None, + None, + ); with_id.as_type_id_unchecked() } @@ -612,10 +621,7 @@ impl Item { /// Is this item a module? pub fn is_module(&self) -> bool { - match self.kind { - ItemKind::Module(..) => true, - _ => false, - } + matches!(self.kind, ItemKind::Module(..)) } /// Get this item's annotations. @@ -635,13 +641,24 @@ impl Item { return true; } + if !ctx.options().blocklisted_files.is_empty() { + if let Some(location) = &self.location { + let (file, _, _, _) = location.location(); + if let Some(filename) = file.name() { + if ctx.options().blocklisted_files.matches(&filename) { + return true; + } + } + } + } + let path = self.path_for_allowlisting(ctx); let name = path[1..].join("::"); ctx.options().blocklisted_items.matches(&name) || match self.kind { ItemKind::Type(..) => { ctx.options().blocklisted_types.matches(&name) || - ctx.is_replaced_type(&path, self.id) + ctx.is_replaced_type(path, self.id) } ItemKind::Function(..) => { ctx.options().blocklisted_functions.matches(&name) @@ -658,10 +675,7 @@ impl Item { /// Is this item a var type? pub fn is_var(&self) -> bool { - match *self.kind() { - ItemKind::Var(..) => true, - _ => false, - } + matches!(*self.kind(), ItemKind::Var(..)) } /// Take out item NameOptions @@ -722,7 +736,7 @@ impl Item { .through_type_refs() .resolve(ctx) .push_disambiguated_name(ctx, to, level + 1); - to.push_str("_"); + to.push('_'); } to.push_str(&format!("close{}", level)); } @@ -835,7 +849,7 @@ impl Item { if ctx.options().enable_cxx_namespaces { return path.last().unwrap().clone(); } - return path.join("_").to_owned(); + return path.join("_"); } let base_name = target.base_name(ctx); @@ -873,7 +887,7 @@ impl Item { // If target is anonymous we need find its first named ancestor. if target.is_anon() { - while let Some(id) = ids_iter.next() { + for id in ids_iter.by_ref() { ids.push(id); if !ctx.resolve_item(id).is_anon() { @@ -1104,7 +1118,7 @@ impl IsOpaque for Item { ); self.annotations.opaque() || self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) || - ctx.opaque_by_name(&self.path_for_allowlisting(ctx)) + ctx.opaque_by_name(self.path_for_allowlisting(ctx)) } } @@ -1114,20 +1128,16 @@ where { fn has_vtable(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx) - .map_or(false, |id| match ctx.lookup_has_vtable(id) { - HasVtableResult::No => false, - _ => true, - }) + id.as_type_id(ctx).map_or(false, |id| { + !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No) + }) } fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx) - .map_or(false, |id| match ctx.lookup_has_vtable(id) { - HasVtableResult::SelfHasVtable => true, - _ => false, - }) + id.as_type_id(ctx).map_or(false, |id| { + matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable) + }) } } @@ -1307,7 +1317,7 @@ impl ClangItemParser for Item { let id = ctx.next_item_id(); let module = ctx.root_module().into(); ctx.add_item( - Item::new(id, None, None, module, ItemKind::Type(ty)), + Item::new(id, None, None, module, ItemKind::Type(ty), None), None, None, ); @@ -1345,6 +1355,7 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::$what(item), + Some(cursor.location()), ), declaration, Some(cursor), @@ -1392,7 +1403,7 @@ impl ClangItemParser for Item { } ctx.known_semantic_parent(definition) .or(parent_id) - .unwrap_or(ctx.current_module().into()) + .unwrap_or_else(|| ctx.current_module().into()) } None => relevant_parent_id, }; @@ -1524,8 +1535,9 @@ impl ClangItemParser for Item { potential_id, None, None, - parent_id.unwrap_or(current_module.into()), + parent_id.unwrap_or_else(|| current_module.into()), ItemKind::Type(Type::new(None, None, kind, is_const)), + Some(location.location()), ), None, None, @@ -1594,8 +1606,8 @@ impl ClangItemParser for Item { } let decl = { - let decl = ty.declaration(); - decl.definition().unwrap_or(decl) + let canonical_def = ty.canonical_type().declaration().definition(); + canonical_def.unwrap_or_else(|| ty.declaration()) }; let comment = decl.raw_comment().or_else(|| location.raw_comment()); @@ -1603,7 +1615,7 @@ impl ClangItemParser for Item { Annotations::new(&decl).or_else(|| Annotations::new(&location)); if let Some(ref annotations) = annotations { - if let Some(ref replaced) = annotations.use_instead_of() { + if let Some(replaced) = annotations.use_instead_of() { ctx.replace(replaced, id); } } @@ -1657,6 +1669,7 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::Type(item), + Some(location.location()), ), declaration, Some(location), @@ -1851,11 +1864,7 @@ impl ClangItemParser for Item { clang_sys::CXChildVisit_Continue }); - if let Some(def) = definition { - def - } else { - return None; - } + definition? }; assert!(is_template_with_spelling(&definition, &ty_spelling)); @@ -1889,6 +1898,7 @@ impl ClangItemParser for Item { None, parent, ItemKind::Type(Type::named(name)), + Some(location.location()), ); ctx.add_type_param(item, definition); Some(id.as_type_id_unchecked()) @@ -1939,7 +1949,7 @@ impl ItemCanonicalPath for Item { path.push(CONSTIFIED_ENUM_MODULE_REPR_NAME.into()); } - return path; + path } fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> { @@ -1972,8 +1982,8 @@ impl<'a> NameOptions<'a> { /// Construct a new `NameOptions` pub fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self { NameOptions { - item: item, - ctx: ctx, + item, + ctx, within_namespaces: false, user_mangled: UserMangled::Yes, } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index 28a6604..6cf9113 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -64,7 +64,7 @@ impl Layout { next_align *= 2; } Layout { - size: size, + size, align: next_align / 2, packed: false, } diff --git a/src/ir/module.rs b/src/ir/module.rs index 13b7c19..d5aca94 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -32,15 +32,15 @@ impl Module { /// Construct a new `Module`. pub fn new(name: Option<String>, kind: ModuleKind) -> Self { Module { - name: name, - kind: kind, + name, + kind, children: ItemSet::new(), } } /// Get this module's name. pub fn name(&self) -> Option<&str> { - self.name.as_ref().map(|n| &**n) + self.name.as_deref() } /// Get a mutable reference to this module's children. diff --git a/src/ir/objc.rs b/src/ir/objc.rs index 91855c6..0845ad0 100644 --- a/src/ir/objc.rs +++ b/src/ir/objc.rs @@ -89,12 +89,10 @@ impl ObjCInterface { pub fn rust_name(&self) -> String { if let Some(ref cat) = self.category { format!("{}_{}", self.name(), cat) + } else if self.is_protocol { + format!("P{}", self.name()) } else { - if self.is_protocol { - format!("P{}", self.name()) - } else { - format!("I{}", self.name().to_owned()) - } + format!("I{}", self.name().to_owned()) } } @@ -149,28 +147,34 @@ impl ObjCInterface { // Gather protocols this interface conforms to let needle = format!("P{}", c.spelling()); let items_map = ctx.items(); - debug!("Interface {} conforms to {}, find the item", interface.name, needle); + debug!( + "Interface {} conforms to {}, find the item", + interface.name, needle + ); - for (id, item) in items_map - { + for (id, item) in items_map { if let Some(ty) = item.as_type() { - match *ty.kind() { - TypeKind::ObjCInterface(ref protocol) => { - if protocol.is_protocol - { - debug!("Checking protocol {}, ty.name {:?}", protocol.name, ty.name()); - if Some(needle.as_ref()) == ty.name() { - debug!("Found conforming protocol {:?}", item); - interface.conforms_to.push(id); - break; - } + if let TypeKind::ObjCInterface(ref protocol) = + *ty.kind() + { + if protocol.is_protocol { + debug!( + "Checking protocol {}, ty.name {:?}", + protocol.name, + ty.name() + ); + if Some(needle.as_ref()) == ty.name() { + debug!( + "Found conforming protocol {:?}", + item + ); + interface.conforms_to.push(id); + break; } } - _ => {} } } } - } CXCursor_ObjCInstanceMethodDecl | CXCursor_ObjCClassMethodDecl => { @@ -178,8 +182,10 @@ impl ObjCInterface { let signature = FunctionSig::from_ty(&c.cur_type(), &c, ctx) .expect("Invalid function sig"); - let is_class_method = c.kind() == CXCursor_ObjCClassMethodDecl; - let method = ObjCMethod::new(&name, signature, is_class_method); + let is_class_method = + c.kind() == CXCursor_ObjCClassMethodDecl; + let method = + ObjCMethod::new(&name, signature, is_class_method); interface.add_method(method); } CXCursor_TemplateTypeParameter => { @@ -189,7 +195,7 @@ impl ObjCInterface { CXCursor_ObjCSuperClassRef => { let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx); interface.parent_class = Some(item.into()); - }, + } _ => {} } CXChildVisit_Continue @@ -218,7 +224,7 @@ impl ObjCMethod { ObjCMethod { name: name.to_owned(), - rust_name: rust_name.to_owned(), + rust_name, signature, is_class_method, } @@ -261,7 +267,7 @@ impl ObjCMethod { .collect(); // No arguments - if args.len() == 0 && split_name.len() == 1 { + if args.is_empty() && split_name.len() == 1 { let name = &split_name[0]; return quote! { #name @@ -269,13 +275,12 @@ impl ObjCMethod { } // Check right amount of arguments - if args.len() != split_name.len() - 1 { - panic!( - "Incorrect method name or arguments for objc method, {:?} vs {:?}", - args, - split_name, - ); - } + assert!( + args.len() == split_name.len() - 1, + "Incorrect method name or arguments for objc method, {:?} vs {:?}", + args, + split_name + ); // Get arguments without type signatures to pass to `msg_send!` let mut args_without_types = vec![]; diff --git a/src/ir/template.rs b/src/ir/template.rs index b519fff..8b06748 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -134,10 +134,10 @@ pub trait TemplateParameters: Sized { where Self: ItemAncestors, { - let ancestors: Vec<_> = self.ancestors(ctx).collect(); + let mut ancestors: Vec<_> = self.ancestors(ctx).collect(); + ancestors.reverse(); ancestors .into_iter() - .rev() .flat_map(|id| id.self_template_params(ctx).into_iter()) .collect() } diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs index 430dd02..088e744 100644 --- a/src/ir/traversal.rs +++ b/src/ir/traversal.rs @@ -24,9 +24,9 @@ impl Edge { } } -impl Into<ItemId> for Edge { - fn into(self) -> ItemId { - self.to +impl From<Edge> for ItemId { + fn from(val: Edge) -> Self { + val.to } } @@ -424,10 +424,10 @@ where } ItemTraversal { - ctx: ctx, - seen: seen, - queue: queue, - predicate: predicate, + ctx, + seen, + queue, + predicate, currently_traversing: None, } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index e049ed6..d573408 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -87,23 +87,17 @@ impl Type { /// Get this type's name. pub fn name(&self) -> Option<&str> { - self.name.as_ref().map(|name| &**name) + self.name.as_deref() } /// Whether this is a block pointer type. pub fn is_block_pointer(&self) -> bool { - match self.kind { - TypeKind::BlockPointer(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::BlockPointer(..)) } /// Is this a compound type? pub fn is_comp(&self) -> bool { - match self.kind { - TypeKind::Comp(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::Comp(..)) } /// Is this a union? @@ -116,58 +110,43 @@ impl Type { /// Is this type of kind `TypeKind::TypeParam`? pub fn is_type_param(&self) -> bool { - match self.kind { - TypeKind::TypeParam => true, - _ => false, - } + matches!(self.kind, TypeKind::TypeParam) } /// Is this a template instantiation type? pub fn is_template_instantiation(&self) -> bool { - match self.kind { - TypeKind::TemplateInstantiation(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::TemplateInstantiation(..)) } /// Is this a template alias type? pub fn is_template_alias(&self) -> bool { - match self.kind { - TypeKind::TemplateAlias(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::TemplateAlias(..)) } /// Is this a function type? pub fn is_function(&self) -> bool { - match self.kind { - TypeKind::Function(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::Function(..)) } /// Is this an enum type? pub fn is_enum(&self) -> bool { - match self.kind { - TypeKind::Enum(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::Enum(..)) } /// Is this either a builtin or named type? pub fn is_builtin_or_type_param(&self) -> bool { - match self.kind { + matches!( + self.kind, TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Function(..) | - TypeKind::Array(..) | - TypeKind::Reference(..) | - TypeKind::Pointer(..) | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::TypeParam => true, - _ => false, - } + TypeKind::NullPtr | + TypeKind::Function(..) | + TypeKind::Array(..) | + TypeKind::Reference(..) | + TypeKind::Pointer(..) | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::TypeParam + ) } /// Creates a new named type, with name `name`. @@ -178,26 +157,17 @@ impl Type { /// Is this a floating point type? pub fn is_float(&self) -> bool { - match self.kind { - TypeKind::Float(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::Float(..)) } /// Is this a boolean type? pub fn is_bool(&self) -> bool { - match self.kind { - TypeKind::Int(IntKind::Bool) => true, - _ => false, - } + matches!(self.kind, TypeKind::Int(IntKind::Bool)) } /// Is this an integer type? pub fn is_integer(&self) -> bool { - match self.kind { - TypeKind::Int(..) => true, - _ => false, - } + matches!(self.kind, TypeKind::Int(..)) } /// Cast this type to an integer kind, or `None` if it is not an integer @@ -216,19 +186,15 @@ impl Type { /// Is this a reference to another type? pub fn is_type_ref(&self) -> bool { - match self.kind { - TypeKind::ResolvedTypeRef(_) | - TypeKind::UnresolvedTypeRef(_, _, _) => true, - _ => false, - } + matches!( + self.kind, + TypeKind::ResolvedTypeRef(_) | TypeKind::UnresolvedTypeRef(_, _, _) + ) } /// Is this an unresolved reference? pub fn is_unresolved_ref(&self) -> bool { - match self.kind { - TypeKind::UnresolvedTypeRef(_, _, _) => true, - _ => false, - } + matches!(self.kind, TypeKind::UnresolvedTypeRef(_, _, _)) } /// Is this a incomplete array type? @@ -278,14 +244,14 @@ impl Type { match self.kind { TypeKind::TypeParam => { let name = self.name().expect("Unnamed named type?"); - !clang::is_valid_identifier(&name) + !clang::is_valid_identifier(name) } _ => false, } } /// Takes `name`, and returns a suitable identifier representation for it. - fn sanitize_name<'a>(name: &'a str) -> Cow<'a, str> { + fn sanitize_name(name: &str) -> Cow<str> { if clang::is_valid_identifier(name) { return Cow::Borrowed(name); } @@ -300,12 +266,8 @@ impl Type { ctx: &BindgenContext, ) -> Option<Cow<'a, str>> { let name_info = match *self.kind() { - TypeKind::Pointer(inner) => { - Some((inner.into(), Cow::Borrowed("ptr"))) - } - TypeKind::Reference(inner) => { - Some((inner.into(), Cow::Borrowed("ref"))) - } + TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))), + TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))), TypeKind::Array(inner, length) => { Some((inner, format!("array{}", length).into())) } @@ -375,16 +337,16 @@ impl Type { /// There are some types we don't want to stop at when finding an opaque /// item, so we can arrive to the proper item that needs to be generated. pub fn should_be_traced_unconditionally(&self) -> bool { - match self.kind { + matches!( + self.kind, TypeKind::Comp(..) | - TypeKind::Function(..) | - TypeKind::Pointer(..) | - TypeKind::Array(..) | - TypeKind::Reference(..) | - TypeKind::TemplateInstantiation(..) | - TypeKind::ResolvedTypeRef(..) => true, - _ => false, - } + TypeKind::Function(..) | + TypeKind::Pointer(..) | + TypeKind::Array(..) | + TypeKind::Reference(..) | + TypeKind::TemplateInstantiation(..) | + TypeKind::ResolvedTypeRef(..) + ) } } @@ -791,7 +753,7 @@ impl Type { (ty.template_args().is_some() && ty_kind != CXType_Typedef) { // This is a template instantiation. - match TemplateInstantiation::from_ty(&ty, ctx) { + match TemplateInstantiation::from_ty(ty, ctx) { Some(inst) => TypeKind::TemplateInstantiation(inst), None => TypeKind::Opaque, } @@ -1120,7 +1082,16 @@ impl Type { let inner = cursor.typedef_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(inner, location, None, ctx); - TypeKind::Alias(inner) + if inner == potential_id { + warn!( + "Generating oqaque type instead of self-referential \ + typedef"); + // This can happen if we bail out of recursive situations + // within the clang parsing. + TypeKind::Opaque + } else { + TypeKind::Alias(inner) + } } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); diff --git a/src/ir/var.rs b/src/ir/var.rs index 49c4f30..cd17937 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -88,7 +88,7 @@ impl Var { /// Get this variable's mangled name. pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_ref().map(|n| &**n) + self.mangled_name.as_deref() } } @@ -282,7 +282,7 @@ impl ClangSubItemParser for Var { .parse_callbacks() .and_then(|c| c.int_macro(&name, value)) .unwrap_or_else(|| { - default_macro_constant_type(&ctx, value) + default_macro_constant_type(ctx, value) }); (TypeKind::Int(kind), VarType::Int(value)) @@ -398,11 +398,8 @@ fn parse_macro( let parser = expr::IdentifierParser::new(ctx.parsed_macros()); - match parser.macro_definition(&cexpr_tokens) { - Ok((_, (id, val))) => { - return Some((id.into(), val)); - } - _ => {} + if let Ok((_, (id, val))) = parser.macro_definition(&cexpr_tokens) { + return Some((id.into(), val)); } // Try without the last token, to workaround a libclang bug in versions @@ -89,7 +89,7 @@ type HashSet<K> = ::rustc_hash::FxHashSet<K>; pub(crate) use std::collections::hash_map::Entry; /// Default prefix for the anon fields. -pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_"; +pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_"; fn file_is_cpp(name_file: &str) -> bool { name_file.ends_with(".hpp") || @@ -308,6 +308,7 @@ impl Builder { (&self.options.blocklisted_types, "--blocklist-type"), (&self.options.blocklisted_functions, "--blocklist-function"), (&self.options.blocklisted_items, "--blocklist-item"), + (&self.options.blocklisted_files, "--blocklist-file"), (&self.options.opaque_types, "--opaque-type"), (&self.options.allowlisted_functions, "--allowlist-function"), (&self.options.allowlisted_types, "--allowlist-type"), @@ -317,6 +318,7 @@ impl Builder { (&self.options.no_debug_types, "--no-debug"), (&self.options.no_default_types, "--no-default"), (&self.options.no_hash_types, "--no-hash"), + (&self.options.must_use_types, "--must-use-type"), ]; for (set, flag) in regex_sets { @@ -820,6 +822,13 @@ impl Builder { self } + /// Hide any contents of the given file from the generated bindings, + /// regardless of whether it's a type, function, module etc. + pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.blocklisted_files.insert(arg); + self + } + /// Treat the given type as opaque in the generated bindings. Regular /// expressions are supported. /// @@ -1588,6 +1597,13 @@ impl Builder { self } + /// Add `#[must_use]` for the given type. Regular + /// expressions are supported. + pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder { + self.options.must_use_types.insert(arg.into()); + self + } + /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut) pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { self.options.array_pointers_in_arguments = doit; @@ -1661,6 +1677,10 @@ struct BindgenOptions { /// blocklisted and should not appear in the generated code. blocklisted_items: RegexSet, + /// The set of files whose contents should be blocklisted and should not + /// appear in the generated code. + blocklisted_files: RegexSet, + /// The set of types that should be treated as opaque structures in the /// generated code. opaque_types: RegexSet, @@ -1928,6 +1948,9 @@ struct BindgenOptions { /// The set of types that we should not derive `Hash` for. no_hash_types: RegexSet, + /// The set of types that we should be annotated with `#[must_use]`. + must_use_types: RegexSet, + /// Decide if C arrays should be regular pointers in rust or array pointers array_pointers_in_arguments: bool, @@ -1971,6 +1994,7 @@ impl BindgenOptions { &mut self.blocklisted_types, &mut self.blocklisted_functions, &mut self.blocklisted_items, + &mut self.blocklisted_files, &mut self.opaque_types, &mut self.bitfield_enums, &mut self.constified_enums, @@ -1986,6 +2010,7 @@ impl BindgenOptions { &mut self.no_debug_types, &mut self.no_default_types, &mut self.no_hash_types, + &mut self.must_use_types, ]; let record_matches = self.record_matches; for regex_set in &mut regex_sets { @@ -2017,6 +2042,7 @@ impl Default for BindgenOptions { blocklisted_types: Default::default(), blocklisted_functions: Default::default(), blocklisted_items: Default::default(), + blocklisted_files: Default::default(), opaque_types: Default::default(), rustfmt_path: Default::default(), depfile: Default::default(), @@ -2090,6 +2116,7 @@ impl Default for BindgenOptions { no_debug_types: Default::default(), no_default_types: Default::default(), no_hash_types: Default::default(), + must_use_types: Default::default(), array_pointers_in_arguments: false, wasm_import_module_name: None, dynamic_library_name: None, @@ -2135,7 +2162,7 @@ pub struct Bindings { module: proc_macro2::TokenStream, } -pub(crate) const HOST_TARGET: &'static str = +pub(crate) const HOST_TARGET: &str = include_str!(concat!(env!("OUT_DIR"), "/host-target.txt")); // Some architecture triplets are different between rust and libclang, see #1211 @@ -2143,7 +2170,8 @@ pub(crate) const HOST_TARGET: &'static str = fn rust_to_clang_target(rust_target: &str) -> String { if rust_target.starts_with("aarch64-apple-") { let mut clang_target = "arm64-apple-".to_owned(); - clang_target.push_str(&rust_target["aarch64-apple-".len()..]); + clang_target + .push_str(rust_target.strip_prefix("aarch64-apple-").unwrap()); return clang_target; } rust_target.to_owned() @@ -2265,10 +2293,7 @@ impl Bindings { // Whether we are working with C or C++ inputs. let is_cpp = args_are_cpp(&options.clang_args) || - options - .input_header - .as_ref() - .map_or(false, |i| file_is_cpp(&i)); + options.input_header.as_deref().map_or(false, file_is_cpp); let search_paths = if is_cpp { clang.cpp_search_paths @@ -2356,15 +2381,6 @@ impl Bindings { }) } - /// Convert these bindings into source text (with raw lines prepended). - pub fn to_string(&self) -> String { - let mut bytes = vec![]; - self.write(Box::new(&mut bytes) as Box<dyn Write>) - .expect("writing to a vec cannot fail"); - String::from_utf8(bytes) - .expect("we should only write bindings that are valid utf-8") - } - /// Write these bindings as source text to a file. pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { let file = OpenOptions::new() @@ -2379,7 +2395,7 @@ impl Bindings { /// Write these bindings as source text to the given `Write`able. pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> { if !self.options.disable_header_comment { - let version = Some("0.59.1"); + let version = Some("0.59.2"); let header = format!( "/* automatically generated by rust-bindgen {} */\n\n", version.unwrap_or("(unknown version)") @@ -2414,7 +2430,7 @@ impl Bindings { } /// Gets the rustfmt path to rustfmt the generated bindings. - fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> { + fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> { debug_assert!(self.options.rustfmt_bindings); if let Some(ref p) = self.options.rustfmt_path { return Ok(Cow::Borrowed(p)); @@ -2505,6 +2521,18 @@ impl Bindings { } } +impl std::fmt::Display for Bindings { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut bytes = vec![]; + self.write(Box::new(&mut bytes) as Box<dyn Write>) + .expect("writing to a vec cannot fail"); + f.write_str( + std::str::from_utf8(&bytes) + .expect("we should only write bindings that are valid utf-8"), + ) + } +} + /// Determines whether the given cursor is in any of the files matched by the /// options. fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { @@ -2553,7 +2581,7 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> { if context.options().emit_ast { fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { if !cur.is_builtin() { - clang::ast_dump(&cur, 0) + clang::ast_dump(cur, 0) } else { CXChildVisit_Continue } @@ -2590,26 +2618,19 @@ pub fn clang_version() -> ClangVersion { let raw_v: String = clang::extract_clang_version(); let split_v: Option<Vec<&str>> = raw_v .split_whitespace() - .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit())) - .next() + .find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit())) .map(|v| v.split('.').collect()); - match split_v { - Some(v) => { - if v.len() >= 2 { - let maybe_major = v[0].parse::<u32>(); - let maybe_minor = v[1].parse::<u32>(); - match (maybe_major, maybe_minor) { - (Ok(major), Ok(minor)) => { - return ClangVersion { - parsed: Some((major, minor)), - full: raw_v.clone(), - } - } - _ => {} - } + if let Some(v) = split_v { + if v.len() >= 2 { + let maybe_major = v[0].parse::<u32>(); + let maybe_minor = v[1].parse::<u32>(); + if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) { + return ClangVersion { + parsed: Some((major, minor)), + full: raw_v.clone(), + }; } } - None => {} }; ClangVersion { parsed: None, @@ -2635,7 +2656,7 @@ fn get_target_dependent_env_var(var: &str) -> Option<String> { /// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed /// line /// -/// When running in side a `build.rs` script, this can be used to make cargo invalidate the +/// When running inside a `build.rs` script, this can be used to make cargo invalidate the /// generated bindings whenever any of the files included from the header change: /// ``` /// use bindgen::builder; diff --git a/src/log_stubs.rs b/src/log_stubs.rs index 4af496c..8315983 100644 --- a/src/log_stubs.rs +++ b/src/log_stubs.rs @@ -1,32 +1,32 @@ #![allow(unused)] macro_rules! log { - (target: $target:expr, $lvl:expr, $($arg:tt)+) => { + (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{ let _ = $target; let _ = log!($lvl, $($arg)+); - }; + }}; ($lvl:expr, $($arg:tt)+) => {{ let _ = $lvl; let _ = format_args!($($arg)+); }}; } macro_rules! error { - (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; - ($($arg:tt)*) => { log!("", $($arg)*); }; + (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; + ($($arg:tt)+) => { log!("", $($arg)+) }; } macro_rules! warn { - (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; - ($($arg:tt)*) => { log!("", $($arg)*); }; + (target: $target:expr, $($arg:tt)*) => { log!(target: $target, "", $($arg)*) }; + ($($arg:tt)*) => { log!("", $($arg)*) }; } macro_rules! info { - (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; - ($($arg:tt)*) => { log!("", $($arg)*); }; + (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; + ($($arg:tt)+) => { log!("", $($arg)+) }; } macro_rules! debug { - (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; - ($($arg:tt)*) => { log!("", $($arg)*); }; + (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; + ($($arg:tt)+) => { log!("", $($arg)+) }; } macro_rules! trace { - (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; - ($($arg:tt)*) => { log!("", $($arg)*); }; + (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; + ($($arg:tt)+) => { log!("", $($arg)+) }; } diff --git a/src/main.rs b/src/main.rs index 1768ed8..f3398db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ fn clang_version_check() { ); if expected_version.is_some() { - assert_eq!(version.parsed, version.parsed); + // assert_eq!(version.parsed, version.parsed); } } @@ -45,9 +45,7 @@ pub fn main() { #[cfg(feature = "logging")] env_logger::init(); - let bind_args: Vec<_> = env::args().collect(); - - match builder_from_flags(bind_args.into_iter()) { + match builder_from_flags(env::args()) { Ok((builder, output, verbose)) => { clang_version_check(); let builder_result = panic::catch_unwind(|| { diff --git a/src/options.rs b/src/options.rs index c02f275..94f3047 100644 --- a/src/options.rs +++ b/src/options.rs @@ -23,7 +23,7 @@ where ); let matches = App::new("bindgen") - .version(Some("0.59.1").unwrap_or("unknown")) + .version(Some("0.59.2").unwrap_or("unknown")) .about("Generates Rust bindings from C/C++ headers.") .usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...") .args(&[ @@ -164,6 +164,14 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("blocklist-file") + .alias("blacklist-file") + .long("blocklist-file") + .help("Mark all contents of <path> as hidden.") + .value_name("path") + .takes_value(true) + .multiple(true) + .number_of_values(1), Arg::with_name("no-layout-tests") .long("no-layout-tests") .help("Avoid generating layout tests for any type."), @@ -486,6 +494,13 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("must-use-type") + .long("must-use-type") + .help("Add #[must_use] annotation to types matching <regex>.") + .value_name("regex") + .takes_value(true) + .multiple(true) + .number_of_values(1), Arg::with_name("enable-function-attribute-detection") .long("enable-function-attribute-detection") .help( @@ -623,6 +638,12 @@ where } } + if let Some(hidden_files) = matches.values_of("blocklist-file") { + for file in hidden_files { + builder = builder.blocklist_file(file); + } + } + if matches.is_present("builtins") { builder = builder.emit_builtins(); } @@ -710,7 +731,7 @@ where if let Some(what_to_generate) = matches.value_of("generate") { let mut config = CodegenConfig::empty(); - for what in what_to_generate.split(",") { + for what in what_to_generate.split(',') { match what { "functions" => config.insert(CodegenConfig::FUNCTIONS), "types" => config.insert(CodegenConfig::TYPES), @@ -943,6 +964,12 @@ where } } + if let Some(must_use_type) = matches.values_of("must-use-type") { + for regex in must_use_type { + builder = builder.must_use_type(regex); + } + } + if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") { builder = builder.dynamic_library_name(dynamic_library_name); } |