diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85f267a475..4ebd33576f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,6 +108,12 @@ jobs: features: "--all-features" - toolchain: "stable" features: "--all-features" + # The derive feature inherits the MSRV of its dependencies. Syn 3 + # requires Rust 1.71 and uses post-1.56 language and library + # features, so don't test feature sets that enable zerocopy-derive + # on the core library MSRV. + - toolchain: "msrv" + features: "--features __internal_use_only_features_that_work_on_stable" - toolchain: "no-zerocopy-simd-x86-avx12-1-89-0" features: "--all-features" - toolchain: "no-zerocopy-core-error-1-81-0" @@ -132,8 +138,12 @@ jobs: features: "--features __internal_use_only_features_that_work_on_stable" - crate: "zerocopy-derive" features: "--all-features" - # Exclue any combination of zerocopy-derive and any toolchain version - # other than "msrv", "stable", and "nightly". These other versions + # Exclude zerocopy-derive on the core library MSRV; derive + # inherits the MSRV of its dependencies. + - crate: "zerocopy-derive" + toolchain: "msrv" + # Exclude any combination of zerocopy-derive and any toolchain version + # other than "stable" and "nightly". These other versions # exist to exercise zerocopy behavior which differs by toolchain; # zerocopy-derive doesn't behave differently on these toolchains. - crate: "zerocopy-derive" diff --git a/zerocopy/Cargo.lock b/zerocopy/Cargo.lock index d4326140e7..efa163afda 100644 --- a/zerocopy/Cargo.lock +++ b/zerocopy/Cargo.lock @@ -141,19 +141,19 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" dependencies = [ "proc-macro2", - "syn", + "syn 3.0.3", ] [[package]] name = "proc-macro2" -version = "1.0.80" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -252,7 +252,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.56", ] [[package]] @@ -290,6 +290,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "testutil" version = "0.0.0" @@ -319,7 +330,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.56", ] [[package]] @@ -434,7 +445,7 @@ dependencies = [ "quote", "rustversion", "static_assertions", - "syn", + "syn 3.0.3", "testutil", "zerocopy", ] diff --git a/zerocopy/vendor/prettyplease/.cargo-checksum.json b/zerocopy/vendor/prettyplease/.cargo-checksum.json index cef4988a61..a82f94ff9c 100644 --- a/zerocopy/vendor/prettyplease/.cargo-checksum.json +++ b/zerocopy/vendor/prettyplease/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"6db1cca4fbfeefb2fcbac8874c25981ddc265bcccfe698fb27984508f368c858","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"dde54d4d5c759fbaea82b4039ab9cea7ee91918431dae011ffe01472e2e9eb44","build.rs":"fdf8aa9b5441b298c72ae23645e227adc52ac69d2decc1bda04e1a91f70ff87d","examples/input.rs":"53350088f12a346a99034af41ef432dedcc9e5d581c5592d9aae3807c42656c1","examples/output.prettyplease.rs":"fa63c118daadb64c456ec5b8d5e46e5d7fabbbeb6a6e61a08eabc23360a18fbd","examples/output.rustc.rs":"0c66f8929fa40a2822d4ea1aec3d8b83db598aba043b17f3c1a6133f0d657135","examples/output.rustfmt.rs":"914a9aea1c51e097bfd80c9af4011811e6126c9df5fb0eac3d40b1203fba7c58","src/algorithm.rs":"7a4a7b62f5300aabf7fcff3cd8c8aaa3ae1e3d1dc717eea1e4797988ce0e18c7","src/attr.rs":"54e829ae468f22c8e2853d669515575f1444bfee026cfd9b19538f77caf10ab7","src/convenience.rs":"dd392b009b691d3587c7d8e3caeaacf450303c4223792b5f89c336358e371c39","src/data.rs":"9db6623d3ccc79b541a28bdc88875ad0036576689e085007eb362819f8e9a2d3","src/expr.rs":"fd39086a275071f50cb4b519a6b5413a27863dc2a142888e9a1acc1c841b1a1a","src/file.rs":"5689efa3c5959a6a0d8cfc2c13bf8a37ab0669e2b81dbded3f3c28884a88fca0","src/generics.rs":"60df8d54fe81279bcdf790e027eb5e6f80798ffd0873fa0f5bdff921582df397","src/item.rs":"711f2c9a00e9577c058d38cf3e521390f77cb7d0a36955353a4fac2b64af2a4b","src/iter.rs":"38b2cd3b38719c6024fb6b3aa739f6f8736c83193fd21e2365d4f6c27bc41666","src/lib.rs":"09d5eb7ba944ab09e9094fbe9ce1f1a9b9942b8098fa6b84a20f3d079921b6f4","src/lifetime.rs":"6d420430168185b2da3409bc38a45f63cced9443915f04e6aec71367fc070dcf","src/lit.rs":"6aabc9c84f8914064536f7ed89547485c08f042f3f386e88fb1c8f82ec69d8e7","src/mac.rs":"62911747c308187afc750b4bd4f8bd24ee825081043d78da68a001ea55ab5853","src/pat.rs":"d130b141a3fd8098913cb179efe6600a5f010a2719447ecb3d4fb29e9b546220","src/path.rs":"b9c78a53c433678140b5a0e4044872989f25db2fe4fd44123e2500efbde671eb","src/ring.rs":"e23d133209b977e457b07b0cd93b3711d01f4172d7cfa4cf6a7247637390e606","src/stmt.rs":"c9328d8e5111087ed0f8226b9765ddc636e17cb9e4f86301794bb9d3a27cb39a","src/token.rs":"c288b1d81f2a35673d4ca1dd10d3386670b067460121df3038303e1ed73b41a7","src/ty.rs":"b5fa5f318c5e4593ed3eed4707e63dceaa62eea4ecdfba0f59bd946917ca3dbd","tests/test.rs":"04994ad0a37c43457390f11ade6ab74fc26c5e879b0a374f0b64acb530a0a496"},"package":"8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"} \ No newline at end of file +{"files":{".cargo_vcs_info.json":"9ec693c56142ba5d73f4156a7a266ca1cbb7d145fe7df64e3d88106b8f3563f9",".github/FUNDING.yml":"b017158736b3c9751a2d21edfce7fe61c8954e2fced8da8dd3013c2f3e295bd9",".github/workflows/ci.yml":"a93f16c298434c64c2691e673a9229809ef238d39b509cae3501de46ac0afbb4","Cargo.lock":"eb29633a4b99efc641a9c13540cdbaceefd9a2a2cf72992ec6257d2ebdd6b48c","Cargo.toml":"6474a08956c9922f41924680a4ba418ad99117c61bcfbad94e5b4b4d258a663b","Cargo.toml.orig":"bd9562b75d7ecdd85bec47fa5d936be80a96cf7fc386b41c9f47bdab21b819ed","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f586de4251ca5a441ec4c01b2c042a9cd8d4117a59c925f788ec5fcbf079fd1b","build.rs":"6e18666b8a69aa6b3d6fc6c7273e2d313f55075035ef5aff73b000e52eaedbfd","examples/.tokeignore":"23ab7a9f335a33747ebbc74f39c81b145cb7928e7fefe8055ca4db0a4fac7557","examples/input.rs":"53350088f12a346a99034af41ef432dedcc9e5d581c5592d9aae3807c42656c1","examples/output.prettyplease.rs":"fa63c118daadb64c456ec5b8d5e46e5d7fabbbeb6a6e61a08eabc23360a18fbd","examples/output.rustc.rs":"04647e9b01f2aa85982f849c2d897acf3b6931121c1ef953de5fb6a67b80e05a","examples/output.rustfmt.rs":"914a9aea1c51e097bfd80c9af4011811e6126c9df5fb0eac3d40b1203fba7c58","src/algorithm.rs":"901c91416d7526038bfad30e0066295a03d2bb995830016ace49a41540079010","src/attr.rs":"0a5c64b1c1f6fe4944c1d805c528ee4a9a8c6223e875afe9f48371cba66732ee","src/classify.rs":"709f6437a804fb1f135b0f454a1acea1f98e3519d1c785b62343ed24c5f2be84","src/convenience.rs":"dd392b009b691d3587c7d8e3caeaacf450303c4223792b5f89c336358e371c39","src/data.rs":"58299942fa3a90af9162dc7d256899d9c9389de3dcb8eb3927e706c20c2d2f81","src/expr.rs":"72136dc4537467957d620a135bdca7382c8fe4d32d5874b86fe7b7e7e7502e11","src/file.rs":"5689efa3c5959a6a0d8cfc2c13bf8a37ab0669e2b81dbded3f3c28884a88fca0","src/fixup.rs":"ecf87543c342fffc79bae54e4fa174cbfd5c341817315caa3b95cce0d49ebf7c","src/generics.rs":"613c5eaefe7a80d05967e96072431e080e0cffee01291f04b42dda8ecc9df149","src/item.rs":"235193c2ea4825091a1f5ed21715047d65656647219be9300be7652610bf23e0","src/iter.rs":"38b2cd3b38719c6024fb6b3aa739f6f8736c83193fd21e2365d4f6c27bc41666","src/lib.rs":"b25d72417ceacdfb4820461cc295b14800e12dc79f8e8c0ddafcab1957a4b68f","src/lifetime.rs":"6d420430168185b2da3409bc38a45f63cced9443915f04e6aec71367fc070dcf","src/lit.rs":"9ea6d25533e64df4ff01c084fa1c31ddf64fb3b159409eec7d80dbf281e5171e","src/mac.rs":"b4512317afe2221ca4c5cbc9f1e4e33aa399577b10c34c19071d07fd3b617a41","src/pat.rs":"ddc1352516d5f9c52d56b0939aef61a125121ef921874d80fcc8f571cf23b1d3","src/path.rs":"bb2c7946a3c742ab84f19c6229097832b35a9f6a94d550a6a80648e0321ceae7","src/precedence.rs":"a8ce97ba0a25f442b5f238c64f078d70f4114b4b0f9df82764d533dd39a47abb","src/ring.rs":"517b1a02f8e0a9c1316830117daad1e30d17e1fcf6428c6b438c626aa43286ae","src/stmt.rs":"e17ab9647fed9daa4f5b2fbd007015128f2a7fc65686a988593444a37242f885","src/token.rs":"c288b1d81f2a35673d4ca1dd10d3386670b067460121df3038303e1ed73b41a7","src/ty.rs":"b40ce3d2bf6caffa7605ca5f1961ebdc645a12e1aa43fbf3bda60ceab28f0180","tests/test.rs":"c6f8c7830b7491fca1d56e41aa4acc6256b683a3556a48982f57ae62d38aaaa2","tests/test_precedence.rs":"139ccee1718eb4b2690ee090104afbbc41a7eb44fb18b6f5cb900527d5955786"},"package":"2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0"} \ No newline at end of file diff --git a/zerocopy/vendor/prettyplease/.cargo_vcs_info.json b/zerocopy/vendor/prettyplease/.cargo_vcs_info.json new file mode 100644 index 0000000000..d8793ca5e2 --- /dev/null +++ b/zerocopy/vendor/prettyplease/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "49e50897b580a5b7591ead6ef73f3fe09e76d896" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/zerocopy/vendor/prettyplease/.github/FUNDING.yml b/zerocopy/vendor/prettyplease/.github/FUNDING.yml new file mode 100644 index 0000000000..750707701c --- /dev/null +++ b/zerocopy/vendor/prettyplease/.github/FUNDING.yml @@ -0,0 +1 @@ +github: dtolnay diff --git a/zerocopy/vendor/prettyplease/.github/workflows/ci.yml b/zerocopy/vendor/prettyplease/.github/workflows/ci.yml new file mode 100644 index 0000000000..1e0c924a4d --- /dev/null +++ b/zerocopy/vendor/prettyplease/.github/workflows/ci.yml @@ -0,0 +1,123 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + schedule: [cron: "40 1 * * *"] + +permissions: + contents: read + +env: + RUSTFLAGS: -Dwarnings + +jobs: + pre_ci: + uses: dtolnay/.github/.github/workflows/pre_ci.yml@master + + test: + name: Rust ${{matrix.rust}} + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [nightly, beta, stable, 1.71.0] + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + - run: cargo check + - run: cargo check --features verbatim + - run: cargo test + env: + RUSTFLAGS: ${{env.RUSTFLAGS}} ${{matrix.rust == 'nightly' && '--cfg exhaustive' || ''}} + - run: cargo test --release --test test_precedence + env: + RUSTFLAGS: ${{env.RUSTFLAGS}} ${{matrix.rust == 'nightly' && '--cfg exhaustive' || ''}} + if: matrix.rust != '1.71.0' + - uses: actions/upload-artifact@v7 + if: matrix.rust == 'nightly' && always() + with: + name: Cargo.lock + path: Cargo.lock + continue-on-error: true + + examples: + name: Examples + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + with: + components: llvm-tools, rustc-dev, rustfmt + - run: cargo run --manifest-path examples/update/Cargo.toml + - run: git diff --exit-code + - run: cargo run --manifest-path cargo-expand/update/Cargo.toml + - run: git diff --exit-code + + fuzz: + name: Fuzz + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/install@cargo-fuzz + - run: cargo fuzz check + + minimal: + name: Minimal versions + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo generate-lockfile -Z minimal-versions + - run: cargo check --locked + + doc: + name: Documentation + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/install@cargo-docs-rs + - run: cargo docs-rs + + clippy: + name: Clippy + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@clippy + - run: cargo clippy --features verbatim -- -Dclippy::all -Dclippy::pedantic + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --workspace --exit-code 1 diff --git a/zerocopy/vendor/prettyplease/Cargo.lock b/zerocopy/vendor/prettyplease/Cargo.lock new file mode 100644 index 0000000000..823e83badf --- /dev/null +++ b/zerocopy/vendor/prettyplease/Cargo.lock @@ -0,0 +1,63 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "indoc" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] + +[[package]] +name = "prettyplease" +version = "0.3.0" +dependencies = [ + "indoc", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "syn" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fac314a64dc9a36e61a9eb4261a5e9bbfbc922b27e518af97bc32b926cf967" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/zerocopy/vendor/prettyplease/Cargo.toml b/zerocopy/vendor/prettyplease/Cargo.toml index 5d74042209..31db3aa2a8 100644 --- a/zerocopy/vendor/prettyplease/Cargo.toml +++ b/zerocopy/vendor/prettyplease/Cargo.toml @@ -11,13 +11,18 @@ [package] edition = "2021" -rust-version = "1.56" +rust-version = "1.71" name = "prettyplease" -version = "0.2.17" +version = "0.3.0" authors = ["David Tolnay "] -links = "prettyplease02" +build = "build.rs" +links = "prettyplease03" exclude = ["cargo-expand"] +autolib = false +autobins = false autoexamples = false +autotests = false +autobenches = false description = "A minimal `syn` syntax tree pretty-printer" documentation = "https://docs.rs/prettyplease" readme = "README.md" @@ -27,21 +32,39 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/dtolnay/prettyplease" [package.metadata.docs.rs] -rustdoc-args = ["--generate-link-to-definition"] targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", +] [package.metadata.playground] features = ["verbatim"] +[features] +verbatim = ["syn/parsing"] + [lib] -doc-scrape-examples = false +name = "prettyplease" +path = "src/lib.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[[test]] +name = "test_precedence" +path = "tests/test_precedence.rs" [dependencies.proc-macro2] -version = "1.0.74" +version = "1.0.80" default-features = false [dependencies.syn] -version = "2.0.46" +version = "3" features = ["full"] default-features = false @@ -49,7 +72,7 @@ default-features = false version = "2" [dev-dependencies.proc-macro2] -version = "1.0.74" +version = "1.0.80" default-features = false [dev-dependencies.quote] @@ -57,9 +80,12 @@ version = "1.0.35" default-features = false [dev-dependencies.syn] -version = "2.0.46" -features = ["parsing"] +version = "3" +features = [ + "clone-impls", + "extra-traits", + "parsing", + "printing", + "visit-mut", +] default-features = false - -[features] -verbatim = ["syn/parsing"] diff --git a/zerocopy/vendor/prettyplease/Cargo.toml.orig b/zerocopy/vendor/prettyplease/Cargo.toml.orig new file mode 100644 index 0000000000..59567f4567 --- /dev/null +++ b/zerocopy/vendor/prettyplease/Cargo.toml.orig @@ -0,0 +1,44 @@ +[package] +name = "prettyplease" +version = "0.3.0" +authors = ["David Tolnay "] +autoexamples = false +categories = ["development-tools"] +description = "A minimal `syn` syntax tree pretty-printer" +documentation = "https://docs.rs/prettyplease" +edition = "2021" +exclude = ["cargo-expand"] +keywords = ["rustfmt"] +license = "MIT OR Apache-2.0" +links = "prettyplease03" +repository = "https://github.com/dtolnay/prettyplease" +rust-version = "1.71" + +[features] +verbatim = ["syn/parsing"] + +[dependencies] +proc-macro2 = { version = "1.0.80", default-features = false } +syn = { version = "3", default-features = false, features = ["full"] } + +[dev-dependencies] +indoc = "2" +proc-macro2 = { version = "1.0.80", default-features = false } +quote = { version = "1.0.35", default-features = false } +syn = { version = "3", default-features = false, features = ["clone-impls", "extra-traits", "parsing", "printing", "visit-mut"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", +] + +[package.metadata.playground] +features = ["verbatim"] + +[workspace] +members = ["cargo-expand/update", "examples/update"] diff --git a/zerocopy/vendor/prettyplease/README.md b/zerocopy/vendor/prettyplease/README.md index bd0439b273..5bc2fb00ff 100644 --- a/zerocopy/vendor/prettyplease/README.md +++ b/zerocopy/vendor/prettyplease/README.md @@ -167,8 +167,8 @@ from rustfmt-formatted code. ```rust // [dependencies] -// prettyplease = "0.2" -// syn = { version = "2", default-features = false, features = ["full", "parsing"] } +// prettyplease = "0.3" +// syn = { version = "3", default-features = false, features = ["full", "parsing"] } const INPUT: &str = stringify! { use crate::{ @@ -261,8 +261,8 @@ well-formatted Rust code that is locally indistinguishable from rustfmt's style. The reason is that in the paper, the complete non-whitespace contents are assumed to be independent of linebreak decisions, with Scan and Print being only in control of the whitespace (spaces and line breaks). In Rust as idiomatically -formattted by rustfmt, that is not the case. Trailing commas are one example; -the punctuation is only known *after* the broken vs non-broken status of the +formatted by rustfmt, that is not the case. Trailing commas are one example; the +punctuation is only known *after* the broken vs non-broken status of the surrounding group is known: ```rust diff --git a/zerocopy/vendor/prettyplease/build.rs b/zerocopy/vendor/prettyplease/build.rs index 0d798ed6f3..9dd68b85ff 100644 --- a/zerocopy/vendor/prettyplease/build.rs +++ b/zerocopy/vendor/prettyplease/build.rs @@ -1,5 +1,29 @@ +use std::env; +use std::ffi::OsString; +use std::process; + fn main() { println!("cargo:rerun-if-changed=build.rs"); - println!(concat!("cargo:VERSION=", env!("CARGO_PKG_VERSION"))); + println!("cargo:rustc-check-cfg=cfg(exhaustive)"); + println!("cargo:rustc-check-cfg=cfg(prettyplease_debug)"); + println!("cargo:rustc-check-cfg=cfg(prettyplease_debug_indent)"); + + let pkg_version = cargo_env_var("CARGO_PKG_VERSION"); + println!("cargo:VERSION={}", pkg_version.to_str().unwrap()); + + let pkg_version_major = cargo_env_var("CARGO_PKG_VERSION_MAJOR"); + let pkg_version_minor = cargo_env_var("CARGO_PKG_VERSION_MINOR"); + let manifest_links = cargo_env_var("CARGO_MANIFEST_LINKS"); + assert!( + pkg_version_major == "0" + && manifest_links == *format!("prettyplease0{}", pkg_version_minor.to_str().unwrap()) + ); +} + +fn cargo_env_var(key: &str) -> OsString { + env::var_os(key).unwrap_or_else(|| { + eprintln!("Environment variable ${key} is not set during execution of build script"); + process::exit(1); + }) } diff --git a/zerocopy/vendor/prettyplease/examples/.tokeignore b/zerocopy/vendor/prettyplease/examples/.tokeignore new file mode 100644 index 0000000000..6f5f3d11d3 --- /dev/null +++ b/zerocopy/vendor/prettyplease/examples/.tokeignore @@ -0,0 +1 @@ +*.rs diff --git a/zerocopy/vendor/prettyplease/examples/output.rustc.rs b/zerocopy/vendor/prettyplease/examples/output.rustc.rs index 609a8c3f0c..a77a14a8ec 100644 --- a/zerocopy/vendor/prettyplease/examples/output.rustc.rs +++ b/zerocopy/vendor/prettyplease/examples/output.rustc.rs @@ -97,9 +97,9 @@ impl Ipv4Addr { } pub const fn is_global(&self) -> bool { if u32::from_be_bytes(self.octets()) == 0xc0000009 || - u32::from_be_bytes(self.octets()) == 0xc000000a { - return true; - } + u32::from_be_bytes(self.octets()) == 0xc000000a { + return true; + } !self.is_private() && !self.is_loopback() && !self.is_link_local() && !self.is_broadcast() && !self.is_documentation() && !self.is_shared() && @@ -169,19 +169,18 @@ impl fmt::Display for Ipv4Addr { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let octets = self.octets(); if fmt.precision().is_none() && fmt.width().is_none() { - write!(fmt, "{}.{}.{}.{}", octets [0], octets [1], octets [2], - octets [3]) - } else { - const IPV4_BUF_LEN: usize = 15; - let mut buf = [0u8; IPV4_BUF_LEN]; - let mut buf_slice = &mut buf[..]; - write!(buf_slice, "{}.{}.{}.{}", octets [0], octets [1], octets - [2], octets [3]).unwrap(); - let len = IPV4_BUF_LEN - buf_slice.len(); - let buf = - unsafe { crate::str::from_utf8_unchecked(&buf[..len]) }; - fmt.pad(buf) - } + write!(fmt, "{}.{}.{}.{}", octets [0], octets [1], octets [2], + octets [3]) + } else { + const IPV4_BUF_LEN: usize = 15; + let mut buf = [0u8; IPV4_BUF_LEN]; + let mut buf_slice = &mut buf[..]; + write!(buf_slice, "{}.{}.{}.{}", octets [0], octets [1], octets + [2], octets [3]).unwrap(); + let len = IPV4_BUF_LEN - buf_slice.len(); + let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) }; + fmt.pad(buf) + } } } impl fmt::Debug for Ipv4Addr { @@ -316,17 +315,17 @@ impl Ipv6Addr { } pub const fn multicast_scope(&self) -> Option { if self.is_multicast() { - match self.segments()[0] & 0x000f { - 1 => Some(Ipv6MulticastScope::InterfaceLocal), - 2 => Some(Ipv6MulticastScope::LinkLocal), - 3 => Some(Ipv6MulticastScope::RealmLocal), - 4 => Some(Ipv6MulticastScope::AdminLocal), - 5 => Some(Ipv6MulticastScope::SiteLocal), - 8 => Some(Ipv6MulticastScope::OrganizationLocal), - 14 => Some(Ipv6MulticastScope::Global), - _ => None, - } - } else { None } + match self.segments()[0] & 0x000f { + 1 => Some(Ipv6MulticastScope::InterfaceLocal), + 2 => Some(Ipv6MulticastScope::LinkLocal), + 3 => Some(Ipv6MulticastScope::RealmLocal), + 4 => Some(Ipv6MulticastScope::AdminLocal), + 5 => Some(Ipv6MulticastScope::SiteLocal), + 8 => Some(Ipv6MulticastScope::OrganizationLocal), + 14 => Some(Ipv6MulticastScope::Global), + _ => None, + } + } else { None } } pub const fn is_multicast(&self) -> bool { (self.segments()[0] & 0xff00) == 0xff00 @@ -341,15 +340,15 @@ impl Ipv6Addr { } pub const fn to_ipv4(&self) -> Option { if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() { - let [a, b] = ab.to_be_bytes(); - let [c, d] = cd.to_be_bytes(); - Some(Ipv4Addr::new(a, b, c, d)) - } else { None } + let [a, b] = ab.to_be_bytes(); + let [c, d] = cd.to_be_bytes(); + Some(Ipv4Addr::new(a, b, c, d)) + } else { None } } pub const fn to_canonical(&self) -> IpAddr { if let Some(mapped) = self.to_ipv4_mapped() { - return IpAddr::V4(mapped); - } + return IpAddr::V4(mapped); + } IpAddr::V6(*self) } pub const fn octets(&self) -> [u8; 16] { self.inner.s6_addr } @@ -357,65 +356,64 @@ impl Ipv6Addr { impl fmt::Display for Ipv6Addr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.precision().is_none() && f.width().is_none() { - let segments = self.segments(); - if self.is_unspecified() { - f.write_str("::") - } else if self.is_loopback() { - f.write_str("::1") - } else if let Some(ipv4) = self.to_ipv4() { - match segments[5] { - 0 => write!(f, "::{}", ipv4), - 0xffff => write!(f, "::ffff:{}", ipv4), - _ => unreachable!(), - } - } else { - #[derive(Copy, Clone, Default)] - struct Span { - start: usize, - len: usize, - } - let zeroes = - { - let mut longest = Span::default(); - let mut current = Span::default(); - for (i, &segment) in segments.iter().enumerate() { - if segment == 0 { - if current.len == 0 { current.start = i; } - current.len += 1; - if current.len > longest.len { longest = current; } - } else { current = Span::default(); } - } - longest - }; - #[doc = " Write a colon-separated part of the address"] - #[inline] - fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) - -> fmt::Result { - if let Some((first, tail)) = chunk.split_first() { - write!(f, "{:x}", first)?; - for segment in tail { - f.write_char(':')?; - write!(f, "{:x}", segment)?; - } - } - Ok(()) - } - if zeroes.len > 1 { - fmt_subslice(f, &segments[..zeroes.start])?; - f.write_str("::")?; - fmt_subslice(f, &segments[zeroes.start + zeroes.len..]) - } else { fmt_subslice(f, &segments) } - } + let segments = self.segments(); + if self.is_unspecified() { + f.write_str("::") + } else if self.is_loopback() { + f.write_str("::1") + } else if let Some(ipv4) = self.to_ipv4() { + match segments[5] { + 0 => write!(f, "::{}", ipv4), + 0xffff => write!(f, "::ffff:{}", ipv4), + _ => unreachable!(), + } } else { - const IPV6_BUF_LEN: usize = (4 * 8) + 7; - let mut buf = [0u8; IPV6_BUF_LEN]; - let mut buf_slice = &mut buf[..]; - write!(buf_slice, "{}", self).unwrap(); - let len = IPV6_BUF_LEN - buf_slice.len(); - let buf = - unsafe { crate::str::from_utf8_unchecked(&buf[..len]) }; - f.pad(buf) - } + #[derive(Copy, Clone, Default)] + struct Span { + start: usize, + len: usize, + } + let zeroes = + { + let mut longest = Span::default(); + let mut current = Span::default(); + for (i, &segment) in segments.iter().enumerate() { + if segment == 0 { + if current.len == 0 { current.start = i; } + current.len += 1; + if current.len > longest.len { longest = current; } + } else { current = Span::default(); } + } + longest + }; + #[doc = " Write a colon-separated part of the address"] + #[inline] + fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) + -> fmt::Result { + if let Some((first, tail)) = chunk.split_first() { + write!(f, "{:x}", first)?; + for segment in tail { + f.write_char(':')?; + write!(f, "{:x}", segment)?; + } + } + Ok(()) + } + if zeroes.len > 1 { + fmt_subslice(f, &segments[..zeroes.start])?; + f.write_str("::")?; + fmt_subslice(f, &segments[zeroes.start + zeroes.len..]) + } else { fmt_subslice(f, &segments) } + } + } else { + const IPV6_BUF_LEN: usize = (4 * 8) + 7; + let mut buf = [0u8; IPV6_BUF_LEN]; + let mut buf_slice = &mut buf[..]; + write!(buf_slice, "{}", self).unwrap(); + let len = IPV6_BUF_LEN - buf_slice.len(); + let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) }; + f.pad(buf) + } } } impl fmt::Debug for Ipv6Addr { diff --git a/zerocopy/vendor/prettyplease/src/algorithm.rs b/zerocopy/vendor/prettyplease/src/algorithm.rs index 6e2b9614e3..482b3ad7d1 100644 --- a/zerocopy/vendor/prettyplease/src/algorithm.rs +++ b/zerocopy/vendor/prettyplease/src/algorithm.rs @@ -19,7 +19,7 @@ pub struct BreakToken { pub offset: isize, pub blank_space: usize, pub pre_break: Option, - pub post_break: Option, + pub post_break: &'static str, pub no_break: Option, pub if_nonempty: bool, pub never_break: bool, @@ -174,6 +174,7 @@ impl Printer { } } + #[track_caller] pub fn offset(&mut self, offset: isize) { match &mut self.buf.last_mut().token { Token::Break(token) => token.offset += offset, @@ -211,9 +212,18 @@ impl Printer { self.scan_end(); } + pub fn ends_with(&self, ch: char) -> bool { + for i in self.buf.index_range().rev() { + if let Token::String(token) = &self.buf[i].token { + return token.ends_with(ch); + } + } + self.out.ends_with(ch) + } + fn check_stream(&mut self) { while self.right_total - self.left_total > self.space { - if *self.scan_stack.front().unwrap() == self.buf.index_of_first() { + if *self.scan_stack.front().unwrap() == self.buf.index_range().start { self.scan_stack.pop_front().unwrap(); self.buf.first_mut().size = SIZE_INFINITY; } @@ -353,10 +363,10 @@ impl Printer { let indent = self.indent as isize + token.offset; self.pending_indentation = usize::try_from(indent).unwrap(); self.space = cmp::max(MARGIN - indent, MIN_SPACE); - if let Some(post_break) = token.post_break { + if !token.post_break.is_empty() { self.print_indent(); - self.out.push(post_break); - self.space -= post_break.len_utf8() as isize; + self.out.push_str(token.post_break); + self.space -= token.post_break.len() as isize; } } } diff --git a/zerocopy/vendor/prettyplease/src/attr.rs b/zerocopy/vendor/prettyplease/src/attr.rs index 0388d66f74..b436283f3c 100644 --- a/zerocopy/vendor/prettyplease/src/attr.rs +++ b/zerocopy/vendor/prettyplease/src/attr.rs @@ -1,4 +1,5 @@ use crate::algorithm::Printer; +use crate::fixup::FixupContext; use crate::path::PathKind; use crate::INDENT; use proc_macro2::{Delimiter, Group, TokenStream, TokenTree}; @@ -102,7 +103,7 @@ impl Printer { fn meta_name_value(&mut self, meta: &MetaNameValue) { self.path(&meta.path, PathKind::Simple); self.word(" = "); - self.expr(&meta.value); + self.expr(&meta.value, FixupContext::NONE); } fn attr_tokens(&mut self, tokens: TokenStream) { @@ -283,5 +284,5 @@ fn can_be_block_comment(value: &str) -> bool { } } - depth == 0 + depth == 0 && !value.ends_with('/') } diff --git a/zerocopy/vendor/prettyplease/src/classify.rs b/zerocopy/vendor/prettyplease/src/classify.rs new file mode 100644 index 0000000000..5fa6cf4a60 --- /dev/null +++ b/zerocopy/vendor/prettyplease/src/classify.rs @@ -0,0 +1,324 @@ +use proc_macro2::{Delimiter, TokenStream, TokenTree}; +use std::ops::ControlFlow; +use syn::punctuated::Punctuated; +use syn::{Expr, MacroDelimiter, Path, PathArguments, ReturnType, Token, Type, TypeParamBound}; + +pub(crate) fn requires_semi_to_be_stmt(expr: &Expr) -> bool { + match expr { + Expr::Macro(expr) => !matches!(expr.mac.delimiter, MacroDelimiter::Brace(_)), + _ => requires_comma_to_be_match_arm(expr), + } +} + +pub(crate) fn requires_comma_to_be_match_arm(mut expr: &Expr) -> bool { + loop { + match expr { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::If(_) + | Expr::Match(_) + | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc + | Expr::While(_) + | Expr::Loop(_) + | Expr::ForLoop(_) + | Expr::TryBlock(_) + | Expr::Const(_) => return false, + + Expr::Array(_) + | Expr::Assign(_) + | Expr::Async(_) + | Expr::Await(_) + | Expr::Binary(_) + | Expr::Break(_) + | Expr::Call(_) + | Expr::Cast(_) + | Expr::Closure(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Range(_) + | Expr::RawAddr(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::Try(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Yield(_) + | Expr::Verbatim(_) => return true, + + Expr::Group(group) => expr = &group.expr, + + _ => return true, + } + } +} + +pub(crate) fn trailing_unparameterized_path(mut ty: &Type) -> bool { + loop { + match ty { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Type::FnPtr(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Path(t) => match last_type_in_path(&t.path) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Macro(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) + | Type::Verbatim(_) => return false, + + _ => return false, + } + } + + fn last_type_in_path(path: &Path) -> ControlFlow { + match &path.segments.last().unwrap().arguments { + PathArguments::None => ControlFlow::Break(true), + PathArguments::AngleBracketed(_) => ControlFlow::Break(false), + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => ControlFlow::Break(false), + ReturnType::Type(_, ret) => ControlFlow::Continue(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + TypeParamBound::Trait(t) => last_type_in_path(&t.path), + TypeParamBound::Lifetime(_) + | TypeParamBound::PreciseCapture(_) + | TypeParamBound::Verbatim(_) => ControlFlow::Break(false), + _ => ControlFlow::Break(false), + } + } +} + +/// Whether the expression's first token is the label of a loop/block. +pub(crate) fn expr_leading_label(mut expr: &Expr) -> bool { + loop { + match expr { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::Block(e) => return e.label.is_some(), + Expr::ForLoop(e) => return e.label.is_some(), + Expr::Loop(e) => return e.label.is_some(), + Expr::While(e) => return e.label.is_some(), + + Expr::Assign(e) => expr = &e.left, + Expr::Await(e) => expr = &e.base, + Expr::Binary(e) => expr = &e.left, + Expr::Call(e) => expr = &e.func, + Expr::Cast(e) => expr = &e.expr, + Expr::Field(e) => expr = &e.base, + Expr::Index(e) => expr = &e.expr, + Expr::MethodCall(e) => expr = &e.receiver, + Expr::Range(e) => match &e.start { + Some(start) => expr = start, + None => return false, + }, + Expr::Try(e) => expr = &e.expr, + + Expr::Array(_) + | Expr::Async(_) + | Expr::Break(_) + | Expr::Closure(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::If(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::RawAddr(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::Yield(_) => return false, + + Expr::Group(e) => { + if !e.attrs.is_empty() { + return false; + } + expr = &e.expr; + } + + _ => return false, + } + } +} + +/// Whether the expression's last token is `}`. +pub(crate) fn expr_trailing_brace(mut expr: &Expr) -> bool { + loop { + match expr { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::Async(_) + | Expr::Block(_) + | Expr::Const(_) + | Expr::ForLoop(_) + | Expr::If(_) + | Expr::Loop(_) + | Expr::Match(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Unsafe(_) + | Expr::While(_) => return true, + + Expr::Assign(e) => expr = &e.right, + Expr::Binary(e) => expr = &e.right, + Expr::Break(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Cast(e) => return type_trailing_brace(&e.ty), + Expr::Closure(e) => expr = &e.body, + Expr::Group(e) => expr = &e.expr, + Expr::Let(e) => expr = &e.expr, + Expr::Macro(e) => return matches!(e.mac.delimiter, MacroDelimiter::Brace(_)), + Expr::Range(e) => match &e.end { + Some(end) => expr = end, + None => return false, + }, + Expr::RawAddr(e) => expr = &e.expr, + Expr::Reference(e) => expr = &e.expr, + Expr::Return(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Unary(e) => expr = &e.expr, + Expr::Verbatim(e) => return tokens_trailing_brace(e), + Expr::Yield(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + + Expr::Array(_) + | Expr::Await(_) + | Expr::Call(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Lit(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Repeat(_) + | Expr::Try(_) + | Expr::Tuple(_) => return false, + + _ => return false, + } + } + + fn type_trailing_brace(mut ty: &Type) -> bool { + loop { + match ty { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Type::FnPtr(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Macro(t) => return matches!(t.mac.delimiter, MacroDelimiter::Brace(_)), + Type::Path(t) => match last_type_in_path(&t.path) { + Some(t) => ty = t, + None => return false, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Verbatim(t) => return tokens_trailing_brace(t), + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) => return false, + + _ => return false, + } + } + } + + fn last_type_in_path(path: &Path) -> Option<&Type> { + match &path.segments.last().unwrap().arguments { + PathArguments::None | PathArguments::AngleBracketed(_) => None, + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => None, + ReturnType::Type(_, ret) => Some(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + TypeParamBound::Trait(t) => match last_type_in_path(&t.path) { + Some(t) => ControlFlow::Continue(t), + None => ControlFlow::Break(false), + }, + TypeParamBound::Lifetime(_) | TypeParamBound::PreciseCapture(_) => { + ControlFlow::Break(false) + } + TypeParamBound::Verbatim(t) => ControlFlow::Break(tokens_trailing_brace(t)), + _ => ControlFlow::Break(false), + } + } + + fn tokens_trailing_brace(tokens: &TokenStream) -> bool { + if let Some(TokenTree::Group(last)) = tokens.clone().into_iter().last() { + last.delimiter() == Delimiter::Brace + } else { + false + } + } +} diff --git a/zerocopy/vendor/prettyplease/src/data.rs b/zerocopy/vendor/prettyplease/src/data.rs index d823ee3e2e..c1450dd3d2 100644 --- a/zerocopy/vendor/prettyplease/src/data.rs +++ b/zerocopy/vendor/prettyplease/src/data.rs @@ -1,4 +1,5 @@ use crate::algorithm::Printer; +use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::path::PathKind; use crate::INDENT; @@ -31,7 +32,7 @@ impl Printer { } if let Some((_eq_token, discriminant)) = &variant.discriminant { self.word(" = "); - self.expr(discriminant); + self.expr(discriminant, FixupContext::NONE); } } @@ -66,9 +67,10 @@ impl Printer { fn vis_restricted(&mut self, vis: &VisRestricted) { self.word("pub("); - let omit_in = vis.path.get_ident().map_or(false, |ident| { - matches!(ident.to_string().as_str(), "self" | "super" | "crate") - }); + let omit_in = vis + .path + .get_ident() + .is_some_and(|ident| matches!(ident.to_string().as_str(), "self" | "super" | "crate")); if !omit_in { self.word("in "); } diff --git a/zerocopy/vendor/prettyplease/src/expr.rs b/zerocopy/vendor/prettyplease/src/expr.rs index d3fb6d72e6..16692a62b1 100644 --- a/zerocopy/vendor/prettyplease/src/expr.rs +++ b/zerocopy/vendor/prettyplease/src/expr.rs @@ -1,7 +1,10 @@ use crate::algorithm::{BreakToken, Printer}; use crate::attr; +use crate::classify; +use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::path::PathKind; +use crate::precedence::Precedence; use crate::stmt; use crate::INDENT; use proc_macro2::TokenStream; @@ -10,100 +13,137 @@ use syn::{ token, Arm, Attribute, BinOp, Block, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBinary, ExprBlock, ExprBreak, ExprCall, ExprCast, ExprClosure, ExprConst, ExprContinue, ExprField, ExprForLoop, ExprGroup, ExprIf, ExprIndex, ExprInfer, ExprLet, ExprLit, ExprLoop, - ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprReference, - ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary, ExprUnsafe, - ExprWhile, ExprYield, FieldValue, Index, Label, Member, RangeLimits, ReturnType, Stmt, Token, - UnOp, + ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprRawAddr, + ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary, + ExprUnsafe, ExprWhile, ExprYield, FieldValue, Index, Label, Lit, Member, PointerMutability, + RangeLimits, ReturnType, Stmt, Token, UnOp, }; impl Printer { - pub fn expr(&mut self, expr: &Expr) { + pub fn expr(&mut self, expr: &Expr, mut fixup: FixupContext) { + let needs_paren = fixup.parenthesize(expr); + if needs_paren { + self.word("("); + fixup = FixupContext::NONE; + } + let beginning_of_line = false; + match expr { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] Expr::Array(expr) => self.expr_array(expr), - Expr::Assign(expr) => self.expr_assign(expr), + Expr::Assign(expr) => self.expr_assign(expr, fixup), Expr::Async(expr) => self.expr_async(expr), - Expr::Await(expr) => self.expr_await(expr, beginning_of_line), - Expr::Binary(expr) => self.expr_binary(expr), + Expr::Await(expr) => self.expr_await(expr, beginning_of_line, fixup), + Expr::Binary(expr) => self.expr_binary(expr, fixup), Expr::Block(expr) => self.expr_block(expr), - Expr::Break(expr) => self.expr_break(expr), - Expr::Call(expr) => self.expr_call(expr, beginning_of_line), - Expr::Cast(expr) => self.expr_cast(expr), - Expr::Closure(expr) => self.expr_closure(expr), + Expr::Break(expr) => self.expr_break(expr, fixup), + Expr::Call(expr) => self.expr_call(expr, beginning_of_line, fixup), + Expr::Cast(expr) => self.expr_cast(expr, fixup), + Expr::Closure(expr) => self.expr_closure(expr, fixup), Expr::Const(expr) => self.expr_const(expr), Expr::Continue(expr) => self.expr_continue(expr), - Expr::Field(expr) => self.expr_field(expr, beginning_of_line), + Expr::Field(expr) => self.expr_field(expr, beginning_of_line, fixup), Expr::ForLoop(expr) => self.expr_for_loop(expr), - Expr::Group(expr) => self.expr_group(expr), + Expr::Group(expr) => self.expr_group(expr, fixup), Expr::If(expr) => self.expr_if(expr), - Expr::Index(expr) => self.expr_index(expr, beginning_of_line), + Expr::Index(expr) => self.expr_index(expr, beginning_of_line, fixup), Expr::Infer(expr) => self.expr_infer(expr), - Expr::Let(expr) => self.expr_let(expr), + Expr::Let(expr) => self.expr_let(expr, fixup), Expr::Lit(expr) => self.expr_lit(expr), Expr::Loop(expr) => self.expr_loop(expr), Expr::Macro(expr) => self.expr_macro(expr), Expr::Match(expr) => self.expr_match(expr), - Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line), + Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line, fixup), Expr::Paren(expr) => self.expr_paren(expr), Expr::Path(expr) => self.expr_path(expr), - Expr::Range(expr) => self.expr_range(expr), - Expr::Reference(expr) => self.expr_reference(expr), + Expr::Range(expr) => self.expr_range(expr, fixup), + Expr::RawAddr(expr) => self.expr_raw_addr(expr, fixup), + Expr::Reference(expr) => self.expr_reference(expr, fixup), Expr::Repeat(expr) => self.expr_repeat(expr), - Expr::Return(expr) => self.expr_return(expr), + Expr::Return(expr) => self.expr_return(expr, fixup), Expr::Struct(expr) => self.expr_struct(expr), - Expr::Try(expr) => self.expr_try(expr, beginning_of_line), + Expr::Try(expr) => self.expr_try(expr, beginning_of_line, fixup), Expr::TryBlock(expr) => self.expr_try_block(expr), Expr::Tuple(expr) => self.expr_tuple(expr), - Expr::Unary(expr) => self.expr_unary(expr), + Expr::Unary(expr) => self.expr_unary(expr, fixup), Expr::Unsafe(expr) => self.expr_unsafe(expr), - Expr::Verbatim(expr) => self.expr_verbatim(expr), + Expr::Verbatim(expr) => self.expr_verbatim(expr, fixup), Expr::While(expr) => self.expr_while(expr), - Expr::Yield(expr) => self.expr_yield(expr), + Expr::Yield(expr) => self.expr_yield(expr, fixup), _ => unimplemented!("unknown Expr"), } + + if needs_paren { + self.word(")"); + } } - pub fn expr_beginning_of_line(&mut self, expr: &Expr, beginning_of_line: bool) { + pub fn expr_beginning_of_line( + &mut self, + expr: &Expr, + mut needs_paren: bool, + beginning_of_line: bool, + mut fixup: FixupContext, + ) { + needs_paren |= fixup.parenthesize(expr); + if needs_paren { + self.word("("); + fixup = FixupContext::NONE; + } + match expr { - Expr::Await(expr) => self.expr_await(expr, beginning_of_line), - Expr::Field(expr) => self.expr_field(expr, beginning_of_line), - Expr::Index(expr) => self.expr_index(expr, beginning_of_line), - Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line), - Expr::Try(expr) => self.expr_try(expr, beginning_of_line), - _ => self.expr(expr), + Expr::Await(expr) => self.expr_await(expr, beginning_of_line, fixup), + Expr::Field(expr) => self.expr_field(expr, beginning_of_line, fixup), + Expr::Index(expr) => self.expr_index(expr, beginning_of_line, fixup), + Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line, fixup), + Expr::Try(expr) => self.expr_try(expr, beginning_of_line, fixup), + _ => self.expr(expr, fixup), + } + + if needs_paren { + self.word(")"); } } - fn subexpr(&mut self, expr: &Expr, beginning_of_line: bool) { + fn prefix_subexpr( + &mut self, + expr: &Expr, + mut needs_paren: bool, + beginning_of_line: bool, + mut fixup: FixupContext, + ) { + needs_paren |= fixup.parenthesize(expr); + if needs_paren { + self.word("("); + fixup = FixupContext::NONE; + } + match expr { - Expr::Await(expr) => self.subexpr_await(expr, beginning_of_line), - Expr::Call(expr) => self.subexpr_call(expr), - Expr::Field(expr) => self.subexpr_field(expr, beginning_of_line), - Expr::Index(expr) => self.subexpr_index(expr, beginning_of_line), + Expr::Await(expr) => self.prefix_subexpr_await(expr, beginning_of_line, fixup), + Expr::Call(expr) => self.prefix_subexpr_call(expr, fixup), + Expr::Field(expr) => self.prefix_subexpr_field(expr, beginning_of_line, fixup), + Expr::Index(expr) => self.prefix_subexpr_index(expr, beginning_of_line, fixup), Expr::MethodCall(expr) => { let unindent_call_args = false; - self.subexpr_method_call(expr, beginning_of_line, unindent_call_args); + self.prefix_subexpr_method_call(expr, beginning_of_line, unindent_call_args, fixup); } - Expr::Try(expr) => self.subexpr_try(expr, beginning_of_line), + Expr::Try(expr) => self.prefix_subexpr_try(expr, beginning_of_line, fixup), _ => { self.cbox(-INDENT); - self.expr(expr); + self.expr(expr, fixup); self.end(); } } - } - fn wrap_exterior_struct(&mut self, expr: &Expr) { - let needs_paren = contains_exterior_struct_lit(expr); - if needs_paren { - self.word("("); - } - self.cbox(0); - self.expr(expr); if needs_paren { self.word(")"); } + } + + fn expr_condition(&mut self, expr: &Expr) { + self.cbox(0); + self.expr(expr, FixupContext::new_condition()); if needs_newline_if_wrap(expr) { self.space(); } else { @@ -112,26 +152,75 @@ impl Printer { self.end(); } + pub fn subexpr(&mut self, expr: &Expr, needs_paren: bool, mut fixup: FixupContext) { + if needs_paren { + self.word("("); + fixup = FixupContext::NONE; + } + + self.expr(expr, fixup); + + if needs_paren { + self.word(")"); + } + } + fn expr_array(&mut self, expr: &ExprArray) { self.outer_attrs(&expr.attrs); - self.word("["); - self.cbox(INDENT); - self.zerobreak(); - for element in expr.elems.iter().delimited() { - self.expr(&element); - self.trailing_comma(element.is_last); + if expr.elems.is_empty() { + self.word("[]"); + } else if simple_array(&expr.elems) { + self.cbox(INDENT); + self.word("["); + self.zerobreak(); + self.ibox(0); + for elem in expr.elems.iter().delimited() { + self.expr(&elem, FixupContext::NONE); + if !elem.is_last { + self.word(","); + self.space(); + } + } + self.end(); + self.trailing_comma(true); + self.offset(-INDENT); + self.word("]"); + self.end(); + } else { + self.word("["); + self.cbox(INDENT); + self.zerobreak(); + for elem in expr.elems.iter().delimited() { + self.expr(&elem, FixupContext::NONE); + self.trailing_comma(elem.is_last); + } + self.offset(-INDENT); + self.end(); + self.word("]"); } - self.offset(-INDENT); - self.end(); - self.word("]"); } - fn expr_assign(&mut self, expr: &ExprAssign) { + fn expr_assign(&mut self, expr: &ExprAssign, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.left, + false, + false, + Precedence::Assign, + ); + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign); + self.outer_attrs(&expr.attrs); self.ibox(0); - self.expr(&expr.left); + if !expr.attrs.is_empty() { + self.word("("); + } + self.subexpr(&expr.left, left_prec <= Precedence::Range, left_fixup); self.word(" = "); - self.expr(&expr.right); + self.neverbreak(); + self.expr(&expr.right, right_fixup); + if !expr.attrs.is_empty() { + self.word(")"); + } self.end(); } @@ -146,29 +235,81 @@ impl Printer { self.end(); } - fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) { + fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.cbox(INDENT); - self.subexpr_await(expr, beginning_of_line); + self.prefix_subexpr_await(expr, beginning_of_line, fixup); self.end(); } - fn subexpr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) { - self.subexpr(&expr.base, beginning_of_line); - self.zerobreak_unless_short_ident(beginning_of_line, &expr.base); + fn prefix_subexpr_await( + &mut self, + expr: &ExprAwait, + beginning_of_line: bool, + fixup: FixupContext, + ) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.base); + + self.prefix_subexpr( + &expr.base, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); + if !(beginning_of_line && is_short_ident(&expr.base)) { + self.scan_break(BreakToken { + no_break: self.ends_with('.').then_some(' '), + ..BreakToken::default() + }); + } self.word(".await"); } - fn expr_binary(&mut self, expr: &ExprBinary) { + fn expr_binary(&mut self, expr: &ExprBinary, fixup: FixupContext) { + let binop_prec = Precedence::of_binop(&expr.op); + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.left, + match &expr.op { + BinOp::Sub(_) + | BinOp::Mul(_) + | BinOp::And(_) + | BinOp::Or(_) + | BinOp::BitAnd(_) + | BinOp::BitOr(_) + | BinOp::Shl(_) + | BinOp::Lt(_) => true, + _ => false, + }, + match &expr.op { + BinOp::Shl(_) | BinOp::Lt(_) => true, + _ => false, + }, + binop_prec, + ); + let left_needs_group = match binop_prec { + Precedence::Assign => left_prec <= Precedence::Range, + Precedence::Compare => left_prec <= binop_prec, + _ => left_prec < binop_prec, + }; + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, binop_prec); + let right_needs_group = binop_prec != Precedence::Assign + && right_fixup.rightmost_subexpression_precedence(&expr.right) <= binop_prec; + self.outer_attrs(&expr.attrs); self.ibox(INDENT); self.ibox(-INDENT); - self.expr(&expr.left); + if !expr.attrs.is_empty() { + self.word("("); + } + self.subexpr(&expr.left, left_needs_group, left_fixup); self.end(); self.space(); self.binary_operator(&expr.op); self.nbsp(); - self.expr(&expr.right); + self.subexpr(&expr.right, right_needs_group, right_fixup); + if !expr.attrs.is_empty() { + self.word(")"); + } self.end(); } @@ -182,7 +323,7 @@ impl Printer { self.end(); } - fn expr_break(&mut self, expr: &ExprBreak) { + fn expr_break(&mut self, expr: &ExprBreak, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.word("break"); if let Some(lifetime) = &expr.label { @@ -191,39 +332,76 @@ impl Printer { } if let Some(value) = &expr.expr { self.nbsp(); - self.expr(value); + self.subexpr( + value, + expr.label.is_none() && classify::expr_leading_label(value), + fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump), + ); } } - fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool) { + fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.func, + true, + false, + Precedence::Unambiguous, + ); + let needs_paren = if let Expr::Field(func) = &*expr.func { + matches!(func.member, Member::Named(_)) + } else { + left_prec < Precedence::Unambiguous + }; + self.outer_attrs(&expr.attrs); - self.expr_beginning_of_line(&expr.func, beginning_of_line); + self.expr_beginning_of_line(&expr.func, needs_paren, beginning_of_line, left_fixup); self.word("("); self.call_args(&expr.args); self.word(")"); } - fn subexpr_call(&mut self, expr: &ExprCall) { + fn prefix_subexpr_call(&mut self, expr: &ExprCall, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.func, + true, + false, + Precedence::Unambiguous, + ); + let needs_paren = if let Expr::Field(func) = &*expr.func { + matches!(func.member, Member::Named(_)) + } else { + left_prec < Precedence::Unambiguous + }; + let beginning_of_line = false; - self.subexpr(&expr.func, beginning_of_line); + self.prefix_subexpr(&expr.func, needs_paren, beginning_of_line, left_fixup); self.word("("); self.call_args(&expr.args); self.word(")"); } - fn expr_cast(&mut self, expr: &ExprCast) { + fn expr_cast(&mut self, expr: &ExprCast, fixup: FixupContext) { + let (left_prec, left_fixup) = + fixup.leftmost_subexpression_with_operator(&expr.expr, false, false, Precedence::Cast); + self.outer_attrs(&expr.attrs); self.ibox(INDENT); self.ibox(-INDENT); - self.expr(&expr.expr); + if !expr.attrs.is_empty() { + self.word("("); + } + self.subexpr(&expr.expr, left_prec < Precedence::Cast, left_fixup); self.end(); self.space(); self.word("as "); self.ty(&expr.ty); + if !expr.attrs.is_empty() { + self.word(")"); + } self.end(); } - fn expr_closure(&mut self, expr: &ExprClosure) { + fn expr_closure(&mut self, expr: &ExprClosure, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.ibox(0); if let Some(bound_lifetimes) = &expr.lifetimes { @@ -232,9 +410,6 @@ impl Printer { if expr.constness.is_some() { self.word("const "); } - if expr.movability.is_some() { - self.word("static "); - } if expr.asyncness.is_some() { self.word("async "); } @@ -273,16 +448,22 @@ impl Printer { pre_break: Some(if okay_to_brace { '{' } else { '(' }), ..BreakToken::default() }); - self.expr(&expr.body); + self.expr( + &expr.body, + fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump), + ); self.scan_break(BreakToken { offset: -INDENT, - pre_break: (okay_to_brace && stmt::add_semi(&expr.body)).then(|| ';'), - post_break: Some(if okay_to_brace { '}' } else { ')' }), + pre_break: (okay_to_brace && stmt::add_semi(&expr.body)).then_some(';'), + post_break: if okay_to_brace { "}" } else { ")" }, ..BreakToken::default() }); self.end(); } else { - self.expr(&expr.body); + self.expr( + &expr.body, + fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump), + ); } } ReturnType::Type(_arrow, ty) => { @@ -296,7 +477,17 @@ impl Printer { self.ty(ty); self.nbsp(); self.neverbreak(); - self.expr(&expr.body); + if matches!(&*expr.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none()) + { + self.expr( + &expr.body, + fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump), + ); + } else { + self.cbox(INDENT); + self.expr_as_small_block(&expr.body, 0); + self.end(); + } } } self.end(); @@ -319,16 +510,33 @@ impl Printer { } } - fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool) { + fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.cbox(INDENT); - self.subexpr_field(expr, beginning_of_line); + self.prefix_subexpr_field(expr, beginning_of_line, fixup); self.end(); } - fn subexpr_field(&mut self, expr: &ExprField, beginning_of_line: bool) { - self.subexpr(&expr.base, beginning_of_line); - self.zerobreak_unless_short_ident(beginning_of_line, &expr.base); + fn prefix_subexpr_field( + &mut self, + expr: &ExprField, + beginning_of_line: bool, + fixup: FixupContext, + ) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.base); + + self.prefix_subexpr( + &expr.base, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); + if !(beginning_of_line && is_short_ident(&expr.base)) { + self.scan_break(BreakToken { + no_break: self.ends_with('.').then_some(' '), + ..BreakToken::default() + }); + } self.word("."); self.member(&expr.member); } @@ -343,14 +551,14 @@ impl Printer { self.pat(&expr.pat); self.word(" in "); self.neverbreak(); - self.wrap_exterior_struct(&expr.expr); + self.expr_condition(&expr.expr); self.word("{"); self.neverbreak(); self.cbox(INDENT); self.hardbreak_if_nonempty(); self.inner_attrs(&expr.attrs); - for stmt in &expr.body.stmts { - self.stmt(stmt); + for stmt in expr.body.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -358,9 +566,9 @@ impl Printer { self.end(); } - fn expr_group(&mut self, expr: &ExprGroup) { + fn expr_group(&mut self, expr: &ExprGroup, fixup: FixupContext) { self.outer_attrs(&expr.attrs); - self.expr(&expr.expr); + self.expr(&expr.expr, fixup); } fn expr_if(&mut self, expr: &ExprIf) { @@ -368,7 +576,7 @@ impl Printer { self.cbox(INDENT); self.word("if "); self.cbox(-INDENT); - self.wrap_exterior_struct(&expr.cond); + self.expr_condition(&expr.cond); self.end(); if let Some((_else_token, else_branch)) = &expr.else_branch { let mut else_branch = &**else_branch; @@ -379,7 +587,7 @@ impl Printer { Expr::If(expr) => { self.word("if "); self.cbox(-INDENT); - self.wrap_exterior_struct(&expr.cond); + self.expr_condition(&expr.cond); self.end(); self.small_block(&expr.then_branch, &[]); if let Some((_else_token, next)) = &expr.else_branch { @@ -392,16 +600,7 @@ impl Printer { } // If not one of the valid expressions to exist in an else // clause, wrap in a block. - other => { - self.word("{"); - self.space(); - self.ibox(INDENT); - self.expr(other); - self.end(); - self.space(); - self.offset(-INDENT); - self.word("}"); - } + other => self.expr_as_small_block(other, INDENT), } break; } @@ -410,8 +609,8 @@ impl Printer { } else { self.word("{"); self.hardbreak(); - for stmt in &expr.then_branch.stmts { - self.stmt(stmt); + for stmt in expr.then_branch.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.word("}"); @@ -419,18 +618,47 @@ impl Printer { self.end(); } - fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) { + fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.expr, + true, + false, + Precedence::Unambiguous, + ); + self.outer_attrs(&expr.attrs); - self.expr_beginning_of_line(&expr.expr, beginning_of_line); + self.expr_beginning_of_line( + &expr.expr, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); self.word("["); - self.expr(&expr.index); + self.expr(&expr.index, FixupContext::NONE); self.word("]"); } - fn subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) { - self.subexpr(&expr.expr, beginning_of_line); + fn prefix_subexpr_index( + &mut self, + expr: &ExprIndex, + beginning_of_line: bool, + fixup: FixupContext, + ) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( + &expr.expr, + true, + false, + Precedence::Unambiguous, + ); + + self.prefix_subexpr( + &expr.expr, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); self.word("["); - self.expr(&expr.index); + self.expr(&expr.index, FixupContext::NONE); self.word("]"); } @@ -439,7 +667,9 @@ impl Printer { self.word("_"); } - fn expr_let(&mut self, expr: &ExprLet) { + fn expr_let(&mut self, expr: &ExprLet, fixup: FixupContext) { + let (right_prec, right_fixup) = fixup.rightmost_subexpression(&expr.expr, Precedence::Let); + self.outer_attrs(&expr.attrs); self.ibox(0); self.word("let "); @@ -449,14 +679,7 @@ impl Printer { self.word(" = "); self.neverbreak(); self.ibox(0); - let needs_paren = contains_exterior_struct_lit(&expr.expr); - if needs_paren { - self.word("("); - } - self.expr(&expr.expr); - if needs_paren { - self.word(")"); - } + self.subexpr(&expr.expr, right_prec < Precedence::Let, right_fixup); self.end(); self.end(); } @@ -475,8 +698,8 @@ impl Printer { self.cbox(INDENT); self.hardbreak_if_nonempty(); self.inner_attrs(&expr.attrs); - for stmt in &expr.body.stmts { - self.stmt(stmt); + for stmt in expr.body.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -493,7 +716,7 @@ impl Printer { self.outer_attrs(&expr.attrs); self.ibox(0); self.word("match "); - self.wrap_exterior_struct(&expr.expr); + self.expr_condition(&expr.expr); self.word("{"); self.neverbreak(); self.cbox(INDENT); @@ -509,22 +732,40 @@ impl Printer { self.end(); } - fn expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool) { + fn expr_method_call( + &mut self, + expr: &ExprMethodCall, + beginning_of_line: bool, + fixup: FixupContext, + ) { self.outer_attrs(&expr.attrs); self.cbox(INDENT); let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver); - self.subexpr_method_call(expr, beginning_of_line, unindent_call_args); + self.prefix_subexpr_method_call(expr, beginning_of_line, unindent_call_args, fixup); self.end(); } - fn subexpr_method_call( + fn prefix_subexpr_method_call( &mut self, expr: &ExprMethodCall, beginning_of_line: bool, unindent_call_args: bool, + fixup: FixupContext, ) { - self.subexpr(&expr.receiver, beginning_of_line); - self.zerobreak_unless_short_ident(beginning_of_line, &expr.receiver); + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.receiver); + + self.prefix_subexpr( + &expr.receiver, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); + if !(beginning_of_line && is_short_ident(&expr.receiver)) { + self.scan_break(BreakToken { + no_break: self.ends_with('.').then_some(' '), + ..BreakToken::default() + }); + } self.word("."); self.ident(&expr.method); if let Some(turbofish) = &expr.turbofish { @@ -540,7 +781,7 @@ impl Printer { fn expr_paren(&mut self, expr: &ExprParen) { self.outer_attrs(&expr.attrs); self.word("("); - self.expr(&expr.expr); + self.expr(&expr.expr, FixupContext::NONE); self.word(")"); } @@ -549,44 +790,73 @@ impl Printer { self.qpath(&expr.qself, &expr.path, PathKind::Expr); } - pub fn expr_range(&mut self, expr: &ExprRange) { + pub fn expr_range(&mut self, expr: &ExprRange, fixup: FixupContext) { self.outer_attrs(&expr.attrs); + if !expr.attrs.is_empty() { + self.word("("); + } if let Some(start) = &expr.start { - self.expr(start); + let (left_prec, left_fixup) = + fixup.leftmost_subexpression_with_operator(start, true, false, Precedence::Range); + self.subexpr(start, left_prec <= Precedence::Range, left_fixup); + } else if self.ends_with('.') { + self.nbsp(); } self.word(match expr.limits { RangeLimits::HalfOpen(_) => "..", RangeLimits::Closed(_) => "..=", }); if let Some(end) = &expr.end { - self.expr(end); + let right_fixup = fixup.rightmost_subexpression_fixup(false, true, Precedence::Range); + let right_prec = right_fixup.rightmost_subexpression_precedence(end); + self.subexpr(end, right_prec <= Precedence::Range, right_fixup); } + if !expr.attrs.is_empty() { + self.word(")"); + } + } + + fn expr_raw_addr(&mut self, expr: &ExprRawAddr, fixup: FixupContext) { + let (right_prec, right_fixup) = + fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix); + + self.outer_attrs(&expr.attrs); + self.word("&raw "); + self.pointer_mutability(&expr.mutability); + self.nbsp(); + self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup); } - fn expr_reference(&mut self, expr: &ExprReference) { + fn expr_reference(&mut self, expr: &ExprReference, fixup: FixupContext) { + let (right_prec, right_fixup) = + fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix); + self.outer_attrs(&expr.attrs); self.word("&"); if expr.mutability.is_some() { self.word("mut "); } - self.expr(&expr.expr); + self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup); } fn expr_repeat(&mut self, expr: &ExprRepeat) { self.outer_attrs(&expr.attrs); self.word("["); - self.expr(&expr.expr); + self.expr(&expr.expr, FixupContext::NONE); self.word("; "); - self.expr(&expr.len); + self.expr(&expr.len, FixupContext::NONE); self.word("]"); } - fn expr_return(&mut self, expr: &ExprReturn) { + fn expr_return(&mut self, expr: &ExprReturn, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.word("return"); if let Some(value) = &expr.expr { self.nbsp(); - self.expr(value); + self.expr( + value, + fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump), + ); } } @@ -604,7 +874,7 @@ impl Printer { } if let Some(rest) = &expr.rest { self.word(".."); - self.expr(rest); + self.expr(rest, FixupContext::NONE); self.space(); } self.offset(-INDENT); @@ -612,14 +882,28 @@ impl Printer { self.word("}"); } - fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) { + fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.expr); + self.outer_attrs(&expr.attrs); - self.expr_beginning_of_line(&expr.expr, beginning_of_line); + self.expr_beginning_of_line( + &expr.expr, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); self.word("?"); } - fn subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) { - self.subexpr(&expr.expr, beginning_of_line); + fn prefix_subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext) { + let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.expr); + + self.prefix_subexpr( + &expr.expr, + left_prec < Precedence::Unambiguous, + beginning_of_line, + left_fixup, + ); self.word("?"); } @@ -637,7 +921,7 @@ impl Printer { self.cbox(INDENT); self.zerobreak(); for elem in expr.elems.iter().delimited() { - self.expr(&elem); + self.expr(&elem, FixupContext::NONE); if expr.elems.len() == 1 { self.word(","); self.zerobreak(); @@ -650,10 +934,13 @@ impl Printer { self.word(")"); } - fn expr_unary(&mut self, expr: &ExprUnary) { + fn expr_unary(&mut self, expr: &ExprUnary, fixup: FixupContext) { + let (right_prec, right_fixup) = + fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix); + self.outer_attrs(&expr.attrs); self.unary_operator(&expr.op); - self.expr(&expr.expr); + self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup); } fn expr_unsafe(&mut self, expr: &ExprUnsafe) { @@ -665,14 +952,14 @@ impl Printer { } #[cfg(not(feature = "verbatim"))] - fn expr_verbatim(&mut self, expr: &TokenStream) { + fn expr_verbatim(&mut self, expr: &TokenStream, _fixup: FixupContext) { if !expr.is_empty() { unimplemented!("Expr::Verbatim `{}`", expr); } } #[cfg(feature = "verbatim")] - fn expr_verbatim(&mut self, tokens: &TokenStream) { + fn expr_verbatim(&mut self, tokens: &TokenStream, fixup: FixupContext) { use syn::parse::discouraged::Speculative; use syn::parse::{Parse, ParseStream, Result}; use syn::{parenthesized, Ident}; @@ -680,20 +967,19 @@ impl Printer { enum ExprVerbatim { Empty, Ellipsis, + Become(Become), Builtin(Builtin), - RawReference(RawReference), } - struct Builtin { + struct Become { attrs: Vec, - name: Ident, - args: TokenStream, + tail_call: Expr, } - struct RawReference { + struct Builtin { attrs: Vec, - mutable: bool, - expr: Expr, + name: Ident, + args: TokenStream, } mod kw { @@ -708,6 +994,11 @@ impl Printer { let lookahead = ahead.lookahead1(); if input.is_empty() { Ok(ExprVerbatim::Empty) + } else if lookahead.peek(Token![become]) { + input.advance_to(&ahead); + input.parse::()?; + let tail_call: Expr = input.parse()?; + Ok(ExprVerbatim::Become(Become { attrs, tail_call })) } else if lookahead.peek(kw::builtin) { input.advance_to(&ahead); input.parse::()?; @@ -717,20 +1008,6 @@ impl Printer { parenthesized!(args in input); let args: TokenStream = args.parse()?; Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args })) - } else if lookahead.peek(Token![&]) { - input.advance_to(&ahead); - input.parse::()?; - input.parse::()?; - let mutable = input.parse::>()?.is_some(); - if !mutable { - input.parse::()?; - } - let expr: Expr = input.parse()?; - Ok(ExprVerbatim::RawReference(RawReference { - attrs, - mutable, - expr, - })) } else if lookahead.peek(Token![...]) { input.parse::()?; Ok(ExprVerbatim::Ellipsis) @@ -750,6 +1027,15 @@ impl Printer { ExprVerbatim::Ellipsis => { self.word("..."); } + ExprVerbatim::Become(expr) => { + self.outer_attrs(&expr.attrs); + self.word("become"); + self.nbsp(); + self.expr( + &expr.tail_call, + fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump), + ); + } ExprVerbatim::Builtin(expr) => { self.outer_attrs(&expr.attrs); self.word("builtin # "); @@ -767,12 +1053,6 @@ impl Printer { } self.word(")"); } - ExprVerbatim::RawReference(expr) => { - self.outer_attrs(&expr.attrs); - self.word("&raw "); - self.word(if expr.mutable { "mut " } else { "const " }); - self.expr(&expr.expr); - } } } @@ -782,26 +1062,29 @@ impl Printer { self.label(label); } self.word("while "); - self.wrap_exterior_struct(&expr.cond); + self.expr_condition(&expr.cond); self.word("{"); self.neverbreak(); self.cbox(INDENT); self.hardbreak_if_nonempty(); self.inner_attrs(&expr.attrs); - for stmt in &expr.body.stmts { - self.stmt(stmt); + for stmt in expr.body.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); self.word("}"); } - fn expr_yield(&mut self, expr: &ExprYield) { + fn expr_yield(&mut self, expr: &ExprYield, fixup: FixupContext) { self.outer_attrs(&expr.attrs); self.word("yield"); if let Some(value) = &expr.expr { self.nbsp(); - self.expr(value); + self.expr( + value, + fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump), + ); } } @@ -816,7 +1099,7 @@ impl Printer { if field_value.colon_token.is_some() { self.word(": "); self.ibox(0); - self.expr(&field_value.expr); + self.expr(&field_value.expr, FixupContext::NONE); self.end(); } } @@ -825,11 +1108,7 @@ impl Printer { self.outer_attrs(&arm.attrs); self.ibox(0); self.pat(&arm.pat); - if let Some((_if_token, guard)) = &arm.guard { - self.word(" if "); - self.expr(guard); - } - self.word(" =>"); + self.word(" => "); let empty_block; let mut body = &*arm.body; while let Expr::Block(expr) = body { @@ -856,7 +1135,6 @@ impl Printer { } } if let Expr::Block(body) = body { - self.nbsp(); if let Some(label) = &body.label { self.label(label); } @@ -865,45 +1143,44 @@ impl Printer { self.cbox(INDENT); self.hardbreak_if_nonempty(); self.inner_attrs(&body.attrs); - for stmt in &body.block.stmts { - self.stmt(stmt); + for stmt in body.block.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); self.word("}"); - self.end(); } else { - self.nbsp(); self.neverbreak(); self.cbox(INDENT); + let okay_to_brace = parseable_as_stmt(body); self.scan_break(BreakToken { - pre_break: Some('{'), + pre_break: Some(if okay_to_brace { '{' } else { '(' }), ..BreakToken::default() }); - self.expr_beginning_of_line(body, true); + self.expr_beginning_of_line(body, false, true, FixupContext::new_match_arm()); self.scan_break(BreakToken { offset: -INDENT, - pre_break: stmt::add_semi(body).then(|| ';'), - post_break: Some('}'), - no_break: requires_terminator(body).then(|| ','), + pre_break: (okay_to_brace && stmt::add_semi(body)).then_some(';'), + post_break: if okay_to_brace { "}" } else { ")," }, + no_break: classify::requires_comma_to_be_match_arm(body).then_some(','), ..BreakToken::default() }); self.end(); - self.end(); } + self.end(); } fn call_args(&mut self, args: &Punctuated) { let mut iter = args.iter(); match (iter.next(), iter.next()) { (Some(expr), None) if is_blocklike(expr) => { - self.expr(expr); + self.expr(expr, FixupContext::NONE); } _ => { self.cbox(INDENT); self.zerobreak(); for arg in args.iter().delimited() { - self.expr(&arg); + self.expr(&arg, FixupContext::NONE); self.trailing_comma(arg.is_last); } self.offset(-INDENT); @@ -920,13 +1197,13 @@ impl Printer { match block.stmts.as_slice() { [Stmt::Expr(expr, None)] if stmt::break_after(expr) => { self.ibox(0); - self.expr_beginning_of_line(expr, true); + self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt()); self.end(); self.space(); } _ => { - for stmt in &block.stmts { - self.stmt(stmt); + for stmt in block.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } } } @@ -935,6 +1212,17 @@ impl Printer { self.word("}"); } + pub fn expr_as_small_block(&mut self, expr: &Expr, indent: isize) { + self.word("{"); + self.space(); + self.ibox(indent); + self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt()); + self.end(); + self.space(); + self.offset(-INDENT); + self.word("}"); + } + pub fn member(&mut self, member: &Member) { match member { Member::Named(ident) => self.ident(ident), @@ -995,119 +1283,11 @@ impl Printer { ); } - fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) { - if beginning_of_line && is_short_ident(expr) { - return; + fn pointer_mutability(&mut self, mutability: &PointerMutability) { + match mutability { + PointerMutability::Const(_) => self.word("const"), + PointerMutability::Mut(_) => self.word("mut"), } - self.zerobreak(); - } -} - -fn requires_terminator(expr: &Expr) -> bool { - // see https://github.com/rust-lang/rust/blob/a266f1199/compiler/rustc_ast/src/util/classify.rs#L7-L26 - match expr { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] - Expr::If(_) - | Expr::Match(_) - | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc - | Expr::While(_) - | Expr::Loop(_) - | Expr::ForLoop(_) - | Expr::TryBlock(_) - | Expr::Const(_) => false, - - Expr::Array(_) - | Expr::Assign(_) - | Expr::Async(_) - | Expr::Await(_) - | Expr::Binary(_) - | Expr::Break(_) - | Expr::Call(_) - | Expr::Cast(_) - | Expr::Closure(_) - | Expr::Continue(_) - | Expr::Field(_) - | Expr::Group(_) - | Expr::Index(_) - | Expr::Infer(_) - | Expr::Let(_) - | Expr::Lit(_) - | Expr::Macro(_) - | Expr::MethodCall(_) - | Expr::Paren(_) - | Expr::Path(_) - | Expr::Range(_) - | Expr::Reference(_) - | Expr::Repeat(_) - | Expr::Return(_) - | Expr::Struct(_) - | Expr::Try(_) - | Expr::Tuple(_) - | Expr::Unary(_) - | Expr::Verbatim(_) - | Expr::Yield(_) => true, - - _ => true, - } -} - -// Expressions that syntactically contain an "exterior" struct literal i.e. not -// surrounded by any parens or other delimiters. For example `X { y: 1 }`, `X { -// y: 1 }.method()`, `foo == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X -// { y: 1 }) == foo` does not. -fn contains_exterior_struct_lit(expr: &Expr) -> bool { - match expr { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] - Expr::Struct(_) => true, - - Expr::Assign(ExprAssign { left, right, .. }) - | Expr::Binary(ExprBinary { left, right, .. }) => { - // X { y: 1 } + X { y: 2 } - contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right) - } - - Expr::Await(ExprAwait { base: e, .. }) - | Expr::Cast(ExprCast { expr: e, .. }) - | Expr::Field(ExprField { base: e, .. }) - | Expr::Group(ExprGroup { expr: e, .. }) - | Expr::Index(ExprIndex { expr: e, .. }) - | Expr::MethodCall(ExprMethodCall { receiver: e, .. }) - | Expr::Reference(ExprReference { expr: e, .. }) - | Expr::Unary(ExprUnary { expr: e, .. }) => { - // &X { y: 1 }, X { y: 1 }.y - contains_exterior_struct_lit(e) - } - - Expr::Array(_) - | Expr::Async(_) - | Expr::Block(_) - | Expr::Break(_) - | Expr::Call(_) - | Expr::Closure(_) - | Expr::Const(_) - | Expr::Continue(_) - | Expr::ForLoop(_) - | Expr::If(_) - | Expr::Infer(_) - | Expr::Let(_) - | Expr::Lit(_) - | Expr::Loop(_) - | Expr::Macro(_) - | Expr::Match(_) - | Expr::Paren(_) - | Expr::Path(_) - | Expr::Range(_) - | Expr::Repeat(_) - | Expr::Return(_) - | Expr::Try(_) - | Expr::TryBlock(_) - | Expr::Tuple(_) - | Expr::Unsafe(_) - | Expr::Verbatim(_) - | Expr::While(_) - | Expr::Yield(_) => false, - - _ => false, } } @@ -1154,6 +1334,7 @@ fn needs_newline_if_wrap(expr: &Expr) -> bool { | Expr::Let(ExprLet { expr: e, .. }) | Expr::Paren(ExprParen { expr: e, .. }) | Expr::Range(ExprRange { end: Some(e), .. }) + | Expr::RawAddr(ExprRawAddr { expr: e, .. }) | Expr::Reference(ExprReference { expr: e, .. }) | Expr::Return(ExprReturn { expr: Some(e), .. }) | Expr::Try(ExprTry { expr: e, .. }) @@ -1171,7 +1352,7 @@ fn is_short_ident(expr: &Expr) -> bool { && expr .path .get_ident() - .map_or(false, |ident| ident.to_string().len() as isize <= INDENT); + .is_some_and(|ident| ident.to_string().len() as isize <= INDENT); } false } @@ -1198,7 +1379,6 @@ fn is_blocklike(expr: &Expr) -> bool { | Expr::Continue(_) | Expr::Field(_) | Expr::ForLoop(_) - | Expr::Group(_) | Expr::If(_) | Expr::Index(_) | Expr::Infer(_) @@ -1211,6 +1391,7 @@ fn is_blocklike(expr: &Expr) -> bool { | Expr::Paren(_) | Expr::Path(_) | Expr::Range(_) + | Expr::RawAddr(_) | Expr::Reference(_) | Expr::Repeat(_) | Expr::Return(_) @@ -1220,61 +1401,126 @@ fn is_blocklike(expr: &Expr) -> bool { | Expr::While(_) | Expr::Yield(_) => false, + Expr::Group(e) => is_blocklike(&e.expr), + _ => false, } } +pub fn simple_block(expr: &Expr) -> Option<&ExprBlock> { + if let Expr::Block(expr) = expr { + if expr.attrs.is_empty() && expr.label.is_none() { + return Some(expr); + } + } + None +} + +pub fn simple_array(elements: &Punctuated) -> bool { + for expr in elements { + if let Expr::Lit(expr) = expr { + match expr.lit { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Lit::Byte(_) | Lit::Char(_) | Lit::Int(_) | Lit::Bool(_) => {} + + Lit::Str(_) | Lit::ByteStr(_) | Lit::CStr(_) | Lit::Float(_) | Lit::Verbatim(_) => { + return false; + } + + _ => return false, + } + } else { + return false; + } + } + true +} + // Expressions for which `$expr` and `{ $expr }` mean the same thing. // // This is not the case for all expressions. For example `{} | x | x` has some // bitwise OR operators while `{ {} |x| x }` has a block followed by a closure. -fn parseable_as_stmt(expr: &Expr) -> bool { - match expr { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] - Expr::Array(_) - | Expr::Async(_) - | Expr::Block(_) - | Expr::Break(_) - | Expr::Closure(_) - | Expr::Const(_) - | Expr::Continue(_) - | Expr::ForLoop(_) - | Expr::If(_) - | Expr::Infer(_) - | Expr::Let(_) - | Expr::Lit(_) - | Expr::Loop(_) - | Expr::Macro(_) - | Expr::Match(_) - | Expr::Paren(_) - | Expr::Path(_) - | Expr::Reference(_) - | Expr::Repeat(_) - | Expr::Return(_) - | Expr::Struct(_) - | Expr::TryBlock(_) - | Expr::Tuple(_) - | Expr::Unary(_) - | Expr::Unsafe(_) - | Expr::Verbatim(_) - | Expr::While(_) - | Expr::Yield(_) => true, - - Expr::Assign(expr) => parseable_as_stmt(&expr.left), - Expr::Await(expr) => parseable_as_stmt(&expr.base), - Expr::Binary(expr) => requires_terminator(&expr.left) && parseable_as_stmt(&expr.left), - Expr::Call(expr) => requires_terminator(&expr.func) && parseable_as_stmt(&expr.func), - Expr::Cast(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr), - Expr::Field(expr) => parseable_as_stmt(&expr.base), - Expr::Group(expr) => parseable_as_stmt(&expr.expr), - Expr::Index(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr), - Expr::MethodCall(expr) => parseable_as_stmt(&expr.receiver), - Expr::Range(expr) => match &expr.start { - None => true, - Some(start) => requires_terminator(start) && parseable_as_stmt(start), - }, - Expr::Try(expr) => parseable_as_stmt(&expr.expr), +fn parseable_as_stmt(mut expr: &Expr) -> bool { + loop { + match expr { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::Array(_) + | Expr::Async(_) + | Expr::Block(_) + | Expr::Break(_) + | Expr::Closure(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::ForLoop(_) + | Expr::If(_) + | Expr::Infer(_) + | Expr::Lit(_) + | Expr::Loop(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::RawAddr(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::While(_) + | Expr::Yield(_) => return true, + + Expr::Let(_) => return false, + + Expr::Assign(e) => { + if !classify::requires_semi_to_be_stmt(&e.left) { + return false; + } + expr = &e.left; + } + Expr::Await(e) => expr = &e.base, + Expr::Binary(e) => { + if !classify::requires_semi_to_be_stmt(&e.left) { + return false; + } + expr = &e.left; + } + Expr::Call(e) => { + if !classify::requires_semi_to_be_stmt(&e.func) { + return false; + } + expr = &e.func; + } + Expr::Cast(e) => { + if !classify::requires_semi_to_be_stmt(&e.expr) { + return false; + } + expr = &e.expr; + } + Expr::Field(e) => expr = &e.base, + Expr::Group(e) => expr = &e.expr, + Expr::Index(e) => { + if !classify::requires_semi_to_be_stmt(&e.expr) { + return false; + } + expr = &e.expr; + } + Expr::MethodCall(e) => expr = &e.receiver, + Expr::Range(e) => match &e.start { + None => return true, + Some(start) => { + if !classify::requires_semi_to_be_stmt(start) { + return false; + } + expr = start; + } + }, + Expr::Try(e) => expr = &e.expr, - _ => false, + _ => return false, + } } } diff --git a/zerocopy/vendor/prettyplease/src/fixup.rs b/zerocopy/vendor/prettyplease/src/fixup.rs new file mode 100644 index 0000000000..2355d4905f --- /dev/null +++ b/zerocopy/vendor/prettyplease/src/fixup.rs @@ -0,0 +1,676 @@ +use crate::classify; +use crate::precedence::Precedence; +use syn::{ + Expr, ExprBreak, ExprRange, ExprRawAddr, ExprReference, ExprReturn, ExprUnary, ExprYield, +}; + +#[derive(Copy, Clone)] +pub struct FixupContext { + previous_operator: Precedence, + next_operator: Precedence, + + // Print expression such that it can be parsed back as a statement + // consisting of the original expression. + // + // The effect of this is for binary operators in statement position to set + // `leftmost_subexpression_in_stmt` when printing their left-hand operand. + // + // (match x {}) - 1; // match needs parens when LHS of binary operator + // + // match x {}; // not when its own statement + // + stmt: bool, + + // This is the difference between: + // + // (match x {}) - 1; // subexpression needs parens + // + // let _ = match x {} - 1; // no parens + // + // There are 3 distinguishable contexts in which `print_expr` might be + // called with the expression `$match` as its argument, where `$match` + // represents an expression of kind `ExprKind::Match`: + // + // - stmt=false leftmost_subexpression_in_stmt=false + // + // Example: `let _ = $match - 1;` + // + // No parentheses required. + // + // - stmt=false leftmost_subexpression_in_stmt=true + // + // Example: `$match - 1;` + // + // Must parenthesize `($match)`, otherwise parsing back the output as a + // statement would terminate the statement after the closing brace of + // the match, parsing `-1;` as a separate statement. + // + // - stmt=true leftmost_subexpression_in_stmt=false + // + // Example: `$match;` + // + // No parentheses required. + leftmost_subexpression_in_stmt: bool, + + // Print expression such that it can be parsed as a match arm. + // + // This is almost equivalent to `stmt`, but the grammar diverges a tiny bit + // between statements and match arms when it comes to braced macro calls. + // Macro calls with brace delimiter terminate a statement without a + // semicolon, but do not terminate a match-arm without comma. + // + // m! {} - 1; // two statements: a macro call followed by -1 literal + // + // match () { + // _ => m! {} - 1, // binary subtraction operator + // } + // + match_arm: bool, + + // This is almost equivalent to `leftmost_subexpression_in_stmt`, other than + // for braced macro calls. + // + // If we have `m! {} - 1` as an expression, the leftmost subexpression + // `m! {}` will need to be parenthesized in the statement case but not the + // match-arm case. + // + // (m! {}) - 1; // subexpression needs parens + // + // match () { + // _ => m! {} - 1, // no parens + // } + // + leftmost_subexpression_in_match_arm: bool, + + // This is the difference between: + // + // if let _ = (Struct {}) {} // needs parens + // + // match () { + // () if let _ = Struct {} => {} // no parens + // } + // + condition: bool, + + // This is the difference between: + // + // if break Struct {} == (break) {} // needs parens + // + // if break break == Struct {} {} // no parens + // + rightmost_subexpression_in_condition: bool, + + // This is the difference between: + // + // if break ({ x }).field + 1 {} needs parens + // + // if break 1 + { x }.field {} // no parens + // + leftmost_subexpression_in_optional_operand: bool, + + // This is the difference between: + // + // let _ = (return) - 1; // without paren, this would return -1 + // + // let _ = return + 1; // no paren because '+' cannot begin expr + // + next_operator_can_begin_expr: bool, + + // This is the difference between: + // + // let _ = 1 + return 1; // no parens if rightmost subexpression + // + // let _ = 1 + (return 1) + 1; // needs parens + // + next_operator_can_continue_expr: bool, + + // This is the difference between: + // + // let _ = x as u8 + T; + // + // let _ = (x as u8) < T; + // + // Without parens, the latter would want to parse `u8 Self { + FixupContext { + stmt: true, + ..FixupContext::NONE + } + } + + /// Create the initial fixup for printing an expression as the right-hand + /// side of a match arm. + pub fn new_match_arm() -> Self { + FixupContext { + match_arm: true, + ..FixupContext::NONE + } + } + + /// Create the initial fixup for printing an expression as the "condition" + /// of an `if` or `while`. There are a few other positions which are + /// grammatically equivalent and also use this, such as the iterator + /// expression in `for` and the scrutinee in `match`. + pub fn new_condition() -> Self { + FixupContext { + condition: true, + rightmost_subexpression_in_condition: true, + ..FixupContext::NONE + } + } + + /// Transform this fixup into the one that should apply when printing the + /// leftmost subexpression of the current expression. + /// + /// The leftmost subexpression is any subexpression that has the same first + /// token as the current expression, but has a different last token. + /// + /// For example in `$a + $b` and `$a.method()`, the subexpression `$a` is a + /// leftmost subexpression. + /// + /// Not every expression has a leftmost subexpression. For example neither + /// `-$a` nor `[$a]` have one. + pub fn leftmost_subexpression_with_operator( + self, + expr: &Expr, + next_operator_can_begin_expr: bool, + next_operator_can_begin_generics: bool, + precedence: Precedence, + ) -> (Precedence, Self) { + let fixup = FixupContext { + next_operator: precedence, + stmt: false, + leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt, + match_arm: false, + leftmost_subexpression_in_match_arm: self.match_arm + || self.leftmost_subexpression_in_match_arm, + rightmost_subexpression_in_condition: false, + next_operator_can_begin_expr, + next_operator_can_continue_expr: true, + next_operator_can_begin_generics, + ..self + }; + + (fixup.leftmost_subexpression_precedence(expr), fixup) + } + + /// Transform this fixup into the one that should apply when printing a + /// leftmost subexpression followed by a `.` or `?` token, which confer + /// different statement boundary rules compared to other leftmost + /// subexpressions. + pub fn leftmost_subexpression_with_dot(self, expr: &Expr) -> (Precedence, Self) { + let fixup = FixupContext { + next_operator: Precedence::Unambiguous, + stmt: self.stmt || self.leftmost_subexpression_in_stmt, + leftmost_subexpression_in_stmt: false, + match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm, + leftmost_subexpression_in_match_arm: false, + rightmost_subexpression_in_condition: false, + next_operator_can_begin_expr: false, + next_operator_can_continue_expr: true, + next_operator_can_begin_generics: false, + ..self + }; + + (fixup.leftmost_subexpression_precedence(expr), fixup) + } + + fn leftmost_subexpression_precedence(self, expr: &Expr) -> Precedence { + if !self.next_operator_can_begin_expr || self.next_operator == Precedence::Range { + if let Scan::Bailout = scan_right(expr, self, Precedence::MIN, 0, 0) { + if scan_left(expr, self) { + return Precedence::Unambiguous; + } + } + } + + self.precedence(expr) + } + + /// Transform this fixup into the one that should apply when printing the + /// rightmost subexpression of the current expression. + /// + /// The rightmost subexpression is any subexpression that has a different + /// first token than the current expression, but has the same last token. + /// + /// For example in `$a + $b` and `-$b`, the subexpression `$b` is a + /// rightmost subexpression. + /// + /// Not every expression has a rightmost subexpression. For example neither + /// `[$b]` nor `$a.f($b)` have one. + pub fn rightmost_subexpression( + self, + expr: &Expr, + precedence: Precedence, + ) -> (Precedence, Self) { + let fixup = self.rightmost_subexpression_fixup(false, false, precedence); + (fixup.rightmost_subexpression_precedence(expr), fixup) + } + + pub fn rightmost_subexpression_fixup( + self, + reset_allow_struct: bool, + optional_operand: bool, + precedence: Precedence, + ) -> Self { + FixupContext { + previous_operator: precedence, + stmt: false, + leftmost_subexpression_in_stmt: false, + match_arm: false, + leftmost_subexpression_in_match_arm: false, + condition: self.condition && !reset_allow_struct, + leftmost_subexpression_in_optional_operand: self.condition && optional_operand, + ..self + } + } + + pub fn rightmost_subexpression_precedence(self, expr: &Expr) -> Precedence { + let default_prec = self.precedence(expr); + + if match self.previous_operator { + Precedence::Assign | Precedence::Let | Precedence::Prefix => { + default_prec < self.previous_operator + } + _ => default_prec <= self.previous_operator, + } && match self.next_operator { + Precedence::Range | Precedence::Or | Precedence::And => true, + _ => !self.next_operator_can_begin_expr, + } { + if let Scan::Bailout | Scan::Fail = scan_right(expr, self, self.previous_operator, 1, 0) + { + if scan_left(expr, self) { + return Precedence::Prefix; + } + } + } + + default_prec + } + + /// Determine whether parentheses are needed around the given expression to + /// head off the early termination of a statement or condition. + pub fn parenthesize(self, expr: &Expr) -> bool { + (self.leftmost_subexpression_in_stmt && !classify::requires_semi_to_be_stmt(expr)) + || ((self.stmt || self.leftmost_subexpression_in_stmt) && matches!(expr, Expr::Let(_))) + || (self.leftmost_subexpression_in_match_arm + && !classify::requires_comma_to_be_match_arm(expr)) + || (self.condition && matches!(expr, Expr::Struct(_))) + || (self.rightmost_subexpression_in_condition + && matches!( + expr, + Expr::Return(ExprReturn { expr: None, .. }) + | Expr::Yield(ExprYield { expr: None, .. }) + )) + || (self.rightmost_subexpression_in_condition + && !self.condition + && matches!( + expr, + Expr::Break(ExprBreak { expr: None, .. }) + | Expr::Path(_) + | Expr::Range(ExprRange { end: None, .. }) + )) + || (self.leftmost_subexpression_in_optional_operand + && matches!(expr, Expr::Block(expr) if expr.attrs.is_empty() && expr.label.is_none())) + } + + /// Determines the effective precedence of a subexpression. Some expressions + /// have higher or lower precedence when adjacent to particular operators. + fn precedence(self, expr: &Expr) -> Precedence { + if self.next_operator_can_begin_expr { + // Decrease precedence of value-less jumps when followed by an + // operator that would otherwise get interpreted as beginning a + // value for the jump. + if let Expr::Break(ExprBreak { expr: None, .. }) + | Expr::Return(ExprReturn { expr: None, .. }) + | Expr::Yield(ExprYield { expr: None, .. }) = expr + { + return Precedence::Jump; + } + } + + if !self.next_operator_can_continue_expr { + match expr { + // Increase precedence of expressions that extend to the end of + // current statement or group. + Expr::Break(_) + | Expr::Closure(_) + | Expr::Let(_) + | Expr::Return(_) + | Expr::Yield(_) => { + return Precedence::Prefix; + } + Expr::Range(e) if e.start.is_none() => return Precedence::Prefix, + _ => {} + } + } + + if self.next_operator_can_begin_generics { + if let Expr::Cast(cast) = expr { + if classify::trailing_unparameterized_path(&cast.ty) { + return Precedence::MIN; + } + } + } + + Precedence::of(expr) + } +} + +#[derive(Copy, Clone, PartialEq)] +enum Scan { + Fail, + Bailout, + Consume, +} + +fn scan_left(expr: &Expr, fixup: FixupContext) -> bool { + match expr { + Expr::Assign(_) => fixup.previous_operator <= Precedence::Assign, + Expr::Binary(e) => match Precedence::of_binop(&e.op) { + Precedence::Assign => fixup.previous_operator <= Precedence::Assign, + binop_prec => fixup.previous_operator < binop_prec, + }, + Expr::Cast(_) => fixup.previous_operator < Precedence::Cast, + Expr::Range(e) => e.start.is_none() || fixup.previous_operator < Precedence::Assign, + _ => true, + } +} + +fn scan_right( + expr: &Expr, + fixup: FixupContext, + precedence: Precedence, + fail_offset: u8, + bailout_offset: u8, +) -> Scan { + let consume_by_precedence = if match precedence { + Precedence::Assign | Precedence::Compare => precedence <= fixup.next_operator, + _ => precedence < fixup.next_operator, + } || fixup.next_operator == Precedence::MIN + { + Scan::Consume + } else { + Scan::Bailout + }; + if fixup.parenthesize(expr) { + return consume_by_precedence; + } + match expr { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::Assign(e) if e.attrs.is_empty() => { + if match fixup.next_operator { + Precedence::Unambiguous => fail_offset >= 2, + _ => bailout_offset >= 1, + } { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign); + let scan = scan_right( + &e.right, + right_fixup, + Precedence::Assign, + match fixup.next_operator { + Precedence::Unambiguous => fail_offset, + _ => 1, + }, + 1, + ); + if let Scan::Bailout | Scan::Consume = scan { + Scan::Consume + } else if let Precedence::Unambiguous = fixup.next_operator { + Scan::Fail + } else { + Scan::Bailout + } + } + Expr::Binary(e) if e.attrs.is_empty() => { + if match fixup.next_operator { + Precedence::Unambiguous => { + fail_offset >= 2 + && (consume_by_precedence == Scan::Consume || bailout_offset >= 1) + } + _ => bailout_offset >= 1, + } { + return Scan::Consume; + } + let binop_prec = Precedence::of_binop(&e.op); + if binop_prec == Precedence::Compare && fixup.next_operator == Precedence::Compare { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, binop_prec); + let scan = scan_right( + &e.right, + right_fixup, + binop_prec, + match fixup.next_operator { + Precedence::Unambiguous => fail_offset, + _ => 1, + }, + consume_by_precedence as u8 - Scan::Bailout as u8, + ); + match scan { + Scan::Fail => {} + Scan::Bailout => return consume_by_precedence, + Scan::Consume => return Scan::Consume, + } + let right_needs_group = binop_prec != Precedence::Assign + && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec; + if right_needs_group { + consume_by_precedence + } else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) { + Scan::Fail + } else { + Scan::Bailout + } + } + Expr::RawAddr(ExprRawAddr { expr, .. }) + | Expr::Reference(ExprReference { expr, .. }) + | Expr::Unary(ExprUnary { expr, .. }) => { + if match fixup.next_operator { + Precedence::Unambiguous => { + fail_offset >= 2 + && (consume_by_precedence == Scan::Consume || bailout_offset >= 1) + } + _ => bailout_offset >= 1, + } { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Prefix); + let scan = scan_right( + expr, + right_fixup, + precedence, + match fixup.next_operator { + Precedence::Unambiguous => fail_offset, + _ => 1, + }, + consume_by_precedence as u8 - Scan::Bailout as u8, + ); + match scan { + Scan::Fail => {} + Scan::Bailout => return consume_by_precedence, + Scan::Consume => return Scan::Consume, + } + if right_fixup.rightmost_subexpression_precedence(expr) < Precedence::Prefix { + consume_by_precedence + } else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) { + Scan::Fail + } else { + Scan::Bailout + } + } + Expr::Range(e) if e.attrs.is_empty() => match &e.end { + Some(end) => { + if fail_offset >= 2 { + return Scan::Consume; + } + let right_fixup = + fixup.rightmost_subexpression_fixup(false, true, Precedence::Range); + let scan = scan_right( + end, + right_fixup, + Precedence::Range, + fail_offset, + match fixup.next_operator { + Precedence::Assign | Precedence::Range => 0, + _ => 1, + }, + ); + if match (scan, fixup.next_operator) { + (Scan::Fail, _) => false, + (Scan::Bailout, Precedence::Assign | Precedence::Range) => false, + (Scan::Bailout | Scan::Consume, _) => true, + } { + return Scan::Consume; + } + if right_fixup.rightmost_subexpression_precedence(end) <= Precedence::Range { + Scan::Consume + } else { + Scan::Fail + } + } + None => { + if fixup.next_operator_can_begin_expr { + Scan::Consume + } else { + Scan::Fail + } + } + }, + Expr::Break(e) => match &e.expr { + Some(value) => { + if bailout_offset >= 1 || e.label.is_none() && classify::expr_leading_label(value) { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump); + match scan_right(value, right_fixup, Precedence::Jump, 1, 1) { + Scan::Fail => Scan::Bailout, + Scan::Bailout | Scan::Consume => Scan::Consume, + } + } + None => match fixup.next_operator { + Precedence::Assign if precedence > Precedence::Assign => Scan::Fail, + _ => Scan::Consume, + }, + }, + Expr::Return(ExprReturn { expr, .. }) | Expr::Yield(ExprYield { expr, .. }) => match expr { + Some(e) => { + if bailout_offset >= 1 { + return Scan::Consume; + } + let right_fixup = + fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump); + match scan_right(e, right_fixup, Precedence::Jump, 1, 1) { + Scan::Fail => Scan::Bailout, + Scan::Bailout | Scan::Consume => Scan::Consume, + } + } + None => match fixup.next_operator { + Precedence::Assign if precedence > Precedence::Assign => Scan::Fail, + _ => Scan::Consume, + }, + }, + Expr::Closure(_) => Scan::Consume, + Expr::Let(e) => { + if bailout_offset >= 1 { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Let); + let scan = scan_right( + &e.expr, + right_fixup, + Precedence::Let, + 1, + if fixup.next_operator < Precedence::Let { + 0 + } else { + 1 + }, + ); + match scan { + Scan::Fail | Scan::Bailout if fixup.next_operator < Precedence::Let => { + return Scan::Bailout; + } + Scan::Consume => return Scan::Consume, + _ => {} + } + if right_fixup.rightmost_subexpression_precedence(&e.expr) < Precedence::Let { + Scan::Consume + } else if let Scan::Fail = scan { + Scan::Bailout + } else { + Scan::Consume + } + } + Expr::Group(e) => scan_right(&e.expr, fixup, precedence, fail_offset, bailout_offset), + Expr::Array(_) + | Expr::Assign(_) + | Expr::Async(_) + | Expr::Await(_) + | Expr::Binary(_) + | Expr::Block(_) + | Expr::Call(_) + | Expr::Cast(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::ForLoop(_) + | Expr::If(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Lit(_) + | Expr::Loop(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Range(_) + | Expr::Repeat(_) + | Expr::Struct(_) + | Expr::Try(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::While(_) => match fixup.next_operator { + Precedence::Assign | Precedence::Range if precedence == Precedence::Range => Scan::Fail, + _ if precedence == Precedence::Let && fixup.next_operator < Precedence::Let => { + Scan::Fail + } + _ => consume_by_precedence, + }, + + _ => match fixup.next_operator { + Precedence::Assign | Precedence::Range if precedence == Precedence::Range => Scan::Fail, + _ if precedence == Precedence::Let && fixup.next_operator < Precedence::Let => { + Scan::Fail + } + _ => consume_by_precedence, + }, + } +} diff --git a/zerocopy/vendor/prettyplease/src/generics.rs b/zerocopy/vendor/prettyplease/src/generics.rs index 3c641fc6b4..72d0bc16fc 100644 --- a/zerocopy/vendor/prettyplease/src/generics.rs +++ b/zerocopy/vendor/prettyplease/src/generics.rs @@ -5,9 +5,9 @@ use crate::INDENT; use proc_macro2::TokenStream; use std::ptr; use syn::{ - BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime, - PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause, - WherePredicate, + BoundLifetimes, CapturedParam, ConstParam, Expr, GenericParam, Generics, LifetimeParam, + PreciseCapture, PredicateLifetime, PredicateType, TraitBound, TypeParam, TypeParamBound, + WhereClause, WherePredicate, }; impl Printer { @@ -93,7 +93,7 @@ impl Printer { } self.type_param_bound(&type_param_bound); } - if let Some(default) = &type_param.default { + if let Some((_eq_token, default)) = &type_param.default { self.space(); self.word("= "); self.ty(default); @@ -105,26 +105,34 @@ impl Printer { match type_param_bound { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] TypeParamBound::Trait(trait_bound) => { - let tilde_const = false; - self.trait_bound(trait_bound, tilde_const); + self.trait_bound(trait_bound, TraitBoundConst::None); } TypeParamBound::Lifetime(lifetime) => self.lifetime(lifetime), + TypeParamBound::PreciseCapture(precise_capture) => { + self.precise_capture(precise_capture); + } TypeParamBound::Verbatim(bound) => self.type_param_bound_verbatim(bound), _ => unimplemented!("unknown TypeParamBound"), } } - fn trait_bound(&mut self, trait_bound: &TraitBound, tilde_const: bool) { + fn trait_bound(&mut self, trait_bound: &TraitBound, constness: TraitBoundConst) { if trait_bound.paren_token.is_some() { self.word("("); } - if tilde_const { - self.word("~const "); - } - self.trait_bound_modifier(&trait_bound.modifier); if let Some(bound_lifetimes) = &trait_bound.lifetimes { self.bound_lifetimes(bound_lifetimes); } + match constness { + TraitBoundConst::None => {} + #[cfg(feature = "verbatim")] + TraitBoundConst::Conditional => self.word("[const] "), + #[cfg(feature = "verbatim")] + TraitBoundConst::Unconditional => self.word("const "), + } + if trait_bound.maybe.is_some() { + self.word("?"); + } for segment in trait_bound.path.segments.iter().delimited() { if !segment.is_first || trait_bound.path.leading_colon.is_some() { self.word("::"); @@ -136,13 +144,6 @@ impl Printer { } } - fn trait_bound_modifier(&mut self, trait_bound_modifier: &TraitBoundModifier) { - match trait_bound_modifier { - TraitBoundModifier::None => {} - TraitBoundModifier::Maybe(_question_mark) => self.word("?"), - } - } - #[cfg(not(feature = "verbatim"))] fn type_param_bound_verbatim(&mut self, bound: &TokenStream) { unimplemented!("TypeParamBound::Verbatim `{}`", bound); @@ -151,34 +152,68 @@ impl Printer { #[cfg(feature = "verbatim")] fn type_param_bound_verbatim(&mut self, tokens: &TokenStream) { use syn::parse::{Parse, ParseStream, Result}; - use syn::{parenthesized, token, Token}; + use syn::{ + bracketed, parenthesized, token, ParenthesizedGenericArguments, Path, PathArguments, + Token, TraitBoundModifiers, + }; enum TypeParamBoundVerbatim { Ellipsis, - TildeConst(TraitBound), + Const(TraitBound, TraitBoundConst), } impl Parse for TypeParamBoundVerbatim { fn parse(input: ParseStream) -> Result { + if input.peek(Token![...]) { + input.parse::()?; + return Ok(TypeParamBoundVerbatim::Ellipsis); + } + let content; - let (paren_token, content) = if input.peek(token::Paren) { - (Some(parenthesized!(content in input)), &content) + let content = if input.peek(token::Paren) { + parenthesized!(content in input); + &content } else { - (None, input) + input }; - let lookahead = content.lookahead1(); - if lookahead.peek(Token![~]) { - content.parse::()?; + + let lifetimes: Option = content.parse()?; + + let constness = if content.peek(token::Bracket) { + let conditionally_const; + bracketed!(conditionally_const in content); + conditionally_const.parse::()?; + TraitBoundConst::Conditional + } else if content.peek(Token![const]) { content.parse::()?; - let mut bound: TraitBound = content.parse()?; - bound.paren_token = paren_token; - Ok(TypeParamBoundVerbatim::TildeConst(bound)) - } else if lookahead.peek(Token![...]) { - content.parse::()?; - Ok(TypeParamBoundVerbatim::Ellipsis) + TraitBoundConst::Unconditional } else { - Err(lookahead.error()) + TraitBoundConst::None + }; + + let maybe: Option = content.parse()?; + + let mut path: Path = content.parse()?; + if path.segments.last().unwrap().arguments.is_empty() + && (content.peek(token::Paren) + || content.peek(Token![::]) && content.peek3(token::Paren)) + { + content.parse::>()?; + let args: ParenthesizedGenericArguments = content.parse()?; + let parenthesized = PathArguments::Parenthesized(args); + path.segments.last_mut().unwrap().arguments = parenthesized; } + + Ok(TypeParamBoundVerbatim::Const( + TraitBound { + paren_token: None, + lifetimes, + modifiers: TraitBoundModifiers::default(), + maybe, + path, + }, + constness, + )) } } @@ -191,9 +226,8 @@ impl Printer { TypeParamBoundVerbatim::Ellipsis => { self.word("..."); } - TypeParamBoundVerbatim::TildeConst(trait_bound) => { - let tilde_const = true; - self.trait_bound(&trait_bound, tilde_const); + TypeParamBoundVerbatim::Const(trait_bound, constness) => { + self.trait_bound(&trait_bound, constness); } } } @@ -204,9 +238,9 @@ impl Printer { self.ident(&const_param.ident); self.word(": "); self.ty(&const_param.ty); - if let Some(default) = &const_param.default { + if let Some((_eq_token, default)) = &const_param.default { self.word(" = "); - self.expr(default); + self.const_argument(default); } } @@ -334,4 +368,55 @@ impl Printer { } self.end(); } + + fn precise_capture(&mut self, precise_capture: &PreciseCapture) { + self.word("use<"); + for capture in precise_capture.params.iter().delimited() { + self.captured_param(&capture); + if !capture.is_last { + self.word(", "); + } + } + self.word(">"); + } + + fn captured_param(&mut self, capture: &CapturedParam) { + match capture { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + CapturedParam::Lifetime(lifetime) => self.lifetime(lifetime), + CapturedParam::Ident(ident) => self.ident(ident), + _ => unimplemented!("unknown CapturedParam"), + } + } + + pub fn const_argument(&mut self, expr: &Expr) { + match expr { + #![cfg_attr(all(test, exhaustive), allow(non_exhaustive_omitted_patterns))] + Expr::Lit(expr) => self.expr_lit(expr), + + Expr::Path(expr) + if expr.attrs.is_empty() + && expr.qself.is_none() + && expr.path.get_ident().is_some() => + { + self.expr_path(expr); + } + + Expr::Block(expr) => self.expr_block(expr), + + _ => { + self.cbox(INDENT); + self.expr_as_small_block(expr, 0); + self.end(); + } + } + } +} + +enum TraitBoundConst { + None, + #[cfg(feature = "verbatim")] + Conditional, + #[cfg(feature = "verbatim")] + Unconditional, } diff --git a/zerocopy/vendor/prettyplease/src/item.rs b/zerocopy/vendor/prettyplease/src/item.rs index 6383111007..9df2ee6cac 100644 --- a/zerocopy/vendor/prettyplease/src/item.rs +++ b/zerocopy/vendor/prettyplease/src/item.rs @@ -1,5 +1,7 @@ use crate::algorithm::Printer; +use crate::fixup::FixupContext; use crate::iter::IterDelimited; +use crate::mac; use crate::path::PathKind; use crate::INDENT; use proc_macro2::TokenStream; @@ -8,8 +10,9 @@ use syn::{ ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, - Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, - TraitItemType, Type, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, + ReceiverKind, Safety, Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, + TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, + Variadic, }; impl Printer { @@ -47,7 +50,7 @@ impl Printer { self.ty(&item.ty); self.word(" = "); self.neverbreak(); - self.expr(&item.expr); + self.expr(&item.expr, FixupContext::NONE); self.word(";"); self.end(); self.hardbreak(); @@ -96,8 +99,8 @@ impl Printer { self.word("{"); self.hardbreak_if_nonempty(); self.inner_attrs(&item.attrs); - for stmt in &item.block.stmts { - self.stmt(stmt); + for stmt in item.block.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -129,7 +132,7 @@ impl Printer { self.cbox(INDENT); self.ibox(-INDENT); self.cbox(INDENT); - if item.defaultness.is_some() { + if item.modifiers.defaultness.is_some() { self.word("default "); } if item.unsafety.is_some() { @@ -139,10 +142,10 @@ impl Printer { self.generics(&item.generics); self.end(); self.nbsp(); - if let Some((negative_polarity, path, _for_token)) = &item.trait_ { - if negative_polarity.is_some() { - self.word("!"); - } + if item.modifiers.polarity.is_some() { + self.word("!"); + } + if let Some((path, _for_token)) = &item.trait_ { self.path(path, PathKind::Type); self.space(); self.word("for "); @@ -164,7 +167,7 @@ impl Printer { fn item_macro(&mut self, item: &ItemMacro) { self.outer_attrs(&item.attrs); - let semicolon = true; + let semicolon = mac::requires_semi(&item.mac.delimiter); self.mac(&item.mac, item.ident.as_ref(), semicolon); self.hardbreak(); } @@ -206,7 +209,7 @@ impl Printer { self.ty(&item.ty); self.word(" = "); self.neverbreak(); - self.expr(&item.expr); + self.expr(&item.expr, FixupContext::NONE); self.word(";"); self.end(); self.hardbreak(); @@ -253,7 +256,7 @@ impl Printer { if item.unsafety.is_some() { self.word("unsafe "); } - if item.auto_token.is_some() { + if item.modifiers.auto_token.is_some() { self.word("auto "); } self.word("trait "); @@ -365,7 +368,8 @@ impl Printer { use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::{ - braced, parenthesized, token, Attribute, Generics, Ident, Lifetime, Token, Visibility, + braced, parenthesized, token, Attribute, Generics, Ident, Lifetime, Token, Type, + Visibility, }; use verbatim::{ FlexibleItemConst, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, @@ -745,6 +749,7 @@ impl Printer { self.word("{}"); } else if use_group.items.len() == 1 && match &use_group.items[0] { + UseTree::Name(use_name) => use_name.ident != "self", UseTree::Rename(use_rename) => use_rename.ident != "self", _ => true, } @@ -828,7 +833,7 @@ impl Printer { fn foreign_item_macro(&mut self, foreign_item: &ForeignItemMacro) { self.outer_attrs(&foreign_item.attrs); - let semicolon = true; + let semicolon = mac::requires_semi(&foreign_item.mac.delimiter); self.mac(&foreign_item.mac, None, semicolon); self.hardbreak(); } @@ -844,7 +849,7 @@ impl Printer { #[cfg(feature = "verbatim")] fn foreign_item_verbatim(&mut self, tokens: &TokenStream) { use syn::parse::{Parse, ParseStream, Result}; - use syn::{Attribute, Token, Visibility}; + use syn::{Abi, Attribute, Token, Visibility}; use verbatim::{FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, WhereClauseLocation}; enum ForeignItemVerbatim { @@ -855,6 +860,16 @@ impl Printer { TypeFlexible(FlexibleItemType), } + fn peek_signature(input: ParseStream) -> bool { + let fork = input.fork(); + fork.parse::>().is_ok() + && fork.parse::>().is_ok() + && ((fork.parse::>().unwrap().is_some()) + || fork.parse::>().is_ok()) + && fork.parse::>().is_ok() + && fork.peek(Token![fn]) + } + impl Parse for ForeignItemVerbatim { fn parse(input: ParseStream) -> Result { if input.is_empty() { @@ -869,15 +884,13 @@ impl Printer { let defaultness = false; let lookahead = input.lookahead1(); - if lookahead.peek(Token![const]) - || lookahead.peek(Token![async]) - || lookahead.peek(Token![unsafe]) - || lookahead.peek(Token![extern]) - || lookahead.peek(Token![fn]) - { + if lookahead.peek(Token![fn]) || peek_signature(input) { let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?; Ok(ForeignItemVerbatim::FnFlexible(flexible_item)) - } else if lookahead.peek(Token![static]) { + } else if lookahead.peek(Token![static]) + || ((input.peek(Token![unsafe]) || input.peek(Token![safe])) + && input.peek2(Token![static])) + { let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?; Ok(ForeignItemVerbatim::StaticFlexible(flexible_item)) } else if lookahead.peek(Token![type]) { @@ -943,7 +956,7 @@ impl Printer { if let Some((_eq_token, default)) = &trait_item.default { self.word(" = "); self.neverbreak(); - self.expr(default); + self.expr(default, FixupContext::NONE); } self.word(";"); self.end(); @@ -959,8 +972,8 @@ impl Printer { self.word("{"); self.hardbreak_if_nonempty(); self.inner_attrs(&trait_item.attrs); - for stmt in &block.stmts { - self.stmt(stmt); + for stmt in block.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -1001,7 +1014,7 @@ impl Printer { fn trait_item_macro(&mut self, trait_item: &TraitItemMacro) { self.outer_attrs(&trait_item.attrs); - let semicolon = true; + let semicolon = mac::requires_semi(&trait_item.mac.delimiter); self.mac(&trait_item.mac, None, semicolon); self.hardbreak(); } @@ -1126,7 +1139,7 @@ impl Printer { self.outer_attrs(&impl_item.attrs); self.cbox(0); self.visibility(&impl_item.vis); - if impl_item.defaultness.is_some() { + if impl_item.modifiers.defaultness.is_some() { self.word("default "); } self.word("const "); @@ -1136,7 +1149,7 @@ impl Printer { self.ty(&impl_item.ty); self.word(" = "); self.neverbreak(); - self.expr(&impl_item.expr); + self.expr(&impl_item.expr, FixupContext::NONE); self.word(";"); self.end(); self.hardbreak(); @@ -1146,7 +1159,7 @@ impl Printer { self.outer_attrs(&impl_item.attrs); self.cbox(INDENT); self.visibility(&impl_item.vis); - if impl_item.defaultness.is_some() { + if impl_item.modifiers.defaultness.is_some() { self.word("default "); } self.signature(&impl_item.sig); @@ -1154,8 +1167,8 @@ impl Printer { self.word("{"); self.hardbreak_if_nonempty(); self.inner_attrs(&impl_item.attrs); - for stmt in &impl_item.block.stmts { - self.stmt(stmt); + for stmt in impl_item.block.stmts.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -1167,7 +1180,7 @@ impl Printer { self.outer_attrs(&impl_item.attrs); self.cbox(INDENT); self.visibility(&impl_item.vis); - if impl_item.defaultness.is_some() { + if impl_item.modifiers.defaultness.is_some() { self.word("default "); } self.word("type "); @@ -1185,7 +1198,7 @@ impl Printer { fn impl_item_macro(&mut self, impl_item: &ImplItemMacro) { self.outer_attrs(&impl_item.attrs); - let semicolon = true; + let semicolon = mac::requires_semi(&impl_item.mac.delimiter); self.mac(&impl_item.mac, None, semicolon); self.hardbreak(); } @@ -1284,9 +1297,7 @@ impl Printer { if signature.asyncness.is_some() { self.word("async "); } - if signature.unsafety.is_some() { - self.word("unsafe "); - } + self.safety(&signature.safety); if let Some(abi) = &signature.abi { self.abi(abi); } @@ -1314,6 +1325,14 @@ impl Printer { self.end(); } + fn safety(&mut self, safety: &Safety) { + match safety { + Safety::Safe(_) => self.word("safe "), + Safety::Unsafe(_) => self.word("unsafe "), + Safety::Default => {} + } + } + fn fn_arg(&mut self, fn_arg: &FnArg) { match fn_arg { FnArg::Receiver(receiver) => self.receiver(receiver), @@ -1323,36 +1342,34 @@ impl Printer { fn receiver(&mut self, receiver: &Receiver) { self.outer_attrs(&receiver.attrs); - if let Some((_ampersand, lifetime)) = &receiver.reference { - self.word("&"); - if let Some(lifetime) = lifetime { - self.lifetime(lifetime); - self.nbsp(); + match &receiver.kind { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + ReceiverKind::Value => { + if receiver.mutability.is_some() { + self.word("mut "); + } + self.word("self"); } - } - if receiver.mutability.is_some() { - self.word("mut "); - } - self.word("self"); - if receiver.colon_token.is_some() { - self.word(": "); - self.ty(&receiver.ty); - } else { - let consistent = match (&receiver.reference, &receiver.mutability, &*receiver.ty) { - (Some(_), mutability, Type::Reference(ty)) => { - mutability.is_some() == ty.mutability.is_some() - && match &*ty.elem { - Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self"), - _ => false, - } + ReceiverKind::Reference(_ampersand, lifetime, mutability) => { + self.word("&"); + if let Some(lifetime) = lifetime { + self.lifetime(lifetime); + self.nbsp(); } - (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"), - _ => false, - }; - if !consistent { + if mutability.is_some() { + self.word("mut "); + } + self.word("self"); + } + ReceiverKind::Typed(_colon, ty) => { + if receiver.mutability.is_some() { + self.word("mut "); + } + self.word("self"); self.word(": "); - self.ty(&receiver.ty); + self.ty(ty); } + _ => unimplemented!("unknown ReceiverKind"), } } @@ -1378,13 +1395,14 @@ impl Printer { #[cfg(feature = "verbatim")] mod verbatim { use crate::algorithm::Printer; + use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::INDENT; use syn::ext::IdentExt; use syn::parse::{ParseStream, Result}; use syn::{ - braced, token, Attribute, Block, Expr, Generics, Ident, Signature, StaticMutability, Stmt, - Token, Type, TypeParamBound, Visibility, WhereClause, + braced, token, Attribute, Block, Expr, Generics, Ident, Safety, Signature, + StaticMutability, Stmt, Token, Type, TypeParamBound, Visibility, WhereClause, }; pub struct FlexibleItemConst { @@ -1408,6 +1426,7 @@ mod verbatim { pub struct FlexibleItemStatic { pub attrs: Vec, pub vis: Visibility, + pub safety: Safety, pub mutability: StaticMutability, pub ident: Ident, pub ty: Option, @@ -1474,7 +1493,16 @@ mod verbatim { defaultness: bool, input: ParseStream, ) -> Result { - let sig: Signature = input.parse()?; + let constness: Option = input.parse()?; + let asyncness: Option = input.parse()?; + let safety = Safety::parse_safe_or_unsafe(input)?; + + let lookahead = input.lookahead1(); + let sig: Signature = if lookahead.peek(Token![extern]) || lookahead.peek(Token![fn]) { + input.parse()? + } else { + return Err(lookahead.error()); + }; let lookahead = input.lookahead1(); let body = if lookahead.peek(Token![;]) { @@ -1493,7 +1521,12 @@ mod verbatim { attrs, vis, defaultness, - sig, + sig: Signature { + constness, + asyncness, + safety, + ..sig + }, body, }) } @@ -1501,6 +1534,7 @@ mod verbatim { impl FlexibleItemStatic { pub fn parse(attrs: Vec, vis: Visibility, input: ParseStream) -> Result { + let safety = Safety::parse_safe_or_unsafe(input)?; input.parse::()?; let mutability: StaticMutability = input.parse()?; let ident = input.parse()?; @@ -1530,6 +1564,7 @@ mod verbatim { Ok(FlexibleItemStatic { attrs, vis, + safety, mutability, ident, ty, @@ -1620,7 +1655,7 @@ mod verbatim { self.word(" = "); self.neverbreak(); self.ibox(-INDENT); - self.expr(value); + self.expr(value, FixupContext::NONE); self.end(); } self.where_clause_oneline_semi(&item.generics.where_clause); @@ -1641,8 +1676,8 @@ mod verbatim { self.word("{"); self.hardbreak_if_nonempty(); self.inner_attrs(&item.attrs); - for stmt in body { - self.stmt(stmt); + for stmt in body.iter().delimited() { + self.stmt(&stmt, stmt.is_last); } self.offset(-INDENT); self.end(); @@ -1658,6 +1693,7 @@ mod verbatim { self.outer_attrs(&item.attrs); self.cbox(0); self.visibility(&item.vis); + self.safety(&item.safety); self.word("static "); self.static_mutability(&item.mutability); self.ident(&item.ident); @@ -1668,7 +1704,7 @@ mod verbatim { if let Some(expr) = &item.expr { self.word(" = "); self.neverbreak(); - self.expr(expr); + self.expr(expr, FixupContext::NONE); } self.word(";"); self.end(); diff --git a/zerocopy/vendor/prettyplease/src/lib.rs b/zerocopy/vendor/prettyplease/src/lib.rs index 84d8e24ce3..643d679037 100644 --- a/zerocopy/vendor/prettyplease/src/lib.rs +++ b/zerocopy/vendor/prettyplease/src/lib.rs @@ -179,8 +179,8 @@ //! //! ``` //! // [dependencies] -//! // prettyplease = "0.2" -//! // syn = { version = "2", default-features = false, features = ["full", "parsing"] } +//! // prettyplease = "0.3" +//! // syn = { version = "3", default-features = false, features = ["full", "parsing"] } //! //! const INPUT: &str = stringify! { //! use crate::{ @@ -276,7 +276,7 @@ //! style. The reason is that in the paper, the complete non-whitespace contents //! are assumed to be independent of linebreak decisions, with Scan and Print //! being only in control of the whitespace (spaces and line breaks). In Rust as -//! idiomatically formattted by rustfmt, that is not the case. Trailing commas +//! idiomatically formatted by rustfmt, that is not the case. Trailing commas //! are one example; the punctuation is only known *after* the broken vs //! non-broken status of the surrounding group is known: //! @@ -320,8 +320,9 @@ //! these situations with conditional punctuation tokens whose selection can be //! deferred and populated after it's known that the group is or is not broken. -#![doc(html_root_url = "https://docs.rs/prettyplease/0.2.17")] +#![doc(html_root_url = "https://docs.rs/prettyplease/0.3.0")] #![allow( + clippy::bool_to_int_with_if, clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::derive_partial_eq_without_eq, @@ -334,7 +335,9 @@ clippy::module_name_repetitions, clippy::must_use_candidate, clippy::needless_pass_by_value, + clippy::ref_option, clippy::similar_names, + clippy::struct_excessive_bools, clippy::too_many_lines, clippy::unused_self, clippy::vec_init_then_push @@ -343,10 +346,12 @@ mod algorithm; mod attr; +mod classify; mod convenience; mod data; mod expr; mod file; +mod fixup; mod generics; mod item; mod iter; @@ -355,6 +360,7 @@ mod lit; mod mac; mod pat; mod path; +mod precedence; mod ring; mod stmt; mod token; diff --git a/zerocopy/vendor/prettyplease/src/lit.rs b/zerocopy/vendor/prettyplease/src/lit.rs index 3e6c14576c..10a86e4b03 100644 --- a/zerocopy/vendor/prettyplease/src/lit.rs +++ b/zerocopy/vendor/prettyplease/src/lit.rs @@ -1,6 +1,6 @@ use crate::algorithm::Printer; use proc_macro2::Literal; -use syn::{Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr}; +use syn::{Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr}; impl Printer { pub fn lit(&mut self, lit: &Lit) { @@ -8,6 +8,7 @@ impl Printer { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] Lit::Str(lit) => self.lit_str(lit), Lit::ByteStr(lit) => self.lit_byte_str(lit), + Lit::CStr(lit) => self.lit_c_str(lit), Lit::Byte(lit) => self.lit_byte(lit), Lit::Char(lit) => self.lit_char(lit), Lit::Int(lit) => self.lit_int(lit), @@ -26,6 +27,10 @@ impl Printer { self.word(lit.token().to_string()); } + fn lit_c_str(&mut self, lit: &LitCStr) { + self.word(lit.token().to_string()); + } + fn lit_byte(&mut self, lit: &LitByte) { self.word(lit.token().to_string()); } diff --git a/zerocopy/vendor/prettyplease/src/mac.rs b/zerocopy/vendor/prettyplease/src/mac.rs index ebc56c7ecf..5ef58455b3 100644 --- a/zerocopy/vendor/prettyplease/src/mac.rs +++ b/zerocopy/vendor/prettyplease/src/mac.rs @@ -41,10 +41,7 @@ impl Printer { } self.word(close); if semicolon { - match mac.delimiter { - MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => self.word(";"), - MacroDelimiter::Brace(_) => {} - } + self.word(";"); } } @@ -133,6 +130,7 @@ impl Printer { enum State { Start, Dollar, + DollarCrate, DollarIdent, DollarIdentColon, DollarParen, @@ -155,7 +153,9 @@ impl Printer { for tt in stream { let token = Token::from(tt); let (needs_space, next_state) = match (&state, &token) { - (Dollar, Token::Ident(_)) => (false, if matcher { DollarIdent } else { Other }), + (Dollar, Token::Ident(_)) if matcher => (false, DollarIdent), + (Dollar, Token::Ident(ident)) if ident == "crate" => (false, DollarCrate), + (Dollar, Token::Ident(_)) => (false, Other), (DollarIdent, Token::Punct(':', Spacing::Alone)) => (false, DollarIdentColon), (DollarIdentColon, Token::Ident(_)) => (false, Other), (DollarParen, Token::Punct('+' | '*' | '?', Spacing::Alone)) => (false, Other), @@ -179,10 +179,13 @@ impl Printer { (_, Token::Ident(ident)) if !is_keyword(ident) => { (state != Dot && state != Colon2, Ident) } + (_, Token::Literal(lit)) if lit.to_string().ends_with('.') => (state != Dot, Other), (_, Token::Literal(_)) => (state != Dot, Ident), (_, Token::Punct(',' | ';', _)) => (false, Other), (_, Token::Punct('.', _)) if !matcher => (state != Ident && state != Delim, Dot), - (_, Token::Punct(':', Spacing::Joint)) => (state != Ident, Colon), + (_, Token::Punct(':', Spacing::Joint)) => { + (state != Ident && state != DollarCrate, Colon) + } (_, Token::Punct('$', _)) => (true, Dollar), (_, Token::Punct('#', _)) => (true, Pound), (_, _) => (true, Other), @@ -211,6 +214,13 @@ impl Printer { } } +pub(crate) fn requires_semi(delimiter: &MacroDelimiter) -> bool { + match delimiter { + MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => true, + MacroDelimiter::Brace(_) => false, + } +} + fn is_keyword(ident: &Ident) -> bool { match ident.to_string().as_str() { "as" | "async" | "await" | "box" | "break" | "const" | "continue" | "crate" | "dyn" @@ -224,11 +234,14 @@ fn is_keyword(ident: &Ident) -> bool { #[cfg(feature = "verbatim")] mod standard_library { use crate::algorithm::Printer; + use crate::expr; + use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::path::PathKind; use crate::INDENT; use syn::ext::IdentExt; use syn::parse::{Parse, ParseStream, Parser, Result}; + use syn::punctuated::Punctuated; use syn::{ parenthesized, token, Attribute, Expr, ExprAssign, ExprPath, Ident, Lit, Macro, Pat, Path, Token, Type, Visibility, @@ -240,7 +253,7 @@ mod standard_library { Cfg(Cfg), Matches(Matches), ThreadLocal(Vec), - VecArray(Vec), + VecArray(Punctuated), VecRepeat { elem: Expr, n: Expr }, } @@ -457,7 +470,7 @@ mod standard_library { fn parse_vec(input: ParseStream) -> Result { if input.is_empty() { - return Ok(KnownMacro::VecArray(Vec::new())); + return Ok(KnownMacro::VecArray(Punctuated::new())); } let first: Expr = input.parse()?; if input.parse::>()?.is_some() { @@ -467,14 +480,16 @@ mod standard_library { n: len, }) } else { - let mut vec = vec![first]; + let mut vec = Punctuated::new(); + vec.push_value(first); while !input.is_empty() { - input.parse::()?; + let comma: Token![,] = input.parse()?; + vec.push_punct(comma); if input.is_empty() { break; } let next: Expr = input.parse()?; - vec.push(next); + vec.push_value(next); } Ok(KnownMacro::VecArray(vec)) } @@ -530,9 +545,8 @@ mod standard_library { _ => return false, }; - let known_macro = match parser.parse2(mac.tokens.clone()) { - Ok(known_macro) => known_macro, - Err(_) => return false, + let Ok(known_macro) = parser.parse2(mac.tokens.clone()) else { + return false; }; self.path(&mac.path, PathKind::Simple); @@ -543,7 +557,7 @@ mod standard_library { self.word("("); self.cbox(INDENT); self.zerobreak(); - self.expr(expr); + self.expr(expr, FixupContext::NONE); self.zerobreak(); self.offset(-INDENT); self.end(); @@ -554,7 +568,7 @@ mod standard_library { self.cbox(INDENT); self.zerobreak(); for elem in exprs.iter().delimited() { - self.expr(&elem); + self.expr(&elem, FixupContext::NONE); self.trailing_comma(elem.is_last); } self.offset(-INDENT); @@ -570,14 +584,14 @@ mod standard_library { self.word("("); self.cbox(INDENT); self.zerobreak(); - self.expr(&matches.expression); + self.expr(&matches.expression, FixupContext::NONE); self.word(","); self.space(); self.pat(&matches.pattern); if let Some(guard) = &matches.guard { self.space(); self.word("if "); - self.expr(guard); + self.expr(guard, FixupContext::NONE); } self.zerobreak(); self.offset(-INDENT); @@ -598,7 +612,7 @@ mod standard_library { self.ty(&item.ty); self.word(" = "); self.neverbreak(); - self.expr(&item.init); + self.expr(&item.init, FixupContext::NONE); self.word(";"); self.end(); self.hardbreak(); @@ -609,25 +623,46 @@ mod standard_library { semicolon = false; } KnownMacro::VecArray(vec) => { - self.word("["); - self.cbox(INDENT); - self.zerobreak(); - for elem in vec.iter().delimited() { - self.expr(&elem); - self.trailing_comma(elem.is_last); + if vec.is_empty() { + self.word("[]"); + } else if expr::simple_array(vec) { + self.cbox(INDENT); + self.word("["); + self.zerobreak(); + self.ibox(0); + for elem in vec.iter().delimited() { + self.expr(&elem, FixupContext::NONE); + if !elem.is_last { + self.word(","); + self.space(); + } + } + self.end(); + self.trailing_comma(true); + self.offset(-INDENT); + self.word("]"); + self.end(); + } else { + self.word("["); + self.cbox(INDENT); + self.zerobreak(); + for elem in vec.iter().delimited() { + self.expr(&elem, FixupContext::NONE); + self.trailing_comma(elem.is_last); + } + self.offset(-INDENT); + self.end(); + self.word("]"); } - self.offset(-INDENT); - self.end(); - self.word("]"); } KnownMacro::VecRepeat { elem, n } => { self.word("["); self.cbox(INDENT); self.zerobreak(); - self.expr(elem); + self.expr(elem, FixupContext::NONE); self.word(";"); self.space(); - self.expr(n); + self.expr(n, FixupContext::NONE); self.zerobreak(); self.offset(-INDENT); self.end(); diff --git a/zerocopy/vendor/prettyplease/src/pat.rs b/zerocopy/vendor/prettyplease/src/pat.rs index aa1806edac..200f5579f3 100644 --- a/zerocopy/vendor/prettyplease/src/pat.rs +++ b/zerocopy/vendor/prettyplease/src/pat.rs @@ -1,11 +1,12 @@ use crate::algorithm::Printer; +use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::path::PathKind; use crate::INDENT; use proc_macro2::TokenStream; use syn::{ - FieldPat, Pat, PatIdent, PatOr, PatParen, PatReference, PatRest, PatSlice, PatStruct, PatTuple, - PatTupleStruct, PatType, PatWild, + FieldPat, Pat, PatGuard, PatIdent, PatOr, PatParen, PatReference, PatRest, PatSlice, PatStruct, + PatTuple, PatTupleStruct, PatType, PatWild, }; impl Printer { @@ -13,13 +14,14 @@ impl Printer { match pat { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] Pat::Const(pat) => self.expr_const(pat), + Pat::Guard(pat) => self.pat_guard(pat), Pat::Ident(pat) => self.pat_ident(pat), Pat::Lit(pat) => self.expr_lit(pat), Pat::Macro(pat) => self.expr_macro(pat), Pat::Or(pat) => self.pat_or(pat), Pat::Paren(pat) => self.pat_paren(pat), Pat::Path(pat) => self.expr_path(pat), - Pat::Range(pat) => self.expr_range(pat), + Pat::Range(pat) => self.expr_range(pat, FixupContext::NONE), Pat::Reference(pat) => self.pat_reference(pat), Pat::Rest(pat) => self.pat_rest(pat), Pat::Slice(pat) => self.pat_slice(pat), @@ -33,6 +35,13 @@ impl Printer { } } + fn pat_guard(&mut self, pat: &PatGuard) { + self.outer_attrs(&pat.attrs); + self.pat(&pat.pat); + self.word(" if "); + self.expr(&pat.guard, FixupContext::NONE); + } + fn pat_ident(&mut self, pat: &PatIdent) { self.outer_attrs(&pat.attrs); if pat.by_ref.is_some() { diff --git a/zerocopy/vendor/prettyplease/src/path.rs b/zerocopy/vendor/prettyplease/src/path.rs index abe5d48933..30fafb7b5d 100644 --- a/zerocopy/vendor/prettyplease/src/path.rs +++ b/zerocopy/vendor/prettyplease/src/path.rs @@ -3,7 +3,7 @@ use crate::iter::IterDelimited; use crate::INDENT; use std::ptr; use syn::{ - AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, Expr, GenericArgument, + AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument, ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf, }; @@ -50,20 +50,7 @@ impl Printer { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] GenericArgument::Lifetime(lifetime) => self.lifetime(lifetime), GenericArgument::Type(ty) => self.ty(ty), - GenericArgument::Const(expr) => { - match expr { - #![cfg_attr(all(test, exhaustive), allow(non_exhaustive_omitted_patterns))] - Expr::Lit(expr) => self.expr_lit(expr), - Expr::Block(expr) => self.expr_block(expr), - // ERROR CORRECTION: Add braces to make sure that the - // generated code is valid. - _ => { - self.word("{"); - self.expr(expr); - self.word("}"); - } - } - } + GenericArgument::Const(expr) => self.const_argument(expr), GenericArgument::AssocType(assoc) => self.assoc_type(assoc), GenericArgument::AssocConst(assoc) => self.assoc_const(assoc), GenericArgument::Constraint(constraint) => self.constraint(constraint), @@ -136,7 +123,7 @@ impl Printer { self.angle_bracketed_generic_arguments(generics, PathKind::Type); } self.word(" = "); - self.expr(&assoc.value); + self.const_argument(&assoc.value); } fn constraint(&mut self, constraint: &Constraint) { @@ -161,9 +148,9 @@ impl Printer { self.cbox(INDENT); self.word("("); self.zerobreak(); - for ty in arguments.inputs.iter().delimited() { - self.ty(&ty); - self.trailing_comma(ty.is_last); + for named_arg in arguments.inputs.iter().delimited() { + self.ty(&named_arg.ty); + self.trailing_comma(named_arg.is_last); } self.offset(-INDENT); self.word(")"); @@ -172,12 +159,9 @@ impl Printer { } pub fn qpath(&mut self, qself: &Option, path: &Path, kind: PathKind) { - let qself = match qself { - Some(qself) => qself, - None => { - self.path(path, kind); - return; - } + let Some(qself) = qself else { + self.path(path, kind); + return; }; assert!(qself.position < path.segments.len()); diff --git a/zerocopy/vendor/prettyplease/src/precedence.rs b/zerocopy/vendor/prettyplease/src/precedence.rs new file mode 100644 index 0000000000..03117d56de --- /dev/null +++ b/zerocopy/vendor/prettyplease/src/precedence.rs @@ -0,0 +1,148 @@ +use syn::{ + AttrStyle, Attribute, BinOp, Expr, ExprArray, ExprAsync, ExprAwait, ExprBlock, ExprBreak, + ExprCall, ExprConst, ExprContinue, ExprField, ExprForLoop, ExprIf, ExprIndex, ExprInfer, + ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRepeat, + ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile, ExprYield, + ReturnType, +}; + +// Reference: https://doc.rust-lang.org/reference/expressions.html#expression-precedence +#[derive(Copy, Clone, PartialEq, PartialOrd)] +pub enum Precedence { + // return, break, closures + Jump, + // = += -= *= /= %= &= |= ^= <<= >>= + Assign, + // .. ..= + Range, + // || + Or, + // && + And, + // let + Let, + // == != < > <= >= + Compare, + // | + BitOr, + // ^ + BitXor, + // & + BitAnd, + // << >> + Shift, + // + - + Sum, + // * / % + Product, + // as + Cast, + // unary - * ! & &mut + Prefix, + // paths, loops, function calls, array indexing, field expressions, method calls + Unambiguous, +} + +impl Precedence { + pub(crate) const MIN: Self = Precedence::Jump; + + pub(crate) fn of_binop(op: &BinOp) -> Self { + match op { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + BinOp::Add(_) | BinOp::Sub(_) => Precedence::Sum, + BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Product, + BinOp::And(_) => Precedence::And, + BinOp::Or(_) => Precedence::Or, + BinOp::BitXor(_) => Precedence::BitXor, + BinOp::BitAnd(_) => Precedence::BitAnd, + BinOp::BitOr(_) => Precedence::BitOr, + BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift, + + BinOp::Eq(_) + | BinOp::Lt(_) + | BinOp::Le(_) + | BinOp::Ne(_) + | BinOp::Ge(_) + | BinOp::Gt(_) => Precedence::Compare, + + BinOp::AddAssign(_) + | BinOp::SubAssign(_) + | BinOp::MulAssign(_) + | BinOp::DivAssign(_) + | BinOp::RemAssign(_) + | BinOp::BitXorAssign(_) + | BinOp::BitAndAssign(_) + | BinOp::BitOrAssign(_) + | BinOp::ShlAssign(_) + | BinOp::ShrAssign(_) => Precedence::Assign, + + _ => Precedence::MIN, + } + } + + pub(crate) fn of(e: &Expr) -> Self { + fn prefix_attrs(attrs: &[Attribute]) -> Precedence { + for attr in attrs { + if let AttrStyle::Outer = attr.style { + return Precedence::Prefix; + } + } + Precedence::Unambiguous + } + + match e { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Expr::Closure(e) => match e.output { + ReturnType::Default => Precedence::Jump, + ReturnType::Type(..) => prefix_attrs(&e.attrs), + }, + + Expr::Break(ExprBreak { expr, .. }) + | Expr::Return(ExprReturn { expr, .. }) + | Expr::Yield(ExprYield { expr, .. }) => match expr { + Some(_) => Precedence::Jump, + None => Precedence::Unambiguous, + }, + + Expr::Assign(_) => Precedence::Assign, + Expr::Range(_) => Precedence::Range, + Expr::Binary(e) => Precedence::of_binop(&e.op), + Expr::Let(_) => Precedence::Let, + Expr::Cast(_) => Precedence::Cast, + Expr::RawAddr(_) | Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix, + + Expr::Array(ExprArray { attrs, .. }) + | Expr::Async(ExprAsync { attrs, .. }) + | Expr::Await(ExprAwait { attrs, .. }) + | Expr::Block(ExprBlock { attrs, .. }) + | Expr::Call(ExprCall { attrs, .. }) + | Expr::Const(ExprConst { attrs, .. }) + | Expr::Continue(ExprContinue { attrs, .. }) + | Expr::Field(ExprField { attrs, .. }) + | Expr::ForLoop(ExprForLoop { attrs, .. }) + | Expr::If(ExprIf { attrs, .. }) + | Expr::Index(ExprIndex { attrs, .. }) + | Expr::Infer(ExprInfer { attrs, .. }) + | Expr::Lit(ExprLit { attrs, .. }) + | Expr::Loop(ExprLoop { attrs, .. }) + | Expr::Macro(ExprMacro { attrs, .. }) + | Expr::Match(ExprMatch { attrs, .. }) + | Expr::MethodCall(ExprMethodCall { attrs, .. }) + | Expr::Paren(ExprParen { attrs, .. }) + | Expr::Path(ExprPath { attrs, .. }) + | Expr::Repeat(ExprRepeat { attrs, .. }) + | Expr::Struct(ExprStruct { attrs, .. }) + | Expr::Try(ExprTry { attrs, .. }) + | Expr::TryBlock(ExprTryBlock { attrs, .. }) + | Expr::Tuple(ExprTuple { attrs, .. }) + | Expr::Unsafe(ExprUnsafe { attrs, .. }) + | Expr::While(ExprWhile { attrs, .. }) => prefix_attrs(attrs), + + Expr::Group(e) => Precedence::of(&e.expr), + + Expr::Verbatim(_) => Precedence::Unambiguous, + + _ => Precedence::Unambiguous, + } + } +} diff --git a/zerocopy/vendor/prettyplease/src/ring.rs b/zerocopy/vendor/prettyplease/src/ring.rs index aff92589a5..882a988ecd 100644 --- a/zerocopy/vendor/prettyplease/src/ring.rs +++ b/zerocopy/vendor/prettyplease/src/ring.rs @@ -1,5 +1,5 @@ use std::collections::VecDeque; -use std::ops::{Index, IndexMut}; +use std::ops::{Index, IndexMut, Range}; pub struct RingBuffer { data: VecDeque, @@ -33,8 +33,8 @@ impl RingBuffer { self.data.clear(); } - pub fn index_of_first(&self) -> usize { - self.offset + pub fn index_range(&self) -> Range { + self.offset..self.offset + self.data.len() } pub fn first(&self) -> &T { diff --git a/zerocopy/vendor/prettyplease/src/stmt.rs b/zerocopy/vendor/prettyplease/src/stmt.rs index 110ab58ee3..ce58200e19 100644 --- a/zerocopy/vendor/prettyplease/src/stmt.rs +++ b/zerocopy/vendor/prettyplease/src/stmt.rs @@ -1,9 +1,13 @@ use crate::algorithm::Printer; +use crate::classify; +use crate::expr; +use crate::fixup::FixupContext; +use crate::mac; use crate::INDENT; use syn::{BinOp, Expr, Stmt}; impl Printer { - pub fn stmt(&mut self, stmt: &Stmt) { + pub fn stmt(&mut self, stmt: &Stmt, is_last: bool) { match stmt { Stmt::Local(local) => { self.outer_attrs(&local.attrs); @@ -13,32 +17,26 @@ impl Printer { if let Some(local_init) = &local.init { self.word(" = "); self.neverbreak(); - self.expr(&local_init.expr); + self.subexpr( + &local_init.expr, + local_init.diverge.is_some() + && classify::expr_trailing_brace(&local_init.expr), + FixupContext::NONE, + ); if let Some((_else, diverge)) = &local_init.diverge { self.space(); self.word("else "); self.end(); self.neverbreak(); - if let Expr::Block(expr) = diverge.as_ref() { - self.cbox(INDENT); + self.cbox(INDENT); + if let Some(expr) = expr::simple_block(diverge) { self.small_block(&expr.block, &[]); - self.end(); } else { - self.word("{"); - self.space(); - self.ibox(INDENT); - self.expr(diverge); - self.end(); - self.space(); - self.offset(-INDENT); - self.word("}"); + self.expr_as_small_block(diverge, INDENT); } - } else { - self.end(); } - } else { - self.end(); } + self.end(); self.word(";"); self.hardbreak(); } @@ -46,14 +44,14 @@ impl Printer { Stmt::Expr(expr, None) => { if break_after(expr) { self.ibox(0); - self.expr_beginning_of_line(expr, true); + self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt()); if add_semi(expr) { self.word(";"); } self.end(); self.hardbreak(); } else { - self.expr_beginning_of_line(expr, true); + self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt()); } } Stmt::Expr(expr, Some(_semi)) => { @@ -63,7 +61,7 @@ impl Printer { } } self.ibox(0); - self.expr_beginning_of_line(expr, true); + self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt()); if !remove_semi(expr) { self.word(";"); } @@ -72,7 +70,8 @@ impl Printer { } Stmt::Macro(stmt) => { self.outer_attrs(&stmt.attrs); - let semicolon = true; + let semicolon = stmt.semi_token.is_some() + || !is_last && mac::requires_semi(&stmt.mac.delimiter); self.mac(&stmt.mac, None, semicolon); self.hardbreak(); } @@ -145,6 +144,7 @@ pub fn add_semi(expr: &Expr) -> bool { | Expr::Paren(_) | Expr::Path(_) | Expr::Range(_) + | Expr::RawAddr(_) | Expr::Reference(_) | Expr::Repeat(_) | Expr::Struct(_) @@ -203,6 +203,7 @@ fn remove_semi(expr: &Expr) -> bool { | Expr::Paren(_) | Expr::Path(_) | Expr::Range(_) + | Expr::RawAddr(_) | Expr::Reference(_) | Expr::Repeat(_) | Expr::Return(_) diff --git a/zerocopy/vendor/prettyplease/src/ty.rs b/zerocopy/vendor/prettyplease/src/ty.rs index ec2cd0a014..9b5a1fe488 100644 --- a/zerocopy/vendor/prettyplease/src/ty.rs +++ b/zerocopy/vendor/prettyplease/src/ty.rs @@ -1,12 +1,13 @@ use crate::algorithm::Printer; +use crate::fixup::FixupContext; use crate::iter::IterDelimited; use crate::path::PathKind; use crate::INDENT; use proc_macro2::TokenStream; use syn::{ - Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup, - TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, - TypeSlice, TypeTraitObject, TypeTuple, + Abi, FnPtrVariadic, NamedArg, PointerMutability, ReturnType, Type, TypeArray, TypeFnPtr, + TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, + TypeReference, TypeSlice, TypeTraitObject, TypeTuple, }; impl Printer { @@ -14,7 +15,7 @@ impl Printer { match ty { #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] Type::Array(ty) => self.type_array(ty), - Type::BareFn(ty) => self.type_bare_fn(ty), + Type::FnPtr(ty) => self.type_fn_ptr(ty), Type::Group(ty) => self.type_group(ty), Type::ImplTrait(ty) => self.type_impl_trait(ty), Type::Infer(ty) => self.type_infer(ty), @@ -36,11 +37,11 @@ impl Printer { self.word("["); self.ty(&ty.elem); self.word("; "); - self.expr(&ty.len); + self.expr(&ty.len, FixupContext::NONE); self.word("]"); } - fn type_bare_fn(&mut self, ty: &TypeBareFn) { + fn type_fn_ptr(&mut self, ty: &TypeFnPtr) { if let Some(bound_lifetimes) = &ty.lifetimes { self.bound_lifetimes(bound_lifetimes); } @@ -53,12 +54,12 @@ impl Printer { self.word("fn("); self.cbox(INDENT); self.zerobreak(); - for bare_fn_arg in ty.inputs.iter().delimited() { - self.bare_fn_arg(&bare_fn_arg); - self.trailing_comma(bare_fn_arg.is_last && ty.variadic.is_none()); + for named_arg in ty.inputs.iter().delimited() { + self.named_arg(&named_arg); + self.trailing_comma(named_arg.is_last && ty.variadic.is_none()); } if let Some(variadic) = &ty.variadic { - self.bare_variadic(variadic); + self.fn_ptr_variadic(variadic); self.zerobreak(); } self.offset(-INDENT); @@ -108,10 +109,9 @@ impl Printer { fn type_ptr(&mut self, ty: &TypePtr) { self.word("*"); - if ty.mutability.is_some() { - self.word("mut "); - } else { - self.word("const "); + match &ty.mutability { + PointerMutability::Const(_) => self.word("const "), + PointerMutability::Mut(_) => self.word("mut "), } self.ty(&ty.elem); } @@ -179,7 +179,6 @@ impl Printer { AnonUnion(AnonUnion), DynStar(DynStar), MutSelf(MutSelf), - NotType(NotType), } struct AnonStruct { @@ -198,10 +197,6 @@ impl Printer { ty: Option, } - struct NotType { - inner: Type, - } - impl Parse for TypeVerbatim { fn parse(input: ParseStream) -> Result { let lookahead = input.lookahead1(); @@ -229,10 +224,6 @@ impl Printer { Some(ty) }; Ok(TypeVerbatim::MutSelf(MutSelf { ty })) - } else if lookahead.peek(Token![!]) { - input.parse::()?; - let inner: Type = input.parse()?; - Ok(TypeVerbatim::NotType(NotType { inner })) } else if lookahead.peek(Token![...]) { input.parse::()?; Ok(TypeVerbatim::Ellipsis) @@ -286,17 +277,13 @@ impl Printer { self.type_param_bound(&type_param_bound); } } - TypeVerbatim::MutSelf(bare_fn_arg) => { + TypeVerbatim::MutSelf(named_arg) => { self.word("mut self"); - if let Some(ty) = &bare_fn_arg.ty { + if let Some(ty) = &named_arg.ty { self.word(": "); self.ty(ty); } } - TypeVerbatim::NotType(ty) => { - self.word("!"); - self.ty(&ty.inner); - } } } @@ -310,16 +297,16 @@ impl Printer { } } - fn bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg) { - self.outer_attrs(&bare_fn_arg.attrs); - if let Some((name, _colon)) = &bare_fn_arg.name { + fn named_arg(&mut self, named_arg: &NamedArg) { + self.outer_attrs(&named_arg.attrs); + if let Some((name, _colon)) = &named_arg.name { self.ident(name); self.word(": "); } - self.ty(&bare_fn_arg.ty); + self.ty(&named_arg.ty); } - fn bare_variadic(&mut self, variadic: &BareVariadic) { + fn fn_ptr_variadic(&mut self, variadic: &FnPtrVariadic) { self.outer_attrs(&variadic.attrs); if let Some((name, _colon)) = &variadic.name { self.ident(name); diff --git a/zerocopy/vendor/prettyplease/tests/test.rs b/zerocopy/vendor/prettyplease/tests/test.rs index 04004a7955..aa6b849fcf 100644 --- a/zerocopy/vendor/prettyplease/tests/test.rs +++ b/zerocopy/vendor/prettyplease/tests/test.rs @@ -20,7 +20,7 @@ fn test_parenthesize_cond() { }, indoc! {" fn main() { - if (Struct {} == Struct {}) {} + if (Struct {}) == (Struct {}) {} } "}, ); @@ -39,17 +39,11 @@ fn test_parenthesize_match_guard() { } } }, - // FIXME: no parens around `Struct {}` because anything until the `=>` - // is considered part of the match guard expression. Parsing of the - // expression is not terminated by `{` in that position. - // - // FIXME: the `true && false` needs parens. Otherwise the precedence is - // `(let _ = true) && false` which means something different. indoc! {" fn main() { match () { - () if let _ = (Struct {}) => {} - () if let _ = true && false => {} + () if let _ = Struct {} => {} + () if let _ = (true && false) => {} } } "}, diff --git a/zerocopy/vendor/prettyplease/tests/test_precedence.rs b/zerocopy/vendor/prettyplease/tests/test_precedence.rs new file mode 100644 index 0000000000..89e0e52efc --- /dev/null +++ b/zerocopy/vendor/prettyplease/tests/test_precedence.rs @@ -0,0 +1,914 @@ +use proc_macro2::{Ident, Span, TokenStream}; +use quote::ToTokens as _; +use std::mem; +use std::process::ExitCode; +use syn::punctuated::Punctuated; +use syn::visit_mut::{self, VisitMut}; +use syn::{ + token, AngleBracketedGenericArguments, Arm, BinOp, Block, BlockModifiers, ClosureModifiers, + ConstModifiers, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBinary, ExprBlock, + ExprBreak, ExprCall, ExprCast, ExprClosure, ExprConst, ExprContinue, ExprField, ExprForLoop, + ExprIf, ExprIndex, ExprLet, ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall, ExprPath, + ExprRange, ExprRawAddr, ExprReference, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, + ExprUnary, ExprUnsafe, ExprWhile, ExprYield, File, GenericArgument, Generics, Item, ItemConst, + Label, Lifetime, LifetimeParam, Lit, LitInt, Macro, MacroDelimiter, Member, Pat, PatGuard, + PatWild, Path, PathArguments, PathSegment, PointerMutability, QSelf, RangeLimits, ReturnType, + Stmt, StmtMacro, Token, Type, TypeInfer, TypeParam, TypePath, UnOp, Visibility, +}; + +struct FlattenParens; + +impl VisitMut for FlattenParens { + fn visit_expr_mut(&mut self, e: &mut Expr) { + while let Expr::Paren(paren) = e { + *e = mem::replace(&mut *paren.expr, Expr::PLACEHOLDER); + } + visit_mut::visit_expr_mut(self, e); + } +} + +struct AsIfPrinted; + +impl VisitMut for AsIfPrinted { + fn visit_generics_mut(&mut self, generics: &mut Generics) { + if generics.params.is_empty() { + generics.lt_token = None; + generics.gt_token = None; + } + if let Some(where_clause) = &generics.where_clause { + if where_clause.predicates.is_empty() { + generics.where_clause = None; + } + } + visit_mut::visit_generics_mut(self, generics); + } + + fn visit_lifetime_param_mut(&mut self, param: &mut LifetimeParam) { + if param.bounds.is_empty() { + param.colon_token = None; + } + visit_mut::visit_lifetime_param_mut(self, param); + } + + fn visit_stmt_mut(&mut self, stmt: &mut Stmt) { + if let Stmt::Expr(expr, semi) = stmt { + if let Expr::Macro(e) = expr { + if match e.mac.delimiter { + MacroDelimiter::Brace(_) => true, + MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => semi.is_some(), + } { + let expr = match mem::replace(expr, Expr::PLACEHOLDER) { + Expr::Macro(expr) => expr, + _ => unreachable!(), + }; + *stmt = Stmt::Macro(StmtMacro { + attrs: expr.attrs, + mac: expr.mac, + semi_token: *semi, + }); + } + } + } + visit_mut::visit_stmt_mut(self, stmt); + } + + fn visit_type_param_mut(&mut self, param: &mut TypeParam) { + if param.bounds.is_empty() { + param.colon_token = None; + } + visit_mut::visit_type_param_mut(self, param); + } +} + +#[test] +fn test_permutations() -> ExitCode { + fn iter(depth: usize, f: &mut dyn FnMut(Expr)) { + let span = Span::call_site(); + + // Expr::Path + f(Expr::Path(ExprPath { + // `x` + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("x", span)), + })); + if false { + f(Expr::Path(ExprPath { + // `x::` + attrs: Vec::new(), + qself: None, + path: Path { + leading_colon: None, + segments: Punctuated::from_iter([PathSegment { + ident: Ident::new("x", span), + arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments { + colon2_token: Some(Token![::](span)), + lt_token: Token![<](span), + args: Punctuated::from_iter([GenericArgument::Type(Type::Path( + TypePath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("T", span)), + }, + ))]), + gt_token: Token![>](span), + }), + }]), + }, + })); + f(Expr::Path(ExprPath { + // `::CONST` + attrs: Vec::new(), + qself: Some(QSelf { + lt_token: Token![<](span), + ty: Box::new(Type::Path(TypePath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("T", span)), + })), + position: 1, + as_token: Some(Token![as](span)), + gt_token: Token![>](span), + }), + path: Path { + leading_colon: None, + segments: Punctuated::from_iter([ + PathSegment::from(Ident::new("Trait", span)), + PathSegment::from(Ident::new("CONST", span)), + ]), + }, + })); + } + + let depth = match depth.checked_sub(1) { + Some(depth) => depth, + None => return, + }; + + // Expr::Assign + iter(depth, &mut |expr| { + iter(0, &mut |simple| { + f(Expr::Assign(ExprAssign { + // `x = $expr` + attrs: Vec::new(), + left: Box::new(simple.clone()), + eq_token: Token![=](span), + right: Box::new(expr.clone()), + })); + f(Expr::Assign(ExprAssign { + // `$expr = x` + attrs: Vec::new(), + left: Box::new(expr.clone()), + eq_token: Token![=](span), + right: Box::new(simple), + })); + }); + }); + + // Expr::Binary + iter(depth, &mut |expr| { + iter(0, &mut |simple| { + for op in [ + BinOp::Add(Token![+](span)), + //BinOp::Sub(Token![-](span)), + //BinOp::Mul(Token![*](span)), + //BinOp::Div(Token![/](span)), + //BinOp::Rem(Token![%](span)), + //BinOp::And(Token![&&](span)), + //BinOp::Or(Token![||](span)), + //BinOp::BitXor(Token![^](span)), + //BinOp::BitAnd(Token![&](span)), + //BinOp::BitOr(Token![|](span)), + //BinOp::Shl(Token![<<](span)), + //BinOp::Shr(Token![>>](span)), + //BinOp::Eq(Token![==](span)), + BinOp::Lt(Token![<](span)), + //BinOp::Le(Token![<=](span)), + //BinOp::Ne(Token![!=](span)), + //BinOp::Ge(Token![>=](span)), + //BinOp::Gt(Token![>](span)), + BinOp::ShlAssign(Token![<<=](span)), + ] { + f(Expr::Binary(ExprBinary { + // `x + $expr` + attrs: Vec::new(), + left: Box::new(simple.clone()), + op, + right: Box::new(expr.clone()), + })); + f(Expr::Binary(ExprBinary { + // `$expr + x` + attrs: Vec::new(), + left: Box::new(expr.clone()), + op, + right: Box::new(simple.clone()), + })); + } + }); + }); + + // Expr::Block + f(Expr::Block(ExprBlock { + // `{}` + attrs: Vec::new(), + label: None, + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::Break + f(Expr::Break(ExprBreak { + // `break` + attrs: Vec::new(), + break_token: Token![break](span), + label: None, + expr: None, + })); + iter(depth, &mut |expr| { + f(Expr::Break(ExprBreak { + // `break $expr` + attrs: Vec::new(), + break_token: Token![break](span), + label: None, + expr: Some(Box::new(expr)), + })); + }); + + // Expr::Call + iter(depth, &mut |expr| { + f(Expr::Call(ExprCall { + // `$expr()` + attrs: Vec::new(), + func: Box::new(expr), + paren_token: token::Paren(span), + args: Punctuated::new(), + })); + }); + + // Expr::Cast + iter(depth, &mut |expr| { + f(Expr::Cast(ExprCast { + // `$expr as T` + attrs: Vec::new(), + expr: Box::new(expr), + as_token: Token![as](span), + ty: Box::new(Type::Path(TypePath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("T", span)), + })), + })); + }); + + // Expr::Closure + iter(depth, &mut |expr| { + f(Expr::Closure(ExprClosure { + // `|| $expr` + attrs: Vec::new(), + lifetimes: None, + modifiers: ClosureModifiers::default(), + constness: None, + asyncness: None, + capture: None, + inputs_begin: Token![|](span), + inputs: Punctuated::new(), + inputs_end: Token![|](span), + output: ReturnType::Default, + body: Box::new(expr), + })); + }); + + // Expr::Field + iter(depth, &mut |expr| { + f(Expr::Field(ExprField { + // `$expr.field` + attrs: Vec::new(), + base: Box::new(expr), + dot_token: Token![.](span), + member: Member::Named(Ident::new("field", span)), + })); + }); + + // Expr::If + iter(depth, &mut |expr| { + f(Expr::If(ExprIf { + // `if $expr {}` + attrs: Vec::new(), + if_token: Token![if](span), + cond: Box::new(expr), + then_branch: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + else_branch: None, + })); + }); + + // Expr::Let + iter(depth, &mut |expr| { + f(Expr::Let(ExprLet { + attrs: Vec::new(), + let_token: Token![let](span), + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + eq_token: Token![=](span), + expr: Box::new(expr), + })); + }); + + // Expr::Range + f(Expr::Range(ExprRange { + // `..` + attrs: Vec::new(), + start: None, + limits: RangeLimits::HalfOpen(Token![..](span)), + end: None, + })); + iter(depth, &mut |expr| { + f(Expr::Range(ExprRange { + // `..$expr` + attrs: Vec::new(), + start: None, + limits: RangeLimits::HalfOpen(Token![..](span)), + end: Some(Box::new(expr.clone())), + })); + f(Expr::Range(ExprRange { + // `$expr..` + attrs: Vec::new(), + start: Some(Box::new(expr)), + limits: RangeLimits::HalfOpen(Token![..](span)), + end: None, + })); + }); + + // Expr::Reference + iter(depth, &mut |expr| { + f(Expr::Reference(ExprReference { + // `&$expr` + attrs: Vec::new(), + and_token: Token![&](span), + mutability: None, + expr: Box::new(expr), + })); + }); + + // Expr::Return + f(Expr::Return(ExprReturn { + // `return` + attrs: Vec::new(), + return_token: Token![return](span), + expr: None, + })); + iter(depth, &mut |expr| { + f(Expr::Return(ExprReturn { + // `return $expr` + attrs: Vec::new(), + return_token: Token![return](span), + expr: Some(Box::new(expr)), + })); + }); + + // Expr::Try + iter(depth, &mut |expr| { + f(Expr::Try(ExprTry { + // `$expr?` + attrs: Vec::new(), + expr: Box::new(expr), + question_token: Token![?](span), + })); + }); + + // Expr::Unary + iter(depth, &mut |expr| { + for op in [ + UnOp::Deref(Token![*](span)), + //UnOp::Not(Token![!](span)), + //UnOp::Neg(Token![-](span)), + ] { + f(Expr::Unary(ExprUnary { + // `*$expr` + attrs: Vec::new(), + op, + expr: Box::new(expr.clone()), + })); + } + }); + + if false { + // Expr::Array + f(Expr::Array(ExprArray { + // `[]` + attrs: Vec::new(), + bracket_token: token::Bracket(span), + elems: Punctuated::new(), + })); + + // Expr::Async + f(Expr::Async(ExprAsync { + // `async {}` + attrs: Vec::new(), + async_token: Token![async](span), + capture: None, + modifiers: BlockModifiers::default(), + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::Await + iter(depth, &mut |expr| { + f(Expr::Await(ExprAwait { + // `$expr.await` + attrs: Vec::new(), + base: Box::new(expr), + dot_token: Token![.](span), + await_token: Token![await](span), + })); + }); + + // Expr::Block + f(Expr::Block(ExprBlock { + // `'a: {}` + attrs: Vec::new(), + label: Some(Label { + name: Lifetime::new("'a", span), + colon_token: Token![:](span), + }), + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + iter(depth, &mut |expr| { + f(Expr::Block(ExprBlock { + // `{ $expr }` + attrs: Vec::new(), + label: None, + block: Block { + brace_token: token::Brace(span), + stmts: Vec::from([Stmt::Expr(expr.clone(), None)]), + }, + })); + f(Expr::Block(ExprBlock { + // `{ $expr; }` + attrs: Vec::new(), + label: None, + block: Block { + brace_token: token::Brace(span), + stmts: Vec::from([Stmt::Expr(expr, Some(Token![;](span)))]), + }, + })); + }); + + // Expr::Break + f(Expr::Break(ExprBreak { + // `break 'a` + attrs: Vec::new(), + break_token: Token![break](span), + label: Some(Lifetime::new("'a", span)), + expr: None, + })); + iter(depth, &mut |expr| { + f(Expr::Break(ExprBreak { + // `break 'a $expr` + attrs: Vec::new(), + break_token: Token![break](span), + label: Some(Lifetime::new("'a", span)), + expr: Some(Box::new(expr)), + })); + }); + + // Expr::Closure + f(Expr::Closure(ExprClosure { + // `|| -> T {}` + attrs: Vec::new(), + lifetimes: None, + modifiers: ClosureModifiers::default(), + constness: None, + asyncness: None, + capture: None, + inputs_begin: Token![|](span), + inputs: Punctuated::new(), + inputs_end: Token![|](span), + output: ReturnType::Type( + Token![->](span), + Box::new(Type::Path(TypePath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("T", span)), + })), + ), + body: Box::new(Expr::Block(ExprBlock { + attrs: Vec::new(), + label: None, + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })), + })); + + // Expr::Const + f(Expr::Const(ExprConst { + // `const {}` + attrs: Vec::new(), + const_token: Token![const](span), + modifiers: BlockModifiers::default(), + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::Continue + f(Expr::Continue(ExprContinue { + // `continue` + attrs: Vec::new(), + continue_token: Token![continue](span), + label: None, + })); + f(Expr::Continue(ExprContinue { + // `continue 'a` + attrs: Vec::new(), + continue_token: Token![continue](span), + label: Some(Lifetime::new("'a", span)), + })); + + // Expr::ForLoop + iter(depth, &mut |expr| { + f(Expr::ForLoop(ExprForLoop { + // `for _ in $expr {}` + attrs: Vec::new(), + label: None, + for_token: Token![for](span), + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + in_token: Token![in](span), + expr: Box::new(expr.clone()), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + f(Expr::ForLoop(ExprForLoop { + // `'a: for _ in $expr {}` + attrs: Vec::new(), + label: Some(Label { + name: Lifetime::new("'a", span), + colon_token: Token![:](span), + }), + for_token: Token![for](span), + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + in_token: Token![in](span), + expr: Box::new(expr), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + }); + + // Expr::Index + iter(depth, &mut |expr| { + f(Expr::Index(ExprIndex { + // `$expr[0]` + attrs: Vec::new(), + expr: Box::new(expr), + bracket_token: token::Bracket(span), + index: Box::new(Expr::Lit(ExprLit { + attrs: Vec::new(), + lit: Lit::Int(LitInt::new("0", span)), + })), + })); + }); + + // Expr::Loop + f(Expr::Loop(ExprLoop { + // `loop {}` + attrs: Vec::new(), + label: None, + loop_token: Token![loop](span), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + f(Expr::Loop(ExprLoop { + // `'a: loop {}` + attrs: Vec::new(), + label: Some(Label { + name: Lifetime::new("'a", span), + colon_token: Token![:](span), + }), + loop_token: Token![loop](span), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::Macro + f(Expr::Macro(ExprMacro { + // `m!()` + attrs: Vec::new(), + mac: Macro { + path: Path::from(Ident::new("m", span)), + bang_token: Token![!](span), + delimiter: MacroDelimiter::Paren(token::Paren(span)), + tokens: TokenStream::new(), + }, + })); + f(Expr::Macro(ExprMacro { + // `m! {}` + attrs: Vec::new(), + mac: Macro { + path: Path::from(Ident::new("m", span)), + bang_token: Token![!](span), + delimiter: MacroDelimiter::Brace(token::Brace(span)), + tokens: TokenStream::new(), + }, + })); + + // Expr::Match + iter(depth, &mut |expr| { + f(Expr::Match(ExprMatch { + // `match $expr {}` + attrs: Vec::new(), + match_token: Token![match](span), + expr: Box::new(expr.clone()), + brace_token: token::Brace(span), + arms: Vec::new(), + })); + f(Expr::Match(ExprMatch { + // `match x { _ => $expr }` + attrs: Vec::new(), + match_token: Token![match](span), + expr: Box::new(Expr::Path(ExprPath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("x", span)), + })), + brace_token: token::Brace(span), + arms: Vec::from([Arm { + attrs: Vec::new(), + pat: Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + }), + fat_arrow_token: Token![=>](span), + body: Box::new(expr.clone()), + comma: None, + }]), + })); + f(Expr::Match(ExprMatch { + // `match x { _ if $expr => {} }` + attrs: Vec::new(), + match_token: Token![match](span), + expr: Box::new(Expr::Path(ExprPath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("x", span)), + })), + brace_token: token::Brace(span), + arms: Vec::from([Arm { + attrs: Vec::new(), + pat: Pat::Guard(PatGuard { + attrs: Vec::new(), + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + if_token: Token![if](span), + guard: Box::new(expr), + }), + fat_arrow_token: Token![=>](span), + body: Box::new(Expr::Block(ExprBlock { + attrs: Vec::new(), + label: None, + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })), + comma: None, + }]), + })); + }); + + // Expr::MethodCall + iter(depth, &mut |expr| { + f(Expr::MethodCall(ExprMethodCall { + // `$expr.method()` + attrs: Vec::new(), + receiver: Box::new(expr.clone()), + dot_token: Token![.](span), + method: Ident::new("method", span), + turbofish: None, + paren_token: token::Paren(span), + args: Punctuated::new(), + })); + f(Expr::MethodCall(ExprMethodCall { + // `$expr.method::()` + attrs: Vec::new(), + receiver: Box::new(expr), + dot_token: Token![.](span), + method: Ident::new("method", span), + turbofish: Some(AngleBracketedGenericArguments { + colon2_token: Some(Token![::](span)), + lt_token: Token![<](span), + args: Punctuated::from_iter([GenericArgument::Type(Type::Path( + TypePath { + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("T", span)), + }, + ))]), + gt_token: Token![>](span), + }), + paren_token: token::Paren(span), + args: Punctuated::new(), + })); + }); + + // Expr::RawAddr + iter(depth, &mut |expr| { + f(Expr::RawAddr(ExprRawAddr { + // `&raw const $expr` + attrs: Vec::new(), + and_token: Token![&](span), + raw: Token![raw](span), + mutability: PointerMutability::Const(Token![const](span)), + expr: Box::new(expr), + })); + }); + + // Expr::Struct + f(Expr::Struct(ExprStruct { + // `Struct {}` + attrs: Vec::new(), + qself: None, + path: Path::from(Ident::new("Struct", span)), + brace_token: token::Brace(span), + fields: Punctuated::new(), + dot2_token: None, + rest: None, + })); + + // Expr::TryBlock + f(Expr::TryBlock(ExprTryBlock { + // `try {}` + attrs: Vec::new(), + try_token: Token![try](span), + modifiers: BlockModifiers::default(), + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::Unsafe + f(Expr::Unsafe(ExprUnsafe { + // `unsafe {}` + attrs: Vec::new(), + unsafe_token: Token![unsafe](span), + block: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + + // Expr::While + iter(depth, &mut |expr| { + f(Expr::While(ExprWhile { + // `while $expr {}` + attrs: Vec::new(), + label: None, + while_token: Token![while](span), + cond: Box::new(expr.clone()), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + f(Expr::While(ExprWhile { + // `'a: while $expr {}` + attrs: Vec::new(), + label: Some(Label { + name: Lifetime::new("'a", span), + colon_token: Token![:](span), + }), + while_token: Token![while](span), + cond: Box::new(expr), + body: Block { + brace_token: token::Brace(span), + stmts: Vec::new(), + }, + })); + }); + + // Expr::Yield + f(Expr::Yield(ExprYield { + // `yield` + attrs: Vec::new(), + yield_token: Token![yield](span), + expr: None, + })); + iter(depth, &mut |expr| { + f(Expr::Yield(ExprYield { + // `yield $expr` + attrs: Vec::new(), + yield_token: Token![yield](span), + expr: Some(Box::new(expr)), + })); + }); + } + } + + let mut failures = 0; + macro_rules! fail { + ($($message:tt)*) => {{ + eprintln!($($message)*); + failures += 1; + return; + }}; + } + let mut assert = |mut original: Expr| { + let span = Span::call_site(); + // `const _: () = $expr;` + let pretty = prettyplease::unparse(&File { + shebang: None, + frontmatter: None, + attrs: Vec::new(), + items: Vec::from([Item::Const(ItemConst { + attrs: Vec::new(), + vis: Visibility::Inherited, + modifiers: ConstModifiers::default(), + const_token: Token![const](span), + ident: Ident::from(Token![_](span)), + generics: Generics::default(), + colon_token: Token![:](span), + ty: Box::new(Type::Infer(TypeInfer { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + eq_token: Token![=](span), + expr: Box::new(original.clone()), + semi_token: Token![;](span), + })]), + }); + let mut parsed = match syn::parse_file(&pretty) { + Ok(parsed) => parsed, + _ => fail!("failed to parse: {pretty}{original:#?}"), + }; + let item = match parsed.items.as_mut_slice() { + [Item::Const(item)] => item, + _ => unreachable!(), + }; + let mut parsed = mem::replace(&mut *item.expr, Expr::PLACEHOLDER); + AsIfPrinted.visit_expr_mut(&mut original); + FlattenParens.visit_expr_mut(&mut parsed); + if original != parsed { + fail!( + "before: {}\n{:#?}\nafter: {}\n{:#?}", + original.to_token_stream(), + original, + parsed.to_token_stream(), + parsed, + ); + } + if pretty.contains("(||") { + // https://github.com/dtolnay/prettyplease/issues/99 + return; + } + let no_paren = pretty.replace(['(', ')'], ""); + if pretty != no_paren { + if let Ok(mut parsed2) = syn::parse_file(&no_paren) { + let item = match parsed2.items.as_mut_slice() { + [Item::Const(item)] => item, + _ => unreachable!(), + }; + if original == *item.expr { + fail!("redundant parens: {}", pretty); + } + } + } + }; + + iter(if cfg!(debug_assertions) { 3 } else { 4 }, &mut assert); + if failures > 0 { + eprintln!("FAILURES: {failures}"); + ExitCode::FAILURE + } else { + ExitCode::SUCCESS + } +} diff --git a/zerocopy/vendor/proc-macro2/.cargo-checksum.json b/zerocopy/vendor/proc-macro2/.cargo-checksum.json index 4ea7798c15..4b7c0d5189 100644 --- a/zerocopy/vendor/proc-macro2/.cargo-checksum.json +++ b/zerocopy/vendor/proc-macro2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"afde5b66e7fbe730397f10a697a669ba0a79e35de4b5af839fc520cf75eeb213","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"7cd349266bac2d2acbd0adb43ab94b6ad6d4effbaac8e516172ae7f04c63ff4e","build/probe.rs":"971fd2178dc506ccdc5c2065c37b77696a4aee8e00330ca52625db4a857f68d3","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"7c3864497cb5298fd5d0e9f5ae5797860338a9a4263220a8e8eabecda1583797","src/fallback.rs":"60a66c3a97f2d3962bf13d876b03bf12d899be3849d9af48ee765d814498422e","src/lib.rs":"6e9854f75340fa269186d67266b06d7febb7edb2eebbc92c61ebec0cbf8b1738","src/location.rs":"f55d2e61f1bb1af65e14ed04c9e91eb1ddbf8430e8c05f2048d1cd538d27368e","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/parse.rs":"4b77cddbc2752bc4d38a65acd8b96b6786c5220d19b1e1b37810257b5d24132d","src/rcvec.rs":"1c3c48c4f819927cc445ae15ca3bb06775feff2fd1cb21901ae4c40c7e6b4e82","src/wrapper.rs":"e41df9abc846b40f0cf01150d22b91944d07cde93bc72aa34798101652675844","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"473e962ee1aa0633dd5cf9a973b3bbd0ef43b740d4b7f6d008ff455a6b89d386","tests/test.rs":"9261ca13805a8311e9cb51d39cc9b0bfe0329496169c32d86558f25abf217a49","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"acf05963c1e62052d769d237b50844a2c59b4182b491231b099a4f74e5456ab0"},"package":"a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e"} \ No newline at end of file +{"files":{".cargo_vcs_info.json":"07ed6e92f7bb276cf97b58c2034d3a0eb707a400ddf98909376cbe656c5b167e",".github/FUNDING.yml":"b017158736b3c9751a2d21edfce7fe61c8954e2fced8da8dd3013c2f3e295bd9",".github/workflows/ci.yml":"4c0b4cc9a7cafd0d3d8ba4c319bc9a181dfd488e691255486d12ad04da4f899e","Cargo.lock":"c76e29511ef21d8be77269d219ca8b857887973cec2fffc8c06cabf678233453","Cargo.toml":"615c608ae7f19e7ce918b296fabe2929a63e320db05d282e6a25e4d096770dd6","Cargo.toml.orig":"59347da9772076ac3ff63ccb6dfe64a33f6719e6d0b283bea51304be56c35788","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"29344b7dbd94595f9fbcbc3f2be9b4bb52b5e8a26d21d4363714bab2a18f32ad","build/probe.rs":"df0d73191f20c207bb1051a4944fb6962e1f632d1e0535aba4b995aa7feba8d1","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"29f094473279a29b71c3cc9f5fa27c2e2c30c670390cf7e4b7cf451486cc857e","src/fallback.rs":"1c29625728cdb7640275c67618ee158c74ef01f3ec0a4e459f87fcbf48265563","src/lib.rs":"cd7c404a5f14d85cd4248b635051f82c183f2eabd9ce924c1a371ee605c1904f","src/location.rs":"9225c5a55f03b56cce42bc55ceb509e8216a5e0b24c94aa1cd071b04e3d6c15f","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/parse.rs":"2cceae010b4a8fabf83fde48467016eaff47e71ebd13acf2b82ec965e73868e5","src/rcvec.rs":"eedb1f09f7e3ede30c4162a19d0caa57f842653184bd905bb3e14c0f0b56c7c3","src/wrapper.rs":"e95f2dd248f82895d6a65d523740dcbef72e7932ff43356eca50a45f1d2ecb96","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"473e962ee1aa0633dd5cf9a973b3bbd0ef43b740d4b7f6d008ff455a6b89d386","tests/test.rs":"2e7106f582367d168638be7364d4e9aadbe0affca8b51dd80f0b3977cc2fcf83","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"62d8373ea46b669b87bc90a9c49b6d02f90ff4c21f9a25acebf60c9926e01fb7"},"package":"307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3"} \ No newline at end of file diff --git a/zerocopy/vendor/proc-macro2/.cargo_vcs_info.json b/zerocopy/vendor/proc-macro2/.cargo_vcs_info.json new file mode 100644 index 0000000000..ed8bb7163c --- /dev/null +++ b/zerocopy/vendor/proc-macro2/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "5046761b9689109142a02c71736284013673f0bd" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/zerocopy/vendor/proc-macro2/.github/FUNDING.yml b/zerocopy/vendor/proc-macro2/.github/FUNDING.yml new file mode 100644 index 0000000000..750707701c --- /dev/null +++ b/zerocopy/vendor/proc-macro2/.github/FUNDING.yml @@ -0,0 +1 @@ +github: dtolnay diff --git a/zerocopy/vendor/proc-macro2/.github/workflows/ci.yml b/zerocopy/vendor/proc-macro2/.github/workflows/ci.yml new file mode 100644 index 0000000000..5723f2b285 --- /dev/null +++ b/zerocopy/vendor/proc-macro2/.github/workflows/ci.yml @@ -0,0 +1,226 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + schedule: [cron: "40 1 * * *"] + +permissions: + contents: read + +env: + RUSTFLAGS: -Dwarnings + +jobs: + pre_ci: + uses: dtolnay/.github/.github/workflows/pre_ci.yml@master + + test: + name: Rust ${{matrix.rust}} + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [1.63.0, stable, beta] + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + components: rust-src + - run: cargo test + - run: cargo test --no-default-features + - run: cargo test --features span-locations + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test + run: cargo test + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test --no-default-features + run: cargo test --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + + nightly: + name: Rust nightly + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - name: Enable type layout randomization + run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout\ --cfg=randomize_layout >> $GITHUB_ENV + - run: cargo check + env: + RUSTFLAGS: --cfg procmacro2_nightly_testing ${{env.RUSTFLAGS}} + - run: cargo test + - run: cargo test --no-default-features + - run: cargo test --no-default-features --test features -- --ignored make_sure_no_proc_macro # run the ignored test to make sure the `proc-macro` feature is disabled + - run: cargo test --features span-locations + - run: cargo test --manifest-path tests/ui/Cargo.toml + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test + run: cargo test + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test --no-default-features + run: cargo test --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='-Z allow-features=' cargo test + run: cargo test + env: + RUSTFLAGS: -Z allow-features= --cfg procmacro2_backtrace ${{env.RUSTFLAGS}} + - uses: actions/upload-artifact@v4 + if: always() + with: + name: Cargo.lock + path: Cargo.lock + continue-on-error: true + + layout: + name: Layout + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - run: cargo test --test test_size + - run: cargo test --test test_size --features span-locations + - run: cargo test --test test_size --no-default-features + - run: cargo test --test test_size --no-default-features --features span-locations + + msrv: + name: Rust 1.56.0 + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.56.0 + with: + components: rust-src + - run: cargo check + - run: cargo check --no-default-features + - run: cargo check --features span-locations + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo check + run: cargo check + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + - name: RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo check --no-default-features + run: cargo check --no-default-features + env: + RUSTFLAGS: --cfg procmacro2_semver_exempt ${{env.RUSTFLAGS}} + + minimal: + name: Minimal versions + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo generate-lockfile -Z minimal-versions + - run: cargo check --locked + + webassembly: + name: WebAssembly + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + target: wasm32-unknown-unknown + components: rust-src + - run: cargo test --target wasm32-unknown-unknown --no-run + + fuzz: + name: Fuzz + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - uses: dtolnay/install@cargo-fuzz + - run: cargo fuzz check + - run: cargo check --no-default-features --features afl + working-directory: fuzz + - uses: dtolnay/install@honggfuzz + - run: sudo apt-get update # https://github.com/actions/runner-images/issues/8953 + - run: sudo apt-get install binutils-dev libunwind-dev + - run: cargo hfuzz build --no-default-features --features honggfuzz + working-directory: fuzz + + doc: + name: Documentation + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - uses: dtolnay/install@cargo-docs-rs + - run: cargo docs-rs + + clippy: + name: Clippy + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: clippy, rust-src + - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic + - run: cargo clippy --tests --all-features -- -Dclippy::all -Dclippy::pedantic + + miri: + name: Miri + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@miri + - run: cargo miri setup + - run: cargo miri test + env: + MIRIFLAGS: -Zmiri-strict-provenance + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --workspace --exit-code 1 + - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1 diff --git a/zerocopy/vendor/proc-macro2/Cargo.lock b/zerocopy/vendor/proc-macro2/Cargo.lock new file mode 100644 index 0000000000..ded03208d3 --- /dev/null +++ b/zerocopy/vendor/proc-macro2/Cargo.lock @@ -0,0 +1,313 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "proc-macro2" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e1ced3fe749df87a909c23e9607ab9a09c8f0bedb7e03b8146f4c08c298673" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2" +version = "1.0.91" +dependencies = [ + "flate2", + "quote", + "rayon", + "rustversion", + "tar", + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2 1.0.90", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustix" +version = "0.38.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "tar" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] diff --git a/zerocopy/vendor/proc-macro2/Cargo.toml b/zerocopy/vendor/proc-macro2/Cargo.toml index 10d7f75d23..2805ff3f9c 100644 --- a/zerocopy/vendor/proc-macro2/Cargo.toml +++ b/zerocopy/vendor/proc-macro2/Cargo.toml @@ -13,11 +13,16 @@ edition = "2021" rust-version = "1.56" name = "proc-macro2" -version = "1.0.80" +version = "1.0.91" authors = [ "David Tolnay ", "Alex Crichton ", ] +build = "build.rs" +autolib = false +autobins = false +autoexamples = false +autotests = false autobenches = false description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case." documentation = "https://docs.rs/proc-macro2" @@ -38,8 +43,6 @@ rustc-args = [ rustdoc-args = [ "--cfg", "procmacro2_semver_exempt", - "--cfg", - "doc_cfg", "--generate-link-to-definition", ] targets = ["x86_64-unknown-linux-gnu"] @@ -48,8 +51,34 @@ targets = ["x86_64-unknown-linux-gnu"] features = ["span-locations"] [lib] +name = "proc_macro2" +path = "src/lib.rs" doc-scrape-examples = false +[[test]] +name = "comments" +path = "tests/comments.rs" + +[[test]] +name = "features" +path = "tests/features.rs" + +[[test]] +name = "marker" +path = "tests/marker.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[[test]] +name = "test_fmt" +path = "tests/test_fmt.rs" + +[[test]] +name = "test_size" +path = "tests/test_size.rs" + [dependencies.unicode-ident] version = "1.0" @@ -58,7 +87,7 @@ version = "1.0" [dev-dependencies.quote] version = "1.0" -default_features = false +default-features = false [dev-dependencies.rayon] version = "1.0" diff --git a/zerocopy/vendor/proc-macro2/Cargo.toml.orig b/zerocopy/vendor/proc-macro2/Cargo.toml.orig new file mode 100644 index 0000000000..a98b8fe0ae --- /dev/null +++ b/zerocopy/vendor/proc-macro2/Cargo.toml.orig @@ -0,0 +1,62 @@ +[package] +name = "proc-macro2" +version = "1.0.91" +authors = ["David Tolnay ", "Alex Crichton "] +autobenches = false +categories = ["development-tools::procedural-macro-helpers"] +description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case." +documentation = "https://docs.rs/proc-macro2" +edition = "2021" +keywords = ["macros", "syn"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/proc-macro2" +rust-version = "1.56" + +[package.metadata.docs.rs] +rustc-args = ["--cfg", "procmacro2_semver_exempt"] +rustdoc-args = ["--cfg", "procmacro2_semver_exempt", "--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = ["span-locations"] + +[dependencies] +unicode-ident = "1.0" + +[dev-dependencies] +flate2 = "1.0" +quote = { version = "1.0", default-features = false } +rayon = "1.0" +rustversion = "1" +tar = "0.4" + +[features] +proc-macro = [] +default = ["proc-macro"] + +# Expose methods Span::start and Span::end which give the line/column location +# of a token. +span-locations = [] + +# This feature no longer means anything. +nightly = [] + +[lib] +doc-scrape-examples = false + +[workspace] +members = ["benches/bench-libproc-macro", "tests/ui"] + +[patch.crates-io] +# Our doc tests depend on quote which depends on proc-macro2. Without this line, +# the proc-macro2 dependency of quote would be the released version of +# proc-macro2. Quote would implement its traits for types from that proc-macro2, +# meaning impls would be missing when tested against types from the local +# proc-macro2. +# +# GitHub Actions builds that are in progress at the time that you publish may +# spuriously fail. This is because they'll be building a local proc-macro2 which +# carries the second-most-recent version number, pulling in quote which resolves +# to a dependency on the just-published most recent version number. Thus the +# patch will fail to apply because the version numbers are different. +proc-macro2 = { path = "." } diff --git a/zerocopy/vendor/proc-macro2/build.rs b/zerocopy/vendor/proc-macro2/build.rs index 656c569e88..bced1e0a4f 100644 --- a/zerocopy/vendor/proc-macro2/build.rs +++ b/zerocopy/vendor/proc-macro2/build.rs @@ -1,41 +1,10 @@ -// rustc-cfg emitted by the build script: -// -// "wrap_proc_macro" -// Wrap types from libproc_macro rather than polyfilling the whole API. -// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, -// because we can't emulate the unstable API without emulating everything -// else. Also enabled unconditionally on nightly, in which case the -// procmacro2_semver_exempt surface area is implemented by using the -// nightly-only proc_macro API. -// -// "hygiene" -// Enable Span::mixed_site() and non-dummy behavior of Span::resolved_at -// and Span::located_at. Enabled on Rust 1.45+. -// -// "proc_macro_span" -// Enable non-dummy behavior of Span::start and Span::end methods which -// requires an unstable compiler feature. Enabled when building with -// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable -// features. -// -// "super_unstable" -// Implement the semver exempt API in terms of the nightly-only proc_macro -// API. Enabled when using procmacro2_semver_exempt on a nightly compiler. -// -// "span_locations" -// Provide methods Span::start and Span::end which give the line/column -// location of a token. Enabled by procmacro2_semver_exempt or the -// "span-locations" Cargo cfg. This is behind a cfg because tracking -// location inside spans is a performance hit. -// -// "is_available" -// Use proc_macro::is_available() to detect if the proc macro API is -// available or needs to be polyfilled instead of trying to use the proc -// macro API and catching a panic if it isn't available. Enabled on Rust -// 1.57+. +#![allow(unknown_lints)] +#![allow(unexpected_cfgs)] use std::env; use std::ffi::OsString; +use std::fs; +use std::io::ErrorKind; use std::iter; use std::path::Path; use std::process::{self, Command, Stdio}; @@ -44,6 +13,22 @@ use std::str; fn main() { let rustc = rustc_minor_version().unwrap_or(u32::MAX); + if rustc >= 80 { + println!("cargo:rustc-check-cfg=cfg(fuzzing)"); + println!("cargo:rustc-check-cfg=cfg(no_is_available)"); + println!("cargo:rustc-check-cfg=cfg(no_literal_byte_character)"); + println!("cargo:rustc-check-cfg=cfg(no_literal_c_string)"); + println!("cargo:rustc-check-cfg=cfg(no_source_text)"); + println!("cargo:rustc-check-cfg=cfg(proc_macro_span)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_backtrace)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_nightly_testing)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_semver_exempt)"); + println!("cargo:rustc-check-cfg=cfg(randomize_layout)"); + println!("cargo:rustc-check-cfg=cfg(span_locations)"); + println!("cargo:rustc-check-cfg=cfg(super_unstable)"); + println!("cargo:rustc-check-cfg=cfg(wrap_proc_macro)"); + } + let docs_rs = env::var_os("DOCS_RS").is_some(); let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; if semver_exempt { @@ -52,18 +37,28 @@ fn main() { } if semver_exempt || cfg!(feature = "span-locations") { + // Provide methods Span::start and Span::end which give the line/column + // location of a token. This is behind a cfg because tracking location + // inside spans is a performance hit. println!("cargo:rustc-cfg=span_locations"); } if rustc < 57 { + // Do not use proc_macro::is_available() to detect whether the proc + // macro API is available vs needs to be polyfilled. Instead, use the + // proc macro API unconditionally and catch the panic that occurs if it + // isn't available. println!("cargo:rustc-cfg=no_is_available"); } if rustc < 66 { + // Do not call libproc_macro's Span::source_text. Always return None. println!("cargo:rustc-cfg=no_source_text"); } if rustc < 79 { + // Do not call Literal::byte_character nor Literal::c_string. They can + // be emulated by way of Literal::from_str. println!("cargo:rustc-cfg=no_literal_byte_character"); println!("cargo:rustc-cfg=no_literal_c_string"); } @@ -111,14 +106,26 @@ fn main() { } if proc_macro_span || !semver_exempt { + // Wrap types from libproc_macro rather than polyfilling the whole API. + // Enabled as long as procmacro2_semver_exempt is not set, because we + // can't emulate the unstable API without emulating everything else. + // Also enabled unconditionally on nightly, in which case the + // procmacro2_semver_exempt surface area is implemented by using the + // nightly-only proc_macro API. println!("cargo:rustc-cfg=wrap_proc_macro"); } if proc_macro_span { + // Enable non-dummy behavior of Span::start and Span::end methods which + // requires an unstable compiler feature. Enabled when building with + // nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable + // features. println!("cargo:rustc-cfg=proc_macro_span"); } if semver_exempt && proc_macro_span { + // Implement the semver exempt API in terms of the nightly-only + // proc_macro API. println!("cargo:rustc-cfg=super_unstable"); } @@ -141,8 +148,16 @@ fn compile_probe(rustc_bootstrap: bool) -> bool { let rustc = cargo_env_var("RUSTC"); let out_dir = cargo_env_var("OUT_DIR"); + let out_subdir = Path::new(&out_dir).join("probe"); let probefile = Path::new("build").join("probe.rs"); + if let Err(err) = fs::create_dir(&out_subdir) { + if err.kind() != ErrorKind::AlreadyExists { + eprintln!("Failed to create {}: {}", out_subdir.display(), err); + process::exit(1); + } + } + let rustc_wrapper = env::var_os("RUSTC_WRAPPER").filter(|wrapper| !wrapper.is_empty()); let rustc_workspace_wrapper = env::var_os("RUSTC_WORKSPACE_WRAPPER").filter(|wrapper| !wrapper.is_empty()); @@ -164,7 +179,7 @@ fn compile_probe(rustc_bootstrap: bool) -> bool { .arg("--cap-lints=allow") .arg("--emit=dep-info,metadata") .arg("--out-dir") - .arg(out_dir) + .arg(&out_subdir) .arg(probefile); if let Some(target) = env::var_os("TARGET") { @@ -180,10 +195,22 @@ fn compile_probe(rustc_bootstrap: bool) -> bool { } } - match cmd.status() { + let success = match cmd.status() { Ok(status) => status.success(), Err(_) => false, + }; + + // Clean up to avoid leaving nondeterministic absolute paths in the dep-info + // file in OUT_DIR, which causes nonreproducible builds in build systems + // that treat the entire OUT_DIR as an artifact. + if let Err(err) = fs::remove_dir_all(&out_subdir) { + if err.kind() != ErrorKind::NotFound { + eprintln!("Failed to clean up {}: {}", out_subdir.display(), err); + process::exit(1); + } } + + success } fn rustc_minor_version() -> Option { diff --git a/zerocopy/vendor/proc-macro2/build/probe.rs b/zerocopy/vendor/proc-macro2/build/probe.rs index 2c4947a0b8..79c8ae2336 100644 --- a/zerocopy/vendor/proc-macro2/build/probe.rs +++ b/zerocopy/vendor/proc-macro2/build/probe.rs @@ -13,6 +13,22 @@ pub fn byte_range(this: &Span) -> Range { this.byte_range() } +pub fn start(this: &Span) -> Span { + this.start() +} + +pub fn end(this: &Span) -> Span { + this.end() +} + +pub fn line(this: &Span) -> usize { + this.line() +} + +pub fn column(this: &Span) -> usize { + this.column() +} + pub fn join(this: &Span, other: Span) -> Option { this.join(other) } diff --git a/zerocopy/vendor/proc-macro2/src/extra.rs b/zerocopy/vendor/proc-macro2/src/extra.rs index 543ec1d9bd..522a90e136 100644 --- a/zerocopy/vendor/proc-macro2/src/extra.rs +++ b/zerocopy/vendor/proc-macro2/src/extra.rs @@ -69,7 +69,7 @@ use core::fmt::{self, Debug}; /// This function is not applicable to and will panic if called from a /// procedural macro. #[cfg(span_locations)] -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] pub fn invalidate_current_thread_spans() { crate::imp::invalidate_current_thread_spans(); } diff --git a/zerocopy/vendor/proc-macro2/src/fallback.rs b/zerocopy/vendor/proc-macro2/src/fallback.rs index b42537b272..92b342f21a 100644 --- a/zerocopy/vendor/proc-macro2/src/fallback.rs +++ b/zerocopy/vendor/proc-macro2/src/fallback.rs @@ -1,3 +1,5 @@ +#[cfg(wrap_proc_macro)] +use crate::imp; #[cfg(span_locations)] use crate::location::LineColumn; use crate::parse::{self, Cursor}; @@ -15,8 +17,12 @@ use core::mem::ManuallyDrop; use core::ops::Range; use core::ops::RangeBounds; use core::ptr; -use core::str::{self, FromStr}; +use core::str; +#[cfg(feature = "proc-macro")] +use core::str::FromStr; use std::ffi::CStr; +#[cfg(wrap_proc_macro)] +use std::panic; #[cfg(procmacro2_semver_exempt)] use std::path::PathBuf; @@ -57,13 +63,31 @@ impl LexError { } impl TokenStream { - pub fn new() -> Self { + pub(crate) fn new() -> Self { TokenStream { inner: RcVecBuilder::new().build(), } } - pub fn is_empty(&self) -> bool { + pub(crate) fn from_str_checked(src: &str) -> Result { + // Create a dummy file & add it to the source map + let mut cursor = get_cursor(src); + + // Strip a byte order mark if present + const BYTE_ORDER_MARK: &str = "\u{feff}"; + if cursor.starts_with(BYTE_ORDER_MARK) { + cursor = cursor.advance(BYTE_ORDER_MARK.len()); + } + + parse::token_stream(cursor) + } + + #[cfg(feature = "proc-macro")] + pub(crate) fn from_str_unchecked(src: &str) -> Self { + Self::from_str_checked(src).unwrap() + } + + pub(crate) fn is_empty(&self) -> bool { self.inner.len() == 0 } @@ -125,23 +149,23 @@ pub(crate) struct TokenStreamBuilder { } impl TokenStreamBuilder { - pub fn new() -> Self { + pub(crate) fn new() -> Self { TokenStreamBuilder { inner: RcVecBuilder::new(), } } - pub fn with_capacity(cap: usize) -> Self { + pub(crate) fn with_capacity(cap: usize) -> Self { TokenStreamBuilder { inner: RcVecBuilder::with_capacity(cap), } } - pub fn push_token_from_parser(&mut self, tt: TokenTree) { + pub(crate) fn push_token_from_parser(&mut self, tt: TokenTree) { self.inner.push(tt); } - pub fn build(self) -> TokenStream { + pub(crate) fn build(self) -> TokenStream { TokenStream { inner: self.inner.build(), } @@ -170,23 +194,6 @@ fn get_cursor(src: &str) -> Cursor { Cursor { rest: src } } -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - // Create a dummy file & add it to the source map - let mut cursor = get_cursor(src); - - // Strip a byte order mark if present - const BYTE_ORDER_MARK: &str = "\u{feff}"; - if cursor.starts_with(BYTE_ORDER_MARK) { - cursor = cursor.advance(BYTE_ORDER_MARK.len()); - } - - parse::token_stream(cursor) - } -} - impl Display for LexError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("cannot parse string into token stream") @@ -226,20 +233,14 @@ impl Debug for TokenStream { #[cfg(feature = "proc-macro")] impl From for TokenStream { fn from(inner: proc_macro::TokenStream) -> Self { - inner - .to_string() - .parse() - .expect("compiler token stream parse failed") + TokenStream::from_str_unchecked(&inner.to_string()) } } #[cfg(feature = "proc-macro")] impl From for proc_macro::TokenStream { fn from(inner: TokenStream) -> Self { - inner - .to_string() - .parse() - .expect("failed to parse to compiler tokens") + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) } } @@ -308,11 +309,11 @@ pub(crate) struct SourceFile { #[cfg(procmacro2_semver_exempt)] impl SourceFile { /// Get the path to this source file as a string. - pub fn path(&self) -> PathBuf { + pub(crate) fn path(&self) -> PathBuf { self.path.clone() } - pub fn is_real(&self) -> bool { + pub(crate) fn is_real(&self) -> bool { false } } @@ -514,37 +515,37 @@ pub(crate) struct Span { impl Span { #[cfg(not(span_locations))] - pub fn call_site() -> Self { + pub(crate) fn call_site() -> Self { Span {} } #[cfg(span_locations)] - pub fn call_site() -> Self { + pub(crate) fn call_site() -> Self { Span { lo: 0, hi: 0 } } - pub fn mixed_site() -> Self { + pub(crate) fn mixed_site() -> Self { Span::call_site() } #[cfg(procmacro2_semver_exempt)] - pub fn def_site() -> Self { + pub(crate) fn def_site() -> Self { Span::call_site() } - pub fn resolved_at(&self, _other: Span) -> Span { + pub(crate) fn resolved_at(&self, _other: Span) -> Span { // Stable spans consist only of line/column information, so // `resolved_at` and `located_at` only select which span the // caller wants line/column information from. *self } - pub fn located_at(&self, other: Span) -> Span { + pub(crate) fn located_at(&self, other: Span) -> Span { other } #[cfg(procmacro2_semver_exempt)] - pub fn source_file(&self) -> SourceFile { + pub(crate) fn source_file(&self) -> SourceFile { #[cfg(fuzzing)] return SourceFile { path: PathBuf::from(""), @@ -559,7 +560,7 @@ impl Span { } #[cfg(span_locations)] - pub fn byte_range(&self) -> Range { + pub(crate) fn byte_range(&self) -> Range { #[cfg(fuzzing)] return 0..0; @@ -574,7 +575,7 @@ impl Span { } #[cfg(span_locations)] - pub fn start(&self) -> LineColumn { + pub(crate) fn start(&self) -> LineColumn { #[cfg(fuzzing)] return LineColumn { line: 0, column: 0 }; @@ -587,7 +588,7 @@ impl Span { } #[cfg(span_locations)] - pub fn end(&self) -> LineColumn { + pub(crate) fn end(&self) -> LineColumn { #[cfg(fuzzing)] return LineColumn { line: 0, column: 0 }; @@ -600,12 +601,12 @@ impl Span { } #[cfg(not(span_locations))] - pub fn join(&self, _other: Span) -> Option { + pub(crate) fn join(&self, _other: Span) -> Option { Some(Span {}) } #[cfg(span_locations)] - pub fn join(&self, other: Span) -> Option { + pub(crate) fn join(&self, other: Span) -> Option { #[cfg(fuzzing)] return { let _ = other; @@ -627,12 +628,12 @@ impl Span { } #[cfg(not(span_locations))] - pub fn source_text(&self) -> Option { + pub(crate) fn source_text(&self) -> Option { None } #[cfg(span_locations)] - pub fn source_text(&self) -> Option { + pub(crate) fn source_text(&self) -> Option { #[cfg(fuzzing)] return None; @@ -709,7 +710,7 @@ pub(crate) struct Group { } impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + pub(crate) fn new(delimiter: Delimiter, stream: TokenStream) -> Self { Group { delimiter, stream, @@ -717,27 +718,27 @@ impl Group { } } - pub fn delimiter(&self) -> Delimiter { + pub(crate) fn delimiter(&self) -> Delimiter { self.delimiter } - pub fn stream(&self) -> TokenStream { + pub(crate) fn stream(&self) -> TokenStream { self.stream.clone() } - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { self.span } - pub fn span_open(&self) -> Span { + pub(crate) fn span_open(&self) -> Span { self.span.first_byte() } - pub fn span_close(&self) -> Span { + pub(crate) fn span_close(&self) -> Span { self.span.last_byte() } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { self.span = span; } } @@ -781,45 +782,45 @@ impl Debug for Group { #[derive(Clone)] pub(crate) struct Ident { - sym: String, + sym: Box, span: Span, raw: bool, } impl Ident { #[track_caller] - pub fn new_checked(string: &str, span: Span) -> Self { + pub(crate) fn new_checked(string: &str, span: Span) -> Self { validate_ident(string); Ident::new_unchecked(string, span) } - pub fn new_unchecked(string: &str, span: Span) -> Self { + pub(crate) fn new_unchecked(string: &str, span: Span) -> Self { Ident { - sym: string.to_owned(), + sym: Box::from(string), span, raw: false, } } #[track_caller] - pub fn new_raw_checked(string: &str, span: Span) -> Self { + pub(crate) fn new_raw_checked(string: &str, span: Span) -> Self { validate_ident_raw(string); Ident::new_raw_unchecked(string, span) } - pub fn new_raw_unchecked(string: &str, span: Span) -> Self { + pub(crate) fn new_raw_unchecked(string: &str, span: Span) -> Self { Ident { - sym: string.to_owned(), + sym: Box::from(string), span, raw: true, } } - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { self.span } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { self.span = span; } } @@ -886,9 +887,9 @@ where fn eq(&self, other: &T) -> bool { let other = other.as_ref(); if self.raw { - other.starts_with("r#") && self.sym == other[2..] + other.starts_with("r#") && *self.sym == other[2..] } else { - self.sym == other + *self.sym == *other } } } @@ -933,7 +934,7 @@ pub(crate) struct Literal { macro_rules! suffixed_numbers { ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { + pub(crate) fn $name(n: $kind) -> Literal { Literal::_new(format!(concat!("{}", stringify!($kind)), n)) } )*) @@ -941,7 +942,7 @@ macro_rules! suffixed_numbers { macro_rules! unsuffixed_numbers { ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { + pub(crate) fn $name(n: $kind) -> Literal { Literal::_new(n.to_string()) } )*) @@ -955,6 +956,36 @@ impl Literal { } } + pub(crate) fn from_str_checked(repr: &str) -> Result { + let mut cursor = get_cursor(repr); + #[cfg(span_locations)] + let lo = cursor.off; + + let negative = cursor.starts_with_char('-'); + if negative { + cursor = cursor.advance(1); + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { + return Err(LexError::call_site()); + } + } + + if let Ok((rest, mut literal)) = parse::literal(cursor) { + if rest.is_empty() { + if negative { + literal.repr.insert(0, '-'); + } + literal.span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; + return Ok(literal); + } + } + Err(LexError::call_site()) + } + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { Literal::_new(repr.to_owned()) } @@ -992,7 +1023,7 @@ impl Literal { isize_unsuffixed => isize, } - pub fn f32_unsuffixed(f: f32) -> Literal { + pub(crate) fn f32_unsuffixed(f: f32) -> Literal { let mut s = f.to_string(); if !s.contains('.') { s.push_str(".0"); @@ -1000,7 +1031,7 @@ impl Literal { Literal::_new(s) } - pub fn f64_unsuffixed(f: f64) -> Literal { + pub(crate) fn f64_unsuffixed(f: f64) -> Literal { let mut s = f.to_string(); if !s.contains('.') { s.push_str(".0"); @@ -1008,7 +1039,7 @@ impl Literal { Literal::_new(s) } - pub fn string(string: &str) -> Literal { + pub(crate) fn string(string: &str) -> Literal { let mut repr = String::with_capacity(string.len() + 2); repr.push('"'); escape_utf8(string, &mut repr); @@ -1016,7 +1047,7 @@ impl Literal { Literal::_new(repr) } - pub fn character(ch: char) -> Literal { + pub(crate) fn character(ch: char) -> Literal { let mut repr = String::new(); repr.push('\''); if ch == '"' { @@ -1029,7 +1060,7 @@ impl Literal { Literal::_new(repr) } - pub fn byte_character(byte: u8) -> Literal { + pub(crate) fn byte_character(byte: u8) -> Literal { let mut repr = "b'".to_string(); #[allow(clippy::match_overlapping_arm)] match byte { @@ -1048,7 +1079,7 @@ impl Literal { Literal::_new(repr) } - pub fn byte_string(bytes: &[u8]) -> Literal { + pub(crate) fn byte_string(bytes: &[u8]) -> Literal { let mut repr = "b\"".to_string(); let mut bytes = bytes.iter(); while let Some(&b) = bytes.next() { @@ -1074,7 +1105,7 @@ impl Literal { Literal::_new(repr) } - pub fn c_string(string: &CStr) -> Literal { + pub(crate) fn c_string(string: &CStr) -> Literal { let mut repr = "c\"".to_string(); let mut bytes = string.to_bytes(); while !bytes.is_empty() { @@ -1102,15 +1133,15 @@ impl Literal { Literal::_new(repr) } - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { self.span } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { self.span = span; } - pub fn subspan>(&self, range: R) -> Option { + pub(crate) fn subspan>(&self, range: R) -> Option { #[cfg(not(span_locations))] { let _ = range; @@ -1152,40 +1183,6 @@ impl Literal { } } -impl FromStr for Literal { - type Err = LexError; - - fn from_str(repr: &str) -> Result { - let mut cursor = get_cursor(repr); - #[cfg(span_locations)] - let lo = cursor.off; - - let negative = cursor.starts_with_char('-'); - if negative { - cursor = cursor.advance(1); - if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { - return Err(LexError::call_site()); - } - } - - if let Ok((rest, mut literal)) = parse::literal(cursor) { - if rest.is_empty() { - if negative { - literal.repr.insert(0, '-'); - } - literal.span = Span { - #[cfg(span_locations)] - lo, - #[cfg(span_locations)] - hi: rest.off, - }; - return Ok(literal); - } - } - Err(LexError::call_site()) - } -} - impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.repr, f) @@ -1224,3 +1221,46 @@ fn escape_utf8(string: &str, repr: &mut String) { } } } + +#[cfg(feature = "proc-macro")] +pub(crate) trait FromStr2: FromStr { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool; + + #[cfg(wrap_proc_macro)] + fn from_str_checked(src: &str) -> Result { + // Validate using fallback parser, because rustc is incapable of + // returning a recoverable Err for certain invalid token streams, and + // will instead permanently poison the compilation. + if !Self::valid(src) { + return Err(imp::LexError::CompilerPanic); + } + + // Catch panic to work around https://github.com/rust-lang/rust/issues/58736. + match panic::catch_unwind(|| Self::from_str(src)) { + Ok(Ok(ok)) => Ok(ok), + Ok(Err(lex)) => Err(imp::LexError::Compiler(lex)), + Err(_panic) => Err(imp::LexError::CompilerPanic), + } + } + + fn from_str_unchecked(src: &str) -> Self { + Self::from_str(src).unwrap() + } +} + +#[cfg(feature = "proc-macro")] +impl FromStr2 for proc_macro::TokenStream { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool { + TokenStream::from_str_checked(src).is_ok() + } +} + +#[cfg(feature = "proc-macro")] +impl FromStr2 for proc_macro::Literal { + #[cfg(wrap_proc_macro)] + fn valid(src: &str) -> bool { + Literal::from_str_checked(src).is_ok() + } +} diff --git a/zerocopy/vendor/proc-macro2/src/lib.rs b/zerocopy/vendor/proc-macro2/src/lib.rs index 681b0c2d05..7966177663 100644 --- a/zerocopy/vendor/proc-macro2/src/lib.rs +++ b/zerocopy/vendor/proc-macro2/src/lib.rs @@ -86,10 +86,10 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.80")] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.91")] #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] #![cfg_attr(super_unstable, feature(proc_macro_def_site))] -#![cfg_attr(doc_cfg, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![deny(unsafe_op_in_unsafe_fn)] #![allow( clippy::cast_lossless, @@ -102,9 +102,11 @@ clippy::let_underscore_untyped, clippy::manual_assert, clippy::manual_range_contains, + clippy::missing_panics_doc, clippy::missing_safety_doc, clippy::must_use_candidate, clippy::needless_doctest_main, + clippy::needless_lifetimes, clippy::new_without_default, clippy::return_self_not_must_use, clippy::shadow_unrelated, @@ -175,7 +177,7 @@ use std::ffi::CStr; use std::path::PathBuf; #[cfg(span_locations)] -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] pub use crate::location::LineColumn; /// An abstract stream of tokens, or more concretely a sequence of token trees. @@ -207,7 +209,7 @@ impl TokenStream { fn _new_fallback(inner: fallback::TokenStream) -> Self { TokenStream { - inner: inner.into(), + inner: imp::TokenStream::from(inner), _marker: MARKER, } } @@ -243,27 +245,29 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - let e = src.parse().map_err(|e| LexError { - inner: e, - _marker: MARKER, - })?; - Ok(TokenStream::_new(e)) + match imp::TokenStream::from_str_checked(src) { + Ok(tokens) => Ok(TokenStream::_new(tokens)), + Err(lex) => Err(LexError { + inner: lex, + _marker: MARKER, + }), + } } } #[cfg(feature = "proc-macro")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] +#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] impl From for TokenStream { fn from(inner: proc_macro::TokenStream) -> Self { - TokenStream::_new(inner.into()) + TokenStream::_new(imp::TokenStream::from(inner)) } } #[cfg(feature = "proc-macro")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] +#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] impl From for proc_macro::TokenStream { fn from(inner: TokenStream) -> Self { - inner.inner.into() + proc_macro::TokenStream::from(inner.inner) } } @@ -339,7 +343,7 @@ impl Error for LexError {} /// /// This type is semver exempt and not exposed by default. #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] -#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] +#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] #[derive(Clone, PartialEq, Eq)] pub struct SourceFile { inner: imp::SourceFile, @@ -403,7 +407,7 @@ impl Span { fn _new_fallback(inner: fallback::Span) -> Self { Span { - inner: inner.into(), + inner: imp::Span::from(inner), _marker: MARKER, } } @@ -428,7 +432,7 @@ impl Span { /// /// This method is semver exempt and not exposed by default. #[cfg(procmacro2_semver_exempt)] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] pub fn def_site() -> Self { Span::_new(imp::Span::def_site()) } @@ -471,7 +475,7 @@ impl Span { /// /// This method is semver exempt and not exposed by default. #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] pub fn source_file(&self) -> SourceFile { SourceFile::_new(self.inner.source_file()) } @@ -486,7 +490,7 @@ impl Span { /// procedural macro, such as main.rs or build.rs, the byte range is always /// accurate regardless of toolchain. #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] pub fn byte_range(&self) -> Range { self.inner.byte_range() } @@ -501,7 +505,7 @@ impl Span { /// outside of a procedural macro, such as main.rs or build.rs, the /// line/column are always meaningful regardless of toolchain. #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] pub fn start(&self) -> LineColumn { self.inner.start() } @@ -516,7 +520,7 @@ impl Span { /// outside of a procedural macro, such as main.rs or build.rs, the /// line/column are always meaningful regardless of toolchain. #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] pub fn end(&self) -> LineColumn { self.inner.end() } @@ -538,7 +542,7 @@ impl Span { /// /// This method is semver exempt and not exposed by default. #[cfg(procmacro2_semver_exempt)] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] pub fn eq(&self, other: &Span) -> bool { self.inner.eq(&other.inner) } @@ -678,13 +682,25 @@ pub enum Delimiter { Brace, /// `[ ... ]` Bracket, - /// `Ø ... Ø` + /// `∅ ... ∅` /// - /// An implicit delimiter, that may, for example, appear around tokens + /// An invisible delimiter, that may, for example, appear around tokens /// coming from a "macro variable" `$var`. It is important to preserve /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. - /// Implicit delimiters may not survive roundtrip of a token stream through + /// Invisible delimiters may not survive roundtrip of a token stream through /// a string. + /// + ///
+ /// + /// Note: rustc currently can ignore the grouping of tokens delimited by `None` in the output + /// of a proc_macro. Only `None`-delimited groups created by a macro_rules macro in the input + /// of a proc_macro macro are preserved, and only in very specific circumstances. + /// Any `None`-delimited groups (re)created by a proc_macro will therefore not preserve + /// operator priorities as indicated above. The other `Delimiter` variants should be used + /// instead in this context. This is a rustc bug. For details, see + /// [rust-lang/rust#67062](https://github.com/rust-lang/rust/issues/67062). + /// + ///
None, } @@ -695,7 +711,7 @@ impl Group { fn _new_fallback(inner: fallback::Group) -> Self { Group { - inner: inner.into(), + inner: imp::Group::from(inner), } } @@ -821,10 +837,16 @@ impl Punct { /// The returned `Punct` will have the default span of `Span::call_site()` /// which can be further configured with the `set_span` method below. pub fn new(ch: char, spacing: Spacing) -> Self { - Punct { - ch, - spacing, - span: Span::call_site(), + if let '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' + | '<' | '=' | '>' | '?' | '@' | '^' | '|' | '~' = ch + { + Punct { + ch, + spacing, + span: Span::call_site(), + } + } else { + panic!("unsupported proc macro punctuation character {:?}", ch); } } @@ -949,6 +971,13 @@ impl Ident { } } + fn _new_fallback(inner: fallback::Ident) -> Self { + Ident { + inner: imp::Ident::from(inner), + _marker: MARKER, + } + } + /// Creates a new `Ident` with the given `string` as well as the specified /// `span`. /// @@ -1118,7 +1147,7 @@ impl Literal { fn _new_fallback(inner: fallback::Literal) -> Self { Literal { - inner: inner.into(), + inner: imp::Literal::from(inner), _marker: MARKER, } } @@ -1287,10 +1316,13 @@ impl FromStr for Literal { type Err = LexError; fn from_str(repr: &str) -> Result { - repr.parse().map(Literal::_new).map_err(|inner| LexError { - inner, - _marker: MARKER, - }) + match imp::Literal::from_str_checked(repr) { + Ok(lit) => Ok(Literal::_new(lit)), + Err(lex) => Err(LexError { + inner: lex, + _marker: MARKER, + }), + } } } diff --git a/zerocopy/vendor/proc-macro2/src/location.rs b/zerocopy/vendor/proc-macro2/src/location.rs index 463026c274..7190e2d052 100644 --- a/zerocopy/vendor/proc-macro2/src/location.rs +++ b/zerocopy/vendor/proc-macro2/src/location.rs @@ -3,7 +3,7 @@ use core::cmp::Ordering; /// A line-column pair representing the start or end of a `Span`. /// /// This type is semver exempt and not exposed by default. -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct LineColumn { /// The 1-indexed line in the source file on which the span starts or ends diff --git a/zerocopy/vendor/proc-macro2/src/parse.rs b/zerocopy/vendor/proc-macro2/src/parse.rs index 07239bc3ad..497b68daa4 100644 --- a/zerocopy/vendor/proc-macro2/src/parse.rs +++ b/zerocopy/vendor/proc-macro2/src/parse.rs @@ -1,5 +1,5 @@ use crate::fallback::{ - self, is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream, + self, is_ident_continue, is_ident_start, Group, Ident, LexError, Literal, Span, TokenStream, TokenStreamBuilder, }; use crate::{Delimiter, Punct, Spacing, TokenTree}; @@ -8,13 +8,13 @@ use core::str::{Bytes, CharIndices, Chars}; #[derive(Copy, Clone, Eq, PartialEq)] pub(crate) struct Cursor<'a> { - pub rest: &'a str, + pub(crate) rest: &'a str, #[cfg(span_locations)] - pub off: u32, + pub(crate) off: u32, } impl<'a> Cursor<'a> { - pub fn advance(&self, bytes: usize) -> Cursor<'a> { + pub(crate) fn advance(&self, bytes: usize) -> Cursor<'a> { let (_front, rest) = self.rest.split_at(bytes); Cursor { rest, @@ -23,22 +23,22 @@ impl<'a> Cursor<'a> { } } - pub fn starts_with(&self, s: &str) -> bool { + pub(crate) fn starts_with(&self, s: &str) -> bool { self.rest.starts_with(s) } - pub fn starts_with_char(&self, ch: char) -> bool { + pub(crate) fn starts_with_char(&self, ch: char) -> bool { self.rest.starts_with(ch) } - pub fn starts_with_fn(&self, f: Pattern) -> bool + pub(crate) fn starts_with_fn(&self, f: Pattern) -> bool where Pattern: FnMut(char) -> bool, { self.rest.starts_with(f) } - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.rest.is_empty() } @@ -300,10 +300,8 @@ fn ident_any(input: Cursor) -> PResult { let (rest, sym) = ident_not_raw(rest)?; if !raw { - let ident = crate::Ident::_new(crate::imp::Ident::new_unchecked( - sym, - fallback::Span::call_site(), - )); + let ident = + crate::Ident::_new_fallback(Ident::new_unchecked(sym, fallback::Span::call_site())); return Ok((rest, ident)); } @@ -312,10 +310,8 @@ fn ident_any(input: Cursor) -> PResult { _ => {} } - let ident = crate::Ident::_new(crate::imp::Ident::new_raw_unchecked( - sym, - fallback::Span::call_site(), - )); + let ident = + crate::Ident::_new_fallback(Ident::new_raw_unchecked(sym, fallback::Span::call_site())); Ok((rest, ident)) } @@ -941,10 +937,10 @@ fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult trees.push_token_from_parser(TokenTree::Punct(bang)); } - let doc_ident = crate::Ident::_new(crate::imp::Ident::new_unchecked("doc", fallback_span)); + let doc_ident = crate::Ident::_new_fallback(Ident::new_unchecked("doc", fallback_span)); let mut equal = Punct::new('=', Spacing::Alone); equal.set_span(span); - let mut literal = crate::Literal::string(comment); + let mut literal = crate::Literal::_new_fallback(Literal::string(comment)); literal.set_span(span); let mut bracketed = TokenStreamBuilder::with_capacity(3); bracketed.push_token_from_parser(TokenTree::Ident(doc_ident)); diff --git a/zerocopy/vendor/proc-macro2/src/rcvec.rs b/zerocopy/vendor/proc-macro2/src/rcvec.rs index 37955afb11..cde9f25f2e 100644 --- a/zerocopy/vendor/proc-macro2/src/rcvec.rs +++ b/zerocopy/vendor/proc-macro2/src/rcvec.rs @@ -22,19 +22,19 @@ pub(crate) struct RcVecIntoIter { } impl RcVec { - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.inner.is_empty() } - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.inner.len() } - pub fn iter(&self) -> slice::Iter { + pub(crate) fn iter(&self) -> slice::Iter { self.inner.iter() } - pub fn make_mut(&mut self) -> RcVecMut + pub(crate) fn make_mut(&mut self) -> RcVecMut where T: Clone, { @@ -43,12 +43,12 @@ impl RcVec { } } - pub fn get_mut(&mut self) -> Option> { + pub(crate) fn get_mut(&mut self) -> Option> { let inner = Rc::get_mut(&mut self.inner)?; Some(RcVecMut { inner }) } - pub fn make_owned(mut self) -> RcVecBuilder + pub(crate) fn make_owned(mut self) -> RcVecBuilder where T: Clone, { @@ -62,31 +62,31 @@ impl RcVec { } impl RcVecBuilder { - pub fn new() -> Self { + pub(crate) fn new() -> Self { RcVecBuilder { inner: Vec::new() } } - pub fn with_capacity(cap: usize) -> Self { + pub(crate) fn with_capacity(cap: usize) -> Self { RcVecBuilder { inner: Vec::with_capacity(cap), } } - pub fn push(&mut self, element: T) { + pub(crate) fn push(&mut self, element: T) { self.inner.push(element); } - pub fn extend(&mut self, iter: impl IntoIterator) { + pub(crate) fn extend(&mut self, iter: impl IntoIterator) { self.inner.extend(iter); } - pub fn as_mut(&mut self) -> RcVecMut { + pub(crate) fn as_mut(&mut self) -> RcVecMut { RcVecMut { inner: &mut self.inner, } } - pub fn build(self) -> RcVec { + pub(crate) fn build(self) -> RcVec { RcVec { inner: Rc::new(self.inner), } @@ -94,19 +94,19 @@ impl RcVecBuilder { } impl<'a, T> RcVecMut<'a, T> { - pub fn push(&mut self, element: T) { + pub(crate) fn push(&mut self, element: T) { self.inner.push(element); } - pub fn extend(&mut self, iter: impl IntoIterator) { + pub(crate) fn extend(&mut self, iter: impl IntoIterator) { self.inner.extend(iter); } - pub fn pop(&mut self) -> Option { + pub(crate) fn pop(&mut self) -> Option { self.inner.pop() } - pub fn as_mut(&mut self) -> RcVecMut { + pub(crate) fn as_mut(&mut self) -> RcVecMut { RcVecMut { inner: self.inner } } } diff --git a/zerocopy/vendor/proc-macro2/src/wrapper.rs b/zerocopy/vendor/proc-macro2/src/wrapper.rs index 87e348dbb3..ecf0bb673e 100644 --- a/zerocopy/vendor/proc-macro2/src/wrapper.rs +++ b/zerocopy/vendor/proc-macro2/src/wrapper.rs @@ -1,14 +1,13 @@ use crate::detection::inside_proc_macro; +use crate::fallback::{self, FromStr2 as _}; #[cfg(span_locations)] use crate::location::LineColumn; -use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; +use crate::{Delimiter, Punct, Spacing, TokenTree}; use core::fmt::{self, Debug, Display}; #[cfg(span_locations)] use core::ops::Range; use core::ops::RangeBounds; -use core::str::FromStr; use std::ffi::CStr; -use std::panic; #[cfg(super_unstable)] use std::path::PathBuf; @@ -78,7 +77,7 @@ impl DeferredTokenStream { } impl TokenStream { - pub fn new() -> Self { + pub(crate) fn new() -> Self { if inside_proc_macro() { TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) } else { @@ -86,7 +85,19 @@ impl TokenStream { } } - pub fn is_empty(&self) -> bool { + pub(crate) fn from_str_checked(src: &str) -> Result { + if inside_proc_macro() { + Ok(TokenStream::Compiler(DeferredTokenStream::new( + proc_macro::TokenStream::from_str_checked(src)?, + ))) + } else { + Ok(TokenStream::Fallback( + fallback::TokenStream::from_str_checked(src)?, + )) + } + } + + pub(crate) fn is_empty(&self) -> bool { match self { TokenStream::Compiler(tts) => tts.is_empty(), TokenStream::Fallback(tts) => tts.is_empty(), @@ -108,26 +119,6 @@ impl TokenStream { } } -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - if inside_proc_macro() { - Ok(TokenStream::Compiler(DeferredTokenStream::new( - proc_macro_parse(src)?, - ))) - } else { - Ok(TokenStream::Fallback(src.parse()?)) - } - } -} - -// Work around https://github.com/rust-lang/rust/issues/58736. -fn proc_macro_parse(src: &str) -> Result { - let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); - result.unwrap_or_else(|_| Err(LexError::CompilerPanic)) -} - impl Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -147,7 +138,9 @@ impl From for proc_macro::TokenStream { fn from(inner: TokenStream) -> Self { match inner { TokenStream::Compiler(inner) => inner.into_token_stream(), - TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(), + TokenStream::Fallback(inner) => { + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) + } } } } @@ -161,7 +154,7 @@ impl From for TokenStream { // Assumes inside_proc_macro(). fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { match token { - TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Group(tt) => proc_macro::TokenTree::Group(tt.inner.unwrap_nightly()), TokenTree::Punct(tt) => { let spacing = match tt.spacing() { Spacing::Joint => proc_macro::Spacing::Joint, @@ -169,19 +162,21 @@ fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { }; let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); punct.set_span(tt.span().inner.unwrap_nightly()); - punct.into() + proc_macro::TokenTree::Punct(punct) } - TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(), - TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Ident(tt) => proc_macro::TokenTree::Ident(tt.inner.unwrap_nightly()), + TokenTree::Literal(tt) => proc_macro::TokenTree::Literal(tt.inner.unwrap_nightly()), } } impl From for TokenStream { fn from(token: TokenTree) -> Self { if inside_proc_macro() { - TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into())) + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::from( + into_compiler_token(token), + ))) } else { - TokenStream::Fallback(token.into()) + TokenStream::Fallback(fallback::TokenStream::from(token)) } } } @@ -336,7 +331,9 @@ impl Iterator for TokenTreeIter { TokenTreeIter::Fallback(iter) => return iter.next(), }; Some(match token { - proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), + proc_macro::TokenTree::Group(tt) => { + TokenTree::Group(crate::Group::_new(Group::Compiler(tt))) + } proc_macro::TokenTree::Punct(tt) => { let spacing = match tt.spacing() { proc_macro::Spacing::Joint => Spacing::Joint, @@ -344,10 +341,14 @@ impl Iterator for TokenTreeIter { }; let mut o = Punct::new(tt.as_char(), spacing); o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); - o.into() + TokenTree::Punct(o) + } + proc_macro::TokenTree::Ident(s) => { + TokenTree::Ident(crate::Ident::_new(Ident::Compiler(s))) + } + proc_macro::TokenTree::Literal(l) => { + TokenTree::Literal(crate::Literal::_new(Literal::Compiler(l))) } - proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), - proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), }) } @@ -373,14 +374,14 @@ impl SourceFile { } /// Get the path to this source file as a string. - pub fn path(&self) -> PathBuf { + pub(crate) fn path(&self) -> PathBuf { match self { SourceFile::Compiler(a) => a.path(), SourceFile::Fallback(a) => a.path(), } } - pub fn is_real(&self) -> bool { + pub(crate) fn is_real(&self) -> bool { match self { SourceFile::Compiler(a) => a.is_real(), SourceFile::Fallback(a) => a.is_real(), @@ -405,7 +406,7 @@ pub(crate) enum Span { } impl Span { - pub fn call_site() -> Self { + pub(crate) fn call_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::call_site()) } else { @@ -413,7 +414,7 @@ impl Span { } } - pub fn mixed_site() -> Self { + pub(crate) fn mixed_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::mixed_site()) } else { @@ -422,7 +423,7 @@ impl Span { } #[cfg(super_unstable)] - pub fn def_site() -> Self { + pub(crate) fn def_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::def_site()) } else { @@ -430,7 +431,7 @@ impl Span { } } - pub fn resolved_at(&self, other: Span) -> Span { + pub(crate) fn resolved_at(&self, other: Span) -> Span { match (self, other) { (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), @@ -439,7 +440,7 @@ impl Span { } } - pub fn located_at(&self, other: Span) -> Span { + pub(crate) fn located_at(&self, other: Span) -> Span { match (self, other) { (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), @@ -448,7 +449,7 @@ impl Span { } } - pub fn unwrap(self) -> proc_macro::Span { + pub(crate) fn unwrap(self) -> proc_macro::Span { match self { Span::Compiler(s) => s, Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), @@ -456,7 +457,7 @@ impl Span { } #[cfg(super_unstable)] - pub fn source_file(&self) -> SourceFile { + pub(crate) fn source_file(&self) -> SourceFile { match self { Span::Compiler(s) => SourceFile::nightly(s.source_file()), Span::Fallback(s) => SourceFile::Fallback(s.source_file()), @@ -464,7 +465,7 @@ impl Span { } #[cfg(span_locations)] - pub fn byte_range(&self) -> Range { + pub(crate) fn byte_range(&self) -> Range { match self { #[cfg(proc_macro_span)] Span::Compiler(s) => s.byte_range(), @@ -475,22 +476,37 @@ impl Span { } #[cfg(span_locations)] - pub fn start(&self) -> LineColumn { + pub(crate) fn start(&self) -> LineColumn { match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => LineColumn { + line: s.line(), + column: s.column().saturating_sub(1), + }, + #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => s.start(), } } #[cfg(span_locations)] - pub fn end(&self) -> LineColumn { + pub(crate) fn end(&self) -> LineColumn { match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => { + let end = s.end(); + LineColumn { + line: end.line(), + column: end.column().saturating_sub(1), + } + } + #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => s.end(), } } - pub fn join(&self, other: Span) -> Option { + pub(crate) fn join(&self, other: Span) -> Option { let ret = match (self, other) { #[cfg(proc_macro_span)] (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), @@ -501,7 +517,7 @@ impl Span { } #[cfg(super_unstable)] - pub fn eq(&self, other: &Span) -> bool { + pub(crate) fn eq(&self, other: &Span) -> bool { match (self, other) { (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), @@ -509,7 +525,7 @@ impl Span { } } - pub fn source_text(&self) -> Option { + pub(crate) fn source_text(&self) -> Option { match self { #[cfg(not(no_source_text))] Span::Compiler(s) => s.source_text(), @@ -564,7 +580,7 @@ pub(crate) enum Group { } impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + pub(crate) fn new(delimiter: Delimiter, stream: TokenStream) -> Self { match stream { TokenStream::Compiler(tts) => { let delimiter = match delimiter { @@ -581,7 +597,7 @@ impl Group { } } - pub fn delimiter(&self) -> Delimiter { + pub(crate) fn delimiter(&self) -> Delimiter { match self { Group::Compiler(g) => match g.delimiter() { proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, @@ -593,35 +609,35 @@ impl Group { } } - pub fn stream(&self) -> TokenStream { + pub(crate) fn stream(&self) -> TokenStream { match self { Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), Group::Fallback(g) => TokenStream::Fallback(g.stream()), } } - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { match self { Group::Compiler(g) => Span::Compiler(g.span()), Group::Fallback(g) => Span::Fallback(g.span()), } } - pub fn span_open(&self) -> Span { + pub(crate) fn span_open(&self) -> Span { match self { Group::Compiler(g) => Span::Compiler(g.span_open()), Group::Fallback(g) => Span::Fallback(g.span_open()), } } - pub fn span_close(&self) -> Span { + pub(crate) fn span_close(&self) -> Span { match self { Group::Compiler(g) => Span::Compiler(g.span_close()), Group::Fallback(g) => Span::Fallback(g.span_close()), } } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { match (self, span) { (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), @@ -670,37 +686,29 @@ pub(crate) enum Ident { impl Ident { #[track_caller] - pub fn new_checked(string: &str, span: Span) -> Self { + pub(crate) fn new_checked(string: &str, span: Span) -> Self { match span { Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), } } - pub fn new_unchecked(string: &str, span: fallback::Span) -> Self { - Ident::Fallback(fallback::Ident::new_unchecked(string, span)) - } - #[track_caller] - pub fn new_raw_checked(string: &str, span: Span) -> Self { + pub(crate) fn new_raw_checked(string: &str, span: Span) -> Self { match span { Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), } } - pub fn new_raw_unchecked(string: &str, span: fallback::Span) -> Self { - Ident::Fallback(fallback::Ident::new_raw_unchecked(string, span)) - } - - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { match self { Ident::Compiler(t) => Span::Compiler(t.span()), Ident::Fallback(t) => Span::Fallback(t.span()), } } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { match (self, span) { (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), @@ -717,6 +725,12 @@ impl Ident { } } +impl From for Ident { + fn from(inner: fallback::Ident) -> Self { + Ident::Fallback(inner) + } +} + impl PartialEq for Ident { fn eq(&self, other: &Ident) -> bool { match (self, other) { @@ -767,7 +781,7 @@ pub(crate) enum Literal { macro_rules! suffixed_numbers { ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { + pub(crate) fn $name(n: $kind) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::$name(n)) } else { @@ -779,7 +793,7 @@ macro_rules! suffixed_numbers { macro_rules! unsuffixed_integers { ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { + pub(crate) fn $name(n: $kind) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::$name(n)) } else { @@ -790,9 +804,19 @@ macro_rules! unsuffixed_integers { } impl Literal { - pub unsafe fn from_str_unchecked(repr: &str) -> Self { + pub(crate) fn from_str_checked(repr: &str) -> Result { + if inside_proc_macro() { + let literal = proc_macro::Literal::from_str_checked(repr)?; + Ok(Literal::Compiler(literal)) + } else { + let literal = fallback::Literal::from_str_checked(repr)?; + Ok(Literal::Fallback(literal)) + } + } + + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal")) + Literal::Compiler(proc_macro::Literal::from_str_unchecked(repr)) } else { Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) } @@ -831,7 +855,7 @@ impl Literal { isize_unsuffixed => isize, } - pub fn f32_unsuffixed(f: f32) -> Literal { + pub(crate) fn f32_unsuffixed(f: f32) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) } else { @@ -839,7 +863,7 @@ impl Literal { } } - pub fn f64_unsuffixed(f: f64) -> Literal { + pub(crate) fn f64_unsuffixed(f: f64) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) } else { @@ -847,7 +871,7 @@ impl Literal { } } - pub fn string(string: &str) -> Literal { + pub(crate) fn string(string: &str) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::string(string)) } else { @@ -855,7 +879,7 @@ impl Literal { } } - pub fn character(ch: char) -> Literal { + pub(crate) fn character(ch: char) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::character(ch)) } else { @@ -863,7 +887,7 @@ impl Literal { } } - pub fn byte_character(byte: u8) -> Literal { + pub(crate) fn byte_character(byte: u8) -> Literal { if inside_proc_macro() { Literal::Compiler({ #[cfg(not(no_literal_byte_character))] @@ -874,7 +898,7 @@ impl Literal { #[cfg(no_literal_byte_character)] { let fallback = fallback::Literal::byte_character(byte); - fallback.repr.parse::().unwrap() + proc_macro::Literal::from_str_unchecked(&fallback.repr) } }) } else { @@ -882,7 +906,7 @@ impl Literal { } } - pub fn byte_string(bytes: &[u8]) -> Literal { + pub(crate) fn byte_string(bytes: &[u8]) -> Literal { if inside_proc_macro() { Literal::Compiler(proc_macro::Literal::byte_string(bytes)) } else { @@ -890,7 +914,7 @@ impl Literal { } } - pub fn c_string(string: &CStr) -> Literal { + pub(crate) fn c_string(string: &CStr) -> Literal { if inside_proc_macro() { Literal::Compiler({ #[cfg(not(no_literal_c_string))] @@ -901,7 +925,7 @@ impl Literal { #[cfg(no_literal_c_string)] { let fallback = fallback::Literal::c_string(string); - fallback.repr.parse::().unwrap() + proc_macro::Literal::from_str_unchecked(&fallback.repr) } }) } else { @@ -909,14 +933,14 @@ impl Literal { } } - pub fn span(&self) -> Span { + pub(crate) fn span(&self) -> Span { match self { Literal::Compiler(lit) => Span::Compiler(lit.span()), Literal::Fallback(lit) => Span::Fallback(lit.span()), } } - pub fn set_span(&mut self, span: Span) { + pub(crate) fn set_span(&mut self, span: Span) { match (self, span) { (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), @@ -925,7 +949,7 @@ impl Literal { } } - pub fn subspan>(&self, range: R) -> Option { + pub(crate) fn subspan>(&self, range: R) -> Option { match self { #[cfg(proc_macro_span)] Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), @@ -949,20 +973,6 @@ impl From for Literal { } } -impl FromStr for Literal { - type Err = LexError; - - fn from_str(repr: &str) -> Result { - if inside_proc_macro() { - let literal = proc_macro::Literal::from_str(repr)?; - Ok(Literal::Compiler(literal)) - } else { - let literal = fallback::Literal::from_str(repr)?; - Ok(Literal::Fallback(literal)) - } - } -} - impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/zerocopy/vendor/proc-macro2/tests/test.rs b/zerocopy/vendor/proc-macro2/tests/test.rs index 3923d33487..0d7c88d3df 100644 --- a/zerocopy/vendor/proc-macro2/tests/test.rs +++ b/zerocopy/vendor/proc-macro2/tests/test.rs @@ -541,7 +541,6 @@ testing 123 } #[cfg(procmacro2_semver_exempt)] -#[cfg(not(nightly))] #[test] fn default_span() { let start = Span::call_site().start(); diff --git a/zerocopy/vendor/proc-macro2/tests/test_size.rs b/zerocopy/vendor/proc-macro2/tests/test_size.rs index 46e58db468..8b6791518f 100644 --- a/zerocopy/vendor/proc-macro2/tests/test_size.rs +++ b/zerocopy/vendor/proc-macro2/tests/test_size.rs @@ -1,42 +1,81 @@ +#![allow(unused_attributes)] + extern crate proc_macro; use std::mem; -#[rustversion::attr(before(1.32), ignore)] +#[rustversion::attr(before(1.64), ignore = "requires Rust 1.64+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] #[test] -fn test_proc_macro_span_size() { +fn test_proc_macro_size() { assert_eq!(mem::size_of::(), 4); assert_eq!(mem::size_of::>(), 4); + assert_eq!(mem::size_of::(), 20); + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 4); } -#[cfg_attr(not(all(not(wrap_proc_macro), not(span_locations))), ignore)] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(wrap_proc_macro, ignore = "wrapper mode")] +#[cfg_attr(span_locations, ignore = "span locations are on")] #[test] -fn test_proc_macro2_fallback_span_size_without_locations() { +fn test_proc_macro2_fallback_size_without_locations() { assert_eq!(mem::size_of::(), 0); assert_eq!(mem::size_of::>(), 1); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 8); } -#[cfg_attr(not(all(not(wrap_proc_macro), span_locations)), ignore)] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(wrap_proc_macro, ignore = "wrapper mode")] +#[cfg_attr(not(span_locations), ignore = "span locations are off")] #[test] -fn test_proc_macro2_fallback_span_size_with_locations() { +fn test_proc_macro2_fallback_size_with_locations() { assert_eq!(mem::size_of::(), 8); assert_eq!(mem::size_of::>(), 12); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 8); } -#[rustversion::attr(before(1.32), ignore)] -#[rustversion::attr( - since(1.32), - cfg_attr(not(all(wrap_proc_macro, not(span_locations))), ignore) -)] +#[rustversion::attr(before(1.71), ignore = "requires Rust 1.71+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(not(wrap_proc_macro), ignore = "fallback mode")] +#[cfg_attr(span_locations, ignore = "span locations are on")] #[test] -fn test_proc_macro2_wrapper_span_size_without_locations() { +fn test_proc_macro2_wrapper_size_without_locations() { assert_eq!(mem::size_of::(), 4); assert_eq!(mem::size_of::>(), 8); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 32); } -#[cfg_attr(not(all(wrap_proc_macro, span_locations)), ignore)] +#[rustversion::attr(before(1.65), ignore = "requires Rust 1.65+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(not(wrap_proc_macro), ignore = "fallback mode")] +#[cfg_attr(not(span_locations), ignore = "span locations are off")] #[test] -fn test_proc_macro2_wrapper_span_size_with_locations() { +fn test_proc_macro2_wrapper_size_with_locations() { assert_eq!(mem::size_of::(), 12); assert_eq!(mem::size_of::>(), 12); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 20); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 32); } diff --git a/zerocopy/vendor/syn-3.0.3/.cargo-checksum.json b/zerocopy/vendor/syn-3.0.3/.cargo-checksum.json new file mode 100644 index 0000000000..0254795bf8 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo_vcs_info.json":"c005ec6217c91836ef610cdf176ebdf9adaa6a6efd97277cd59a4a3ef486f945","Cargo.lock":"036946b2e706008c61c5cedf0e64eff7fa625cdfb6c48ebe608af6fea284d5bf","Cargo.toml":"573f29cdf33ca93b684804e073bd81679fe4b71d40d1c8b8f607201b3a11a87c","Cargo.toml.orig":"da671d51e7459e3fee9acd4b335e50aa69f4389092448f470265fe4fea7c5253","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"a00f270c7f468863f28b9984547872efb57c7db1b9beb6e685852dc24de6846e","benches/file.rs":"6f2ae7748d1576cff48e4ef55d4e87e2f5bb7898a36aa99ea6dd6ed0f72a4e3c","benches/rust.rs":"4ad250087795831d7c79b130d47927b5c733052c9659de039c08835b74be72b1","src/attr.rs":"2108cf48c98ed0a7833ec73b841fccc254c733453a7e69127b0255541bbc9572","src/bigint.rs":"21cf6cf0c8e175421a6579321878e140d6cd2c975e5bdac4eadde25907d7e879","src/buffer.rs":"ddb6d50a9e79dc1db86d819d41dbf532e172997c8e0101d73c95052835756c50","src/classify.rs":"980e81540ddf0414bbfa6fc4f543127d39da84337732a6353473afbd547267f0","src/custom_keyword.rs":"322114e36ae43a2f8605506fb4568efdbc2986853e2fee74bd10a4ca0fb60c69","src/custom_punctuation.rs":"67134b7685ce89eddb7bf4ee3c9a48e5eb8ecbb1703cd49a01cbb115239fb814","src/data.rs":"78280858745d59b721098c7d7f8aa99dddd9e519908d75a1c4444c9c455875d6","src/derive.rs":"4927cfd64d2c61bb9ee8462b83d5bbce77e3f85c3a03a5565ecf6f08d55367c3","src/discouraged.rs":"7b5ca0fb3120970d028ddd4efc69363fea278a0b6ed5160d82295c326b3b08ac","src/drops.rs":"c48e679507424c08716b48256a06d59fe55e877de336c40f0df56cfd80e23826","src/error.rs":"5ed698f9dd63f16775e48455919a626a246d2ac38d682c1ba37a0ff561ed0a7b","src/export.rs":"d9039ba7f1455089139cf8a6871159f0ec57949cc730b42fe3c318a8397d3368","src/expr.rs":"5a3dc478d7b76a13f2bd7632ccb8f2f9733c1081fce527a17dabd7a7e99161a2","src/ext.rs":"8bc0d0ffab88c73d2305c9f588e6b5285501de8869308162f91019c83bc5bdf1","src/file.rs":"4513d0f1f4a4d78ba94c0895e97aadc0c2ebcf6f5da36abf762e77e813bc9aea","src/fixup.rs":"7647cde30efdce96b1488ae805788c168d4499b464b7d421abc17ea8ffde66f2","src/gen/clone.rs":"342704f87c06f11b4b6b60689df5f55e7a9a67d656b9286cc23a364f485c135f","src/gen/debug.rs":"29782ea05d86b95e98bb664d6688c413c871dc78f5dc9ee81f584aaa63e85558","src/gen/eq.rs":"15f2b5070ea8fccf07dbff6bf2fdc027c6d913599b5c1a8e8a5bc9e39e601133","src/gen/fold.rs":"4804ee04ce6ed8437a9e5d2a54a3ca91f711098034f95ac7102ca0928783dc3e","src/gen/hash.rs":"ac638e8b56722dd890bd06297a2902b9015cf85e2c50432258b050e43cc1d4cf","src/gen/token.css":"f79afb8272b8c9b6fe63716c6be5c53d8e7c5ca5473bf3ec891b6e1be9887716","src/gen/visit.rs":"32414282294ae0d0fbbe863c51cf26c2fc3fb6843dbf715d96f5ad69f3048c2c","src/gen/visit_mut.rs":"1d76d69baddc4f1354399cab7309a5a2738b3850ad249f793b596fc854c4e8d1","src/generics.rs":"a563693b6c9ec11d61b2ce7f869763a3c967879dd9306743f01203cd9555cda1","src/group.rs":"61e067094aa930b6550dc3717a5aaeef7dabfdcf1a177f83fb636598fa7e4e72","src/ident.rs":"a17e32b0d997649c4c986d1c9eef24be5331cd9ab478604932297b55f785487a","src/item.rs":"a2da8d9b7c92688d03102a0840104e59f2cfdb93369ed104a1efefe309b4519f","src/lib.rs":"f8615291f116385ff3a55c16fe089a5cbcc87d7cdc6b3769e0786f8f34379ff4","src/lifetime.rs":"2f3a240a4a0d9536dd1e3255d5ae0d64efcc46f295cf565a09e8ac33cd3d3487","src/lit.rs":"b4afa58a52cba945f9c55c4ccf6c27b32637f89fa114b4d6ed254664e6cd1d22","src/lookahead.rs":"ea51bbf9a23d68238f8324a51675f5815fb3e5fc08c6bab93bc2648d3342c38f","src/mac.rs":"fdce8291f71adef3f69975f229156dca2309ca232ed943061afaf96220908ab8","src/macros.rs":"dfc278625948d727ef06e058a94483bbcc551b62b8eb736dc7cd9e0a4777866f","src/meta.rs":"d8703f8cbc5fd6465c367214eac38efca0f8388bdef8ac5e6f863835fbd3b30f","src/op.rs":"a61757370f802e44efa3c4a1057ae2cd26e64e273f7d76c06d5ffb49602319e2","src/parse.rs":"e692d6e895ac79a14680b89a7c29611995126953238176bdb50d2a3c2fb2d9e3","src/parse_macro_input.rs":"e4e22b63d0496d06a4ca17742a22467ed93f08a739081324773828bad63175ee","src/parse_quote.rs":"c0ae210cfe6d6b8f6758cff1f44283acd9df5ed67d88911875079fb28d4d1b67","src/pat.rs":"3258bdaca2be2c692cd9bb09a89f811f53b176939a57ce46c0d89284628fc830","src/path.rs":"088ff7dc2cd278efc32017722887d6849866e54ab7d7ae47710edf785c0cc478","src/precedence.rs":"301f5cc51e1bbb35aeb64f6ed1b21d6f61d83f6c048aec9896976ee0011b948e","src/print.rs":"22910bf0521ab868ebd7c62601c55912d12cfb400c65723e08e5cfa3a2d111c0","src/punctuated.rs":"6b70fd15cc662260c2c0f20cd35a777351b2c5199b299cf5c8d8972723bd0f04","src/restriction.rs":"9506f1dd5710a380a8298dc8b345a0849a011e447e1aca08c4ca29543a65273b","src/scan_expr.rs":"1afda43a7f4e9d426859a90d8a62a58c6654f3be41bb274d4884a56ac08f8eee","src/sealed.rs":"6ece3b3dcb30f6bb98b93d83759ca7712ee8592bef9c0511141039c38765db0e","src/span.rs":"0a48e375e5c9768f6f64174a91ba6a255f4b021e2fb3548d8494e617f142601b","src/spanned.rs":"b53ce23f10935cf202da0f5a430e9feca9f4858bbd6efbe896acf17d3cfce540","src/stmt.rs":"60718ffd8e4b72bae9ea620670276af3bd407f248f2c5e3bd945a2ea8c541661","src/thread.rs":"b91e33c563c2ea584fcd7c5454998303173f4227bdb19504776e61d09b60675c","src/token.rs":"fddf7540f6c87e088ca2e4cd59a4769bc99989907a71e0d7cb42ee6ec067a6ac","src/tt.rs":"d5b9df076504b1506e0b05dafb9006fd0772fdb8d4b8b8dcc315dbca3277331a","src/ty.rs":"63bbf2272575d40ba632b54ca51857f43410bc22c20ff3ecedee3d3f52dd84e5","src/verbatim.rs":"503055ba92ebb97da71a8a7cae1e6606969aadfb965b0d6c7e56693f9ef66b0a","src/whitespace.rs":"9cdcbfe9045b259046329a795bc1105ab5a871471a6d3f7318d275ee53f7a825","tests/common/eq.rs":"112f43d0b996f40267e3352c672acd0fe71ecbb68e6144915c2ce9087494b651","tests/common/mod.rs":"b752aa8f1faf8c6abf1286a12fb50b6c257ec1889d81bcdb3dc3257134695a89","tests/common/parse.rs":"b1685e9e0f0569f48d66ddd92d787a12933a1d2f95e7c9ae974a3648763f989b","tests/common/visit.rs":"a260ecd2ce7853cd3644e19aba08e8d358a656fd3fb0f1287cea40c59c9e62c9","tests/debug/gen.rs":"75b59398bb58e8d05c5ee5598b88163564b480c866af3dddb9bcc69e8df8459a","tests/debug/mod.rs":"1259df940bbcaa968a837e402d6853f2efa38d2260e306d42f17f9e8ef74fae5","tests/macros/mod.rs":"d2294a79e341c623ae671dd363e99965d78dda7f340b0cc038267207adfacae2","tests/regression.rs":"e9565ea0efecb4136f099164ffcfa26e1996b0a27fb9c6659e90ad9bdd42e7b6","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/regression/issue1235.rs":"a2266b10c3f7c7af5734817ab0a3e8b309b51e7d177b63f26e67e6b744d280b0","tests/repo/mod.rs":"b5e0c83cee8fd9016b5ea65f727b831468a56b646b46c95d19702e1bd27b9a4d","tests/repo/progress.rs":"11219e4ae5e0175d5ddc743907a57b8c4e750e709687c3df53728d6af994a86f","tests/snapshot/mod.rs":"4a101272c5abe6ca9f3501e0cacacee9a0ccf7ca773348a239e5b046d0316a7e","tests/test_attribute.rs":"8a4429b7cfe2360bb73beae54a62ae3255ebbd5181467a8608d6f858c2711728","tests/test_derive_input.rs":"ac6fff053bded4ca30f88343cbf984a319119b58805f56058bd6ad61a1f60972","tests/test_expr.rs":"8fde868c1cbfbf48604735eb872cc3f85a59e2c306a579c45a8112e57d9ebf51","tests/test_generics.rs":"2bd20cbaab8ff268e6e283ae9564f064f352deab7d3d4beafb7f41baa2b862cf","tests/test_grouping.rs":"fe3de6e8824f0722ab6450c6dfc374f6e0f8fe75c87c4dd56b2cb00a2197ed58","tests/test_ident.rs":"d5850e817720e774cd397a46dbc5298c57933823c18e20805e84503fc9387e8f","tests/test_item.rs":"49f7130127da9077dc39cb1c3b9a70b55f62c39555b48bf9c7f5bb07fc506531","tests/test_lit.rs":"4130efa425d14ed3ad9a1c2a00ef4b29782c9d1cf9e29ff9dddd3b23b2e3ddee","tests/test_meta.rs":"5b0fdee0decbd07476c9673403a662de385901b4bf60600c26ac879893f5bf9c","tests/test_parse_buffer.rs":"1c8cbbf457603bd0a83348079591f843f7ef0533a6275a0c76533e2d07dd321a","tests/test_parse_quote.rs":"2fc6fcd5f6ab063fb26dd64e087a8a0799f0650b7249c1c4f3b08b870b89ed22","tests/test_parse_stream.rs":"b6b533432173123d6d01d8d2cb33714bc50b30b16ffbb6116f93937221ad4594","tests/test_pat.rs":"91458c108f6d8a1660e5633cde6441b0e583f7fa8f36375dcf0a051301eb3d34","tests/test_path.rs":"4957de8bd9e0c158cfa91dc12ec3b16132d243f0d1f3184d827ac6da5ab1739f","tests/test_precedence.rs":"957a896afe99f33fb6f680b880a1eb9f4fe500722eb4ed619f9a995cc5106e7c","tests/test_punctuated.rs":"efed2c281b6965d71b065c7606631ba1989af6e7b5f5d1ca1033f8b968dc076c","tests/test_receiver.rs":"c94e39e57b21844b9c89f9da672da33e83046a409f6d8d00422652f92e703d43","tests/test_round_trip.rs":"aecd7b37cf937f005ee0858f38482782341d7fa037ec8f15b3e8b26bfd6f6104","tests/test_shebang.rs":"785345c798689328060d59a715ed1a54f7a72e9d0305f2f2a1ed84102bcf100b","tests/test_size.rs":"2928bfc73c6a1dc1a7a4fc31bbd1ce8583f97aea4b3adf747dad325bfa748ef0","tests/test_stmt.rs":"17a3f6f7bbd25b428e8761de34b628c99afceacd339350909bbad13614a96cec","tests/test_token_trees.rs":"c30b921a96739c9334ec2bdd06552729891e0251b9d8fbdf0b8f5cc897babee5","tests/test_ty.rs":"5b70d0bc3a02ef6b06f39e4ba5a29df56f1e2237b365f9a0ea1f146b1e2386d2","tests/test_unparenthesize.rs":"e5c047819afd5f70fde1bdd095467b1291d0854641f21e8183e50919986d8ce7","tests/test_visibility.rs":"811a5df8923426bc24f1bc5e6e346dbbde5ce2ae3143867d81332200ad082494","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"} \ No newline at end of file diff --git a/zerocopy/vendor/syn-3.0.3/.cargo_vcs_info.json b/zerocopy/vendor/syn-3.0.3/.cargo_vcs_info.json new file mode 100644 index 0000000000..4724f4218b --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "23dbaab4b0c43f56cd803894054cf366661e53b0" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/zerocopy/vendor/syn-3.0.3/Cargo.lock b/zerocopy/vendor/syn-3.0.3/Cargo.lock new file mode 100644 index 0000000000..9cd257270d --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/Cargo.lock @@ -0,0 +1,1924 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "automod" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a273e731a7fb8c2268fd2932c9e9a3469f4fd171d85d070d2687190229653bd3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "aws-lc-rs" +version = "1.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cc" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core", +] + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "console" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "displaydoc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-io" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" + +[[package]] +name = "futures-sink" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "rand_core", + "wasm-bindgen", +] + +[[package]] +name = "h2" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "insta" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "ref-cast" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.2", +] + +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" +dependencies = [ + "aws-lc-rs", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.2", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +dependencies = [ + "anyhow", + "automod", + "flate2", + "insta", + "proc-macro2", + "quote", + "rayon", + "ref-cast", + "reqwest", + "rustversion", + "syn-test-suite", + "tar", + "termcolor", + "unicode-ident", + "walkdir", +] + +[[package]] +name = "syn-test-suite" +version = "0.0.0+test" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d661992f60e67c8bdd9a7d6360d30d1301f5783abf7d59933844f656762eb5" + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.2", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] diff --git a/zerocopy/vendor/syn-3.0.3/Cargo.toml b/zerocopy/vendor/syn-3.0.3/Cargo.toml new file mode 100644 index 0000000000..b47ab8a7a7 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/Cargo.toml @@ -0,0 +1,268 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# 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. +# +# 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 = "2021" +rust-version = "1.71" +name = "syn" +version = "3.0.3" +authors = ["David Tolnay "] +build = false +include = [ + "/benches/**", + "/Cargo.toml", + "/LICENSE-APACHE", + "/LICENSE-MIT", + "/README.md", + "/src/**", + "/tests/**", +] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Parser for Rust source code" +documentation = "https://docs.rs/syn" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = [ + "development-tools::procedural-macro-helpers", + "parser-implementations", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/syn" + +[package.metadata.docs.rs] +all-features = true +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extend-css=src/gen/token.css", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", + "--extern-html-root-url=proc_macro=https://doc.rust-lang.org", +] + +[package.metadata.playground] +features = [ + "full", + "visit", + "visit-mut", + "fold", + "extra-traits", +] + +[features] +clone-impls = [] +default = [ + "derive", + "parsing", + "printing", + "clone-impls", + "proc-macro", +] +derive = [] +extra-traits = [] +fold = [] +full = [] +parsing = [] +printing = ["quote"] +proc-macro = [ + "proc-macro2/proc-macro", + "quote/proc-macro", +] +test = ["syn-test-suite/all-features"] +visit = [] +visit-mut = [] + +[lib] +name = "syn" +path = "src/lib.rs" + +[[test]] +name = "regression" +path = "tests/regression.rs" + +[[test]] +name = "test_attribute" +path = "tests/test_attribute.rs" + +[[test]] +name = "test_derive_input" +path = "tests/test_derive_input.rs" + +[[test]] +name = "test_expr" +path = "tests/test_expr.rs" + +[[test]] +name = "test_generics" +path = "tests/test_generics.rs" + +[[test]] +name = "test_grouping" +path = "tests/test_grouping.rs" + +[[test]] +name = "test_ident" +path = "tests/test_ident.rs" + +[[test]] +name = "test_item" +path = "tests/test_item.rs" + +[[test]] +name = "test_lit" +path = "tests/test_lit.rs" + +[[test]] +name = "test_meta" +path = "tests/test_meta.rs" + +[[test]] +name = "test_parse_buffer" +path = "tests/test_parse_buffer.rs" + +[[test]] +name = "test_parse_quote" +path = "tests/test_parse_quote.rs" + +[[test]] +name = "test_parse_stream" +path = "tests/test_parse_stream.rs" + +[[test]] +name = "test_pat" +path = "tests/test_pat.rs" + +[[test]] +name = "test_path" +path = "tests/test_path.rs" + +[[test]] +name = "test_precedence" +path = "tests/test_precedence.rs" + +[[test]] +name = "test_punctuated" +path = "tests/test_punctuated.rs" + +[[test]] +name = "test_receiver" +path = "tests/test_receiver.rs" + +[[test]] +name = "test_round_trip" +path = "tests/test_round_trip.rs" + +[[test]] +name = "test_shebang" +path = "tests/test_shebang.rs" + +[[test]] +name = "test_size" +path = "tests/test_size.rs" + +[[test]] +name = "test_stmt" +path = "tests/test_stmt.rs" + +[[test]] +name = "test_token_trees" +path = "tests/test_token_trees.rs" + +[[test]] +name = "test_ty" +path = "tests/test_ty.rs" + +[[test]] +name = "test_unparenthesize" +path = "tests/test_unparenthesize.rs" + +[[test]] +name = "test_visibility" +path = "tests/test_visibility.rs" + +[[test]] +name = "zzz_stable" +path = "tests/zzz_stable.rs" + +[[bench]] +name = "file" +path = "benches/file.rs" +required-features = [ + "full", + "parsing", +] + +[[bench]] +name = "rust" +path = "benches/rust.rs" +harness = false +required-features = [ + "full", + "parsing", +] + +[dependencies.proc-macro2] +version = "1.0.91" +default-features = false + +[dependencies.quote] +version = "1.0.35" +optional = true +default-features = false + +[dependencies.unicode-ident] +version = "1" + +[dev-dependencies.anyhow] +version = "1" + +[dev-dependencies.automod] +version = "1" + +[dev-dependencies.insta] +version = "1" + +[dev-dependencies.ref-cast] +version = "1" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.syn-test-suite] +version = "0" + +[dev-dependencies.termcolor] +version = "1" + +[target."cfg(not(miri))".dev-dependencies.flate2] +version = "1" + +[target."cfg(not(miri))".dev-dependencies.rayon] +version = "1" + +[target."cfg(not(miri))".dev-dependencies.reqwest] +version = "0.13" +features = ["blocking"] + +[target."cfg(not(miri))".dev-dependencies.tar] +version = "0.4.16" + +[target."cfg(not(miri))".dev-dependencies.walkdir] +version = "2.3.2" diff --git a/zerocopy/vendor/syn-3.0.3/Cargo.toml.orig b/zerocopy/vendor/syn-3.0.3/Cargo.toml.orig new file mode 100644 index 0000000000..81d686518d --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/Cargo.toml.orig @@ -0,0 +1,95 @@ +[package] +name = "syn" +version = "3.0.3" +authors = ["David Tolnay "] +categories = ["development-tools::procedural-macro-helpers", "parser-implementations"] +description = "Parser for Rust source code" +documentation = "https://docs.rs/syn" +edition = "2021" +include = [ + "/benches/**", + "/Cargo.toml", + "/LICENSE-APACHE", + "/LICENSE-MIT", + "/README.md", + "/src/**", + "/tests/**", +] +keywords = ["macros", "syn"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/syn" +rust-version = "1.71" + +[features] +default = ["derive", "parsing", "printing", "clone-impls", "proc-macro"] +derive = [] +full = [] +parsing = [] +printing = ["dep:quote"] +visit = [] +visit-mut = [] +fold = [] +clone-impls = [] +extra-traits = [] +proc-macro = ["proc-macro2/proc-macro", "quote?/proc-macro"] +test = ["syn-test-suite/all-features"] + +[dependencies] +proc-macro2 = { version = "1.0.91", default-features = false } +quote = { version = "1.0.35", optional = true, default-features = false } +unicode-ident = "1" + +[dev-dependencies] +anyhow = "1" +automod = "1" +insta = "1" +ref-cast = "1" +rustversion = "1" +syn-test-suite = { version = "0", path = "tests/features" } +termcolor = "1" + +[target.'cfg(not(miri))'.dev-dependencies] +flate2 = "1" +rayon = "1" +reqwest = { version = "0.13", features = ["blocking"] } +tar = "0.4.16" +walkdir = "2.3.2" + +[[bench]] +name = "rust" +harness = false +required-features = ["full", "parsing"] + +[[bench]] +name = "file" +required-features = ["full", "parsing"] + +[package.metadata.docs.rs] +all-features = true +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--generate-macro-expansion", + "--extend-css=src/gen/token.css", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", + "--extern-html-root-url=proc_macro=https://doc.rust-lang.org", +] + +[package.metadata.playground] +features = ["full", "visit", "visit-mut", "fold", "extra-traits"] + +[workspace] +members = [ + "dev", + "examples/dump-syntax", + "examples/heapsize/example", + "examples/heapsize/heapsize", + "examples/heapsize/heapsize_derive", + "examples/lazy-static/example", + "examples/lazy-static/lazy-static", + "examples/trace-var/example", + "examples/trace-var/trace-var", + "tests/features", +] diff --git a/zerocopy/vendor/syn-3.0.3/LICENSE-APACHE b/zerocopy/vendor/syn-3.0.3/LICENSE-APACHE new file mode 100644 index 0000000000..1b5ec8b78e --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/zerocopy/vendor/syn-3.0.3/LICENSE-MIT b/zerocopy/vendor/syn-3.0.3/LICENSE-MIT new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/zerocopy/vendor/syn-3.0.3/README.md b/zerocopy/vendor/syn-3.0.3/README.md new file mode 100644 index 0000000000..9618ce8f6f --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/README.md @@ -0,0 +1,297 @@ +Parser for Rust source code +=========================== + +[github](https://github.com/dtolnay/syn) +[crates.io](https://crates.io/crates/syn) +[docs.rs](https://docs.rs/syn) +[build status](https://github.com/dtolnay/syn/actions?query=branch%3Amaster) + +Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree +of Rust source code. + +Currently this library is geared toward use in Rust procedural macros, but +contains some APIs that may be useful more generally. + +- **Data structures** — Syn provides a syntax tree that can represent most + stable Rust source code and some unstable syntax. The syntax tree is rooted at + [`syn::File`] which represents a full source file, but there are other entry + points that may be useful to procedural macros including [`syn::Item`], + [`syn::Expr`] and [`syn::Type`]. + +- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`] + which is any of the three legal input items to a derive macro. An example + below shows using this type in a library that can derive implementations of a + user-defined trait. + +- **Parsing** — Parsing in Syn is built around [parser functions] with the + signature `fn(ParseStream) -> Result`. Every syntax tree node defined by + Syn is individually parsable and may be used as a building block for custom + syntaxes, or you may dream up your own brand new syntax without involving any + of our syntax tree types. + +- **Location information** — Every token parsed by Syn is associated with a + `Span` that tracks line and column information back to the source of that + token. These spans allow a procedural macro to display detailed error messages + pointing to all the right places in the user's code. There is an example of + this below. + +- **Feature flags** — Functionality is aggressively feature gated so your + procedural macros enable only what they need, and do not pay in compile time + for all the rest. + +[`syn::File`]: https://docs.rs/syn/3/syn/struct.File.html +[`syn::Item`]: https://docs.rs/syn/3/syn/enum.Item.html +[`syn::Expr`]: https://docs.rs/syn/3/syn/enum.Expr.html +[`syn::Type`]: https://docs.rs/syn/3/syn/enum.Type.html +[`syn::DeriveInput`]: https://docs.rs/syn/3/syn/struct.DeriveInput.html +[parser functions]: https://docs.rs/syn/3/syn/parse/index.html + +[*Release notes*](https://github.com/dtolnay/syn/releases) + +
+ +## Resources + +The best way to learn about procedural macros is by writing some. Consider +working through [this procedural macro workshop][workshop] to get familiar with +the different types of procedural macros. The workshop contains relevant links +into the Syn documentation as you work through each project. + +[workshop]: https://github.com/dtolnay/proc-macro-workshop + +
+ +## Example of a derive macro + +The canonical derive macro using Syn looks like this. We write an ordinary Rust +function tagged with a `proc_macro_derive` attribute and the name of the trait +we are deriving. Any time that derive appears in the user's code, the Rust +compiler passes their data structure as tokens into our macro. We get to execute +arbitrary Rust code to figure out what to do with those tokens, then hand some +tokens back to the compiler to compile into the user's crate. + +[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html + +```toml +# Cargo.toml +[package] +... + +[lib] +proc-macro = true + +[dependencies] +syn = "3" +quote = "1" +``` + +```rust +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +#[proc_macro_derive(MyMacro)] +pub fn my_macro(input: TokenStream) -> TokenStream { + // Parse the input tokens into a syntax tree + let input = parse_macro_input!(input as DeriveInput); + + // Build the output, possibly using quasi-quotation + let expanded = quote! { + // ... + }; + + // Hand the output tokens back to the compiler + TokenStream::from(expanded) +} +``` + +The [`heapsize`] example directory shows a complete working implementation of a +derive macro. The example derives a `HeapSize` trait which computes an estimate +of the amount of heap memory owned by a value. + +[`heapsize`]: examples/heapsize + +```rust +pub trait HeapSize { + /// Total number of bytes of heap memory owned by `self`. + fn heap_size_of_children(&self) -> usize; +} +``` + +The derive macro allows users to write `#[derive(HeapSize)]` on data structures +in their program. + +```rust +#[derive(HeapSize)] +struct Demo<'a, T: ?Sized> { + a: Box, + b: u8, + c: &'a str, + d: String, +} +``` + +
+ +## Spans and error reporting + +The token-based procedural macro API provides great control over where the +compiler's error messages are displayed in user code. Consider the error the +user sees if one of their field types does not implement `HeapSize`. + +```rust +#[derive(HeapSize)] +struct Broken { + ok: String, + bad: std::thread::Thread, +} +``` + +By tracking span information all the way through the expansion of a procedural +macro as shown in the `heapsize` example, token-based macros in Syn are able to +trigger errors that directly pinpoint the source of the problem. + +```console +error[E0277]: the trait bound `Thread: HeapSize` is not satisfied + --> src/main.rs:9:5 + | +3 | #[derive(HeapSize)] + | -------- required by a bound introduced by this call +... +9 | bad: std::thread::Thread, + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread` + | + = help: the following other types implement trait `HeapSize`: + &'a T + Box + Demo<'a, T> + String + [T] + u8 +``` + +
+ +## Parsing a custom syntax + +The [`lazy-static`] example directory shows the implementation of a +`functionlike!(...)` procedural macro in which the input tokens are parsed using +Syn's parsing API. + +[`lazy-static`]: examples/lazy-static + +The example reimplements the popular `lazy_static` crate from crates.io as a +procedural macro. + +```rust +lazy_static! { + static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); +} +``` + +The implementation shows how to trigger custom warnings and error messages on +the macro input. + +```console +warning: come on, pick a more creative name + --> src/main.rs:10:16 + | +10 | static ref FOO: String = "lazy_static".to_owned(); + | ^^^ +``` + +
+ +## Testing + +When testing macros, we often care not just that the macro can be used +successfully but also that when the macro is provided with invalid input it +produces maximally helpful error messages. Consider using the [`trybuild`] crate +to write tests for errors that are emitted by your macro or errors detected by +the Rust compiler in the expanded code following misuse of the macro. Such tests +help avoid regressions from later refactors that mistakenly make an error no +longer trigger or be less helpful than it used to be. + +[`trybuild`]: https://github.com/dtolnay/trybuild + +
+ +## Debugging + +When developing a procedural macro it can be helpful to look at what the +generated code looks like. Use `cargo rustc -- -Zunstable-options +-Zunpretty=expanded` or the [`cargo expand`] subcommand. + +[`cargo expand`]: https://github.com/dtolnay/cargo-expand + +To show the expanded code for some crate that uses your procedural macro, run +`cargo expand` from that crate. To show the expanded code for one of your own +test cases, run `cargo expand --test the_test_case` where the last argument is +the name of the test file without the `.rs` extension. + +This write-up by Brandon W Maister discusses debugging in more detail: +[Debugging Rust's new Custom Derive system][debugging]. + +[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/ + +
+ +## Optional features + +Syn puts a lot of functionality behind optional features in order to optimize +compile time for the most common use cases. The following features are +available. + +- **`derive`** *(enabled by default)* — Data structures for representing the + possible input to a derive macro, including structs and enums and types. +- **`full`** — Data structures for representing the syntax tree of all valid + Rust source code, including items and expressions. +- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a + syntax tree node of a chosen type. +- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as + tokens of Rust source code. +- **`visit`** — Trait for traversing a syntax tree. +- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree. +- **`fold`** — Trait for transforming an owned syntax tree. +- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree + types. +- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree + types. +- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic + library libproc_macro from rustc toolchain. + +
+ +## Proc macro shim + +Syn operates on the token representation provided by the [proc-macro2] crate +from crates.io rather than using the compiler's built in proc-macro crate +directly. This enables code using Syn to execute outside of the context of a +procedural macro, such as in unit tests or build.rs, and we avoid needing +incompatible ecosystems for proc macros vs non-macro use cases. + +In general all of your code should be written against proc-macro2 rather than +proc-macro. The one exception is in the signatures of procedural macro entry +points, which are required by the language to use `proc_macro::TokenStream`. + +The proc-macro2 crate will automatically detect and use the compiler's data +structures when a procedural macro is active. + +[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/ + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/zerocopy/vendor/syn-3.0.3/benches/file.rs b/zerocopy/vendor/syn-3.0.3/benches/file.rs new file mode 100644 index 0000000000..6167488c9c --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/benches/file.rs @@ -0,0 +1,59 @@ +// $ cargo bench --features full,test --bench file + +#![feature(rustc_private, test)] +#![recursion_limit = "1024"] +#![allow( + clippy::elidable_lifetime_names, + clippy::items_after_statements, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::missing_panics_doc, + clippy::must_use_candidate, + clippy::needless_lifetimes, + clippy::uninlined_format_args +)] + +extern crate test; + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use proc_macro2::{Span, TokenStream}; +use std::fs; +use std::str::FromStr; +use syn::parse::{ParseStream, Parser}; +use test::Bencher; + +const FILE: &str = "tests/rust/library/core/src/str/mod.rs"; + +fn get_tokens() -> TokenStream { + repo::clone_rust(); + let content = fs::read_to_string(FILE).unwrap(); + TokenStream::from_str(&content).unwrap() +} + +#[bench] +fn baseline(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| drop(tokens.clone())); +} + +#[bench] +fn create_token_buffer(b: &mut Bencher) { + let tokens = get_tokens(); + fn immediate_fail(_input: ParseStream) -> syn::Result<()> { + Err(syn::Error::new(Span::call_site(), "")) + } + b.iter(|| immediate_fail.parse2(tokens.clone())); +} + +#[bench] +fn parse_file(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| syn::parse2::(tokens.clone())); +} diff --git a/zerocopy/vendor/syn-3.0.3/benches/rust.rs b/zerocopy/vendor/syn-3.0.3/benches/rust.rs new file mode 100644 index 0000000000..c0e82c65c0 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/benches/rust.rs @@ -0,0 +1,189 @@ +// $ cargo bench --features full,test --bench rust +// +// Syn only, useful for profiling: +// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust + +#![cfg_attr(not(syn_only), feature(rustc_private))] +#![recursion_limit = "1024"] +#![allow( + clippy::arc_with_non_send_sync, + clippy::cast_lossless, + clippy::elidable_lifetime_names, + clippy::let_underscore_untyped, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::needless_lifetimes, + clippy::uninlined_format_args, + clippy::unnecessary_wraps +)] + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use std::fs; +use std::path::Path; +use std::time::{Duration, Instant}; + +#[cfg(not(syn_only))] +mod tokenstream_parse { + use proc_macro2::TokenStream; + use std::path::Path; + use std::str::FromStr; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + TokenStream::from_str(content).map(drop).map_err(drop) + } +} + +mod syn_parse { + use std::path::Path; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + syn::parse_file(content).map(drop).map_err(drop) + } +} + +#[cfg(not(syn_only))] +mod librustc_parse { + extern crate rustc_data_structures; + extern crate rustc_driver; + extern crate rustc_error_messages; + extern crate rustc_errors; + extern crate rustc_parse; + extern crate rustc_session; + extern crate rustc_span; + + use crate::repo; + use rustc_errors::emitter::Emitter; + use rustc_errors::{DiagCtxt, DiagInner}; + use rustc_parse::lexer::StripTokens; + use rustc_session::parse::ParseSess; + use rustc_span::source_map::{FilePathMapping, SourceMap}; + use rustc_span::FileName; + use std::path::Path; + use std::sync::Arc; + + pub fn bench(path: &Path, content: &str) -> Result<(), ()> { + struct SilentEmitter; + + impl Emitter for SilentEmitter { + fn emit_diagnostic(&mut self, _diag: DiagInner) {} + fn source_map(&self) -> Option<&SourceMap> { + None + } + } + + let edition = repo::edition(path).parse().unwrap(); + rustc_span::create_session_if_not_set_then(edition, |_| { + let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); + let emitter = Box::new(SilentEmitter); + let handler = DiagCtxt::new(emitter); + let sess = ParseSess::with_dcx(handler, source_map); + let name = FileName::Custom("bench".to_owned()); + let mut parser = rustc_parse::new_parser_from_source_str( + &sess, + name, + content.to_owned(), + StripTokens::ShebangAndFrontmatter, + ) + .unwrap(); + if let Err(diagnostic) = parser.parse_crate_mod() { + diagnostic.cancel(); + return Err(()); + } + Ok(()) + }) + } +} + +#[cfg(not(syn_only))] +mod read_from_disk { + use std::path::Path; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + let _ = content; + Ok(()) + } +} + +fn exec(mut codepath: impl FnMut(&Path, &str) -> Result<(), ()>) -> Duration { + let begin = Instant::now(); + let mut success = 0; + let mut total = 0; + + ["tests/rust/compiler", "tests/rust/library"] + .iter() + .flat_map(|dir| { + walkdir::WalkDir::new(dir) + .into_iter() + .filter_entry(repo::base_dir_filter) + }) + .for_each(|entry| { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + return; + } + let content = fs::read_to_string(path).unwrap(); + let ok = codepath(path, &content).is_ok(); + success += ok as usize; + total += 1; + if !ok { + eprintln!("FAIL {}", path.display()); + } + }); + + assert_eq!(success, total); + begin.elapsed() +} + +fn main() { + repo::clone_rust(); + + macro_rules! testcases { + ($($(#[$cfg:meta])* $name:ident,)*) => { + [ + $( + $(#[$cfg])* + (stringify!($name), $name::bench as fn(&Path, &str) -> Result<(), ()>), + )* + ] + }; + } + + #[cfg(not(syn_only))] + { + let mut lines = 0; + let mut files = 0; + exec(|_path, content| { + lines += content.lines().count(); + files += 1; + Ok(()) + }); + eprintln!("\n{} lines in {} files", lines, files); + } + + for (name, f) in testcases!( + #[cfg(not(syn_only))] + read_from_disk, + #[cfg(not(syn_only))] + tokenstream_parse, + syn_parse, + #[cfg(not(syn_only))] + librustc_parse, + ) { + eprint!("{:20}", format!("{}:", name)); + let elapsed = exec(f); + eprintln!( + "elapsed={}.{:03}s", + elapsed.as_secs(), + elapsed.subsec_millis(), + ); + } + eprintln!(); +} diff --git a/zerocopy/vendor/syn-3.0.3/src/attr.rs b/zerocopy/vendor/syn-3.0.3/src/attr.rs new file mode 100644 index 0000000000..5e2d7a71f2 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/attr.rs @@ -0,0 +1,841 @@ +#[cfg(feature = "parsing")] +use crate::error::Error; +#[cfg(feature = "parsing")] +use crate::error::Result; +use crate::expr::Expr; +use crate::mac::MacroDelimiter; +#[cfg(feature = "parsing")] +use crate::meta::{self, ParseNestedMeta}; +#[cfg(feature = "parsing")] +use crate::parse::{Parse, ParseStream, Parser}; +use crate::path::Path; +use crate::token; +#[cfg(feature = "parsing")] +use alloc::format; +#[cfg(feature = "parsing")] +use alloc::vec::Vec; +#[cfg(feature = "printing")] +use core::iter; +#[cfg(feature = "printing")] +use core::slice; +use proc_macro2::TokenStream; + +ast_struct! { + /// An attribute, like `#[repr(transparent)]`. + /// + ///
+ /// + /// # Syntax + /// + /// Rust has six types of attributes. + /// + /// - Outer attributes like `#[repr(transparent)]`. These appear outside or + /// in front of the item they describe. + /// + /// - Inner attributes like `#![feature(proc_macro)]`. These appear inside + /// of the item they describe, usually a module. + /// + /// - Outer one-line doc comments like `/// Example`. + /// + /// - Inner one-line doc comments like `//! Please file an issue`. + /// + /// - Outer documentation blocks `/** Example */`. + /// + /// - Inner documentation blocks `/*! Please file an issue */`. + /// + /// The `style` field of type `AttrStyle` distinguishes whether an attribute + /// is outer or inner. + /// + /// Every attribute has a `path` that indicates the intended interpretation + /// of the rest of the attribute's contents. The path and the optional + /// additional contents are represented together in the `meta` field of the + /// attribute in three possible varieties: + /// + /// - Meta::Path — attributes whose information content conveys just a + /// path, for example the `#[test]` attribute. + /// + /// - Meta::List — attributes that carry arbitrary tokens after the + /// path, surrounded by a delimiter (parenthesis, bracket, or brace). For + /// example `#[derive(Copy)]` or `#[precondition(x < 5)]`. + /// + /// - Meta::NameValue — attributes with an `=` sign after the path, + /// followed by a Rust expression. For example `#[path = + /// "sys/windows.rs"]`. + /// + /// All doc comments are represented in the NameValue style with a path of + /// "doc", as this is how they are processed by the compiler and by + /// `macro_rules!` macros. + /// + /// ```text + /// #[derive(Copy, Clone)] + /// ~~~~~~Path + /// ^^^^^^^^^^^^^^^^^^^Meta::List + /// + /// #[path = "sys/windows.rs"] + /// ~~~~Path + /// ^^^^^^^^^^^^^^^^^^^^^^^Meta::NameValue + /// + /// #[test] + /// ^^^^Meta::Path + /// ``` + /// + ///
+ /// + /// # Parsing from tokens to Attribute + /// + /// This type does not implement the [`Parse`] trait and thus cannot be + /// parsed directly by [`ParseStream::parse`]. Instead use + /// [`ParseStream::call`] with one of the two parser functions + /// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on + /// which you intend to parse. + /// + /// [`Parse`]: crate::parse::Parse + /// [`ParseStream::parse`]: crate::parse::ParseBuffer::parse + /// [`ParseStream::call`]: crate::parse::ParseBuffer::call + /// + /// ``` + /// use syn::{Attribute, Ident, Result, Token}; + /// use syn::parse::{Parse, ParseStream}; + /// + /// // Parses a unit struct with attributes. + /// // + /// // #[path = "s.tmpl"] + /// // struct S; + /// struct UnitStruct { + /// attrs: Vec, + /// struct_token: Token![struct], + /// name: Ident, + /// semi_token: Token![;], + /// } + /// + /// impl Parse for UnitStruct { + /// fn parse(input: ParseStream) -> Result { + /// Ok(UnitStruct { + /// attrs: input.call(Attribute::parse_outer)?, + /// struct_token: input.parse()?, + /// name: input.parse()?, + /// semi_token: input.parse()?, + /// }) + /// } + /// } + /// ``` + /// + ///


+ /// + /// # Parsing from Attribute to structured arguments + /// + /// The grammar of attributes in Rust is very flexible, which makes the + /// syntax tree not that useful on its own. In particular, arguments of the + /// `Meta::List` variety of attribute are held in an arbitrary `tokens: + /// TokenStream`. Macros are expected to check the `path` of the attribute, + /// decide whether they recognize it, and then parse the remaining tokens + /// according to whatever grammar they wish to require for that kind of + /// attribute. Use [`parse_args()`] to parse those tokens into the expected + /// data structure. + /// + /// [`parse_args()`]: Attribute::parse_args + /// + ///


+ /// + /// # Doc comments + /// + /// The compiler transforms doc comments, such as `/// comment` and `/*! + /// comment */`, into attributes before macros are expanded. Each comment is + /// expanded into an attribute of the form `#[doc = r"comment"]`. + /// + /// As an example, the following `mod` items are expanded identically: + /// + /// ``` + /// # use syn::{ItemMod, parse_quote}; + /// let doc: ItemMod = parse_quote! { + /// /// Single line doc comments + /// /// We write so many! + /// /** + /// * Multi-line comments... + /// * May span many lines + /// */ + /// mod example { + /// //! Of course, they can be inner too + /// /*! And fit in a single line */ + /// } + /// }; + /// let attr: ItemMod = parse_quote! { + /// #[doc = r" Single line doc comments"] + /// #[doc = r" We write so many!"] + /// #[doc = r" + /// * Multi-line comments... + /// * May span many lines + /// "] + /// mod example { + /// #![doc = r" Of course, they can be inner too"] + /// #![doc = r" And fit in a single line "] + /// } + /// }; + /// assert_eq!(doc, attr); + /// ``` + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Attribute { + pub pound_token: Token![#], + pub style: AttrStyle, + pub bracket_token: token::Bracket, + pub meta: Meta, + } +} + +impl Attribute { + /// Returns the path that identifies the interpretation of this attribute. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + self.meta.path() + } + + /// Parse the arguments to the attribute as a syntax tree. + /// + /// This is similar to pulling out the `TokenStream` from `Meta::List` and + /// doing `syn::parse2::(meta_list.tokens)`, except that using + /// `parse_args` the error message has a more useful span when `tokens` is + /// empty. + /// + /// The surrounding delimiters are *not* included in the input to the + /// parser. + /// + /// ```text + /// #[my_attr(value < 5)] + /// ^^^^^^^^^ what gets parsed + /// ``` + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute, Expr}; + /// + /// let attr: Attribute = parse_quote! { + /// #[precondition(value < 5)] + /// }; + /// + /// if attr.path().is_ident("precondition") { + /// let precondition: Expr = attr.parse_args()?; + /// // ... + /// } + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// Parse the arguments to the attribute using the given parser. + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute}; + /// + /// let attr: Attribute = parse_quote! { + /// #[inception { #[brrrrrrraaaaawwwwrwrrrmrmrmmrmrmmmmm] }] + /// }; + /// + /// let bwom = attr.parse_args_with(Attribute::parse_outer)?; + /// + /// // Attribute does not have a Parse impl, so we couldn't directly do: + /// // let bwom: Attribute = attr.parse_args()?; + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + match &self.meta { + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new( + meta.eq_token.span, + format_args!( + "expected parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(&meta.path), + ), + )), + Meta::List(meta) => meta.parse_args_with(parser), + } + } + + /// Parse the arguments to the attribute, expecting it to follow the + /// conventional structure used by most of Rust's built-in attributes. + /// + /// The [*Meta Item Attribute Syntax*][syntax] section in the Rust reference + /// explains the convention in more detail. Not all attributes follow this + /// convention, so [`parse_args()`][Self::parse_args] is available if you + /// need to parse arbitrarily goofy attribute syntax. + /// + /// [syntax]: https://doc.rust-lang.org/reference/attributes.html#meta-item-attribute-syntax + /// + /// # Example + /// + /// We'll parse a struct, and then parse some of Rust's `#[repr]` attribute + /// syntax. + /// + /// ``` + /// use syn::{parenthesized, parse_quote, token, ItemStruct, LitInt}; + /// + /// let input: ItemStruct = parse_quote! { + /// #[repr(C, align(4))] + /// pub struct MyStruct(u16, u32); + /// }; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// attr.parse_nested_meta(|meta| { + /// // #[repr(C)] + /// if meta.path.is_ident("C") { + /// repr_c = true; + /// return Ok(()); + /// } + /// + /// // #[repr(transparent)] + /// if meta.path.is_ident("transparent") { + /// repr_transparent = true; + /// return Ok(()); + /// } + /// + /// // #[repr(align(N))] + /// if meta.path.is_ident("align") { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// return Ok(()); + /// } + /// + /// // #[repr(packed)] or #[repr(packed(N))], omitted N means 1 + /// if meta.path.is_ident("packed") { + /// if meta.input.peek(token::Paren) { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_packed = Some(n); + /// } else { + /// repr_packed = Some(1); + /// } + /// return Ok(()); + /// } + /// + /// Err(meta.error("unrecognized repr")) + /// })?; + /// } + /// } + /// # anyhow::Ok(()) + /// ``` + /// + /// # Alternatives + /// + /// In some cases, for attributes which have nested layers of structured + /// content, the following less flexible approach might be more convenient: + /// + /// ``` + /// # use syn::{parse_quote, ItemStruct}; + /// # + /// # let input: ItemStruct = parse_quote! { + /// # #[repr(C, align(4))] + /// # pub struct MyStruct(u16, u32); + /// # }; + /// # + /// use syn::punctuated::Punctuated; + /// use syn::{parenthesized, token, Error, LitInt, Meta, Token}; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + /// for meta in nested { + /// match meta { + /// // #[repr(C)] + /// Meta::Path(path) if path.is_ident("C") => { + /// repr_c = true; + /// } + /// + /// // #[repr(align(N))] + /// Meta::List(meta) if meta.path.is_ident("align") => { + /// let lit: LitInt = meta.parse_args()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// } + /// + /// /* ... */ + /// + /// _ => { + /// return Err(Error::new_spanned(meta, "unrecognized repr")); + /// } + /// } + /// } + /// } + /// } + /// # Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } + + /// Parses zero or more outer attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_outer(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + while input.peek(Token![#]) { + attrs.push(input.call(parsing::single_parse_outer)?); + } + Ok(attrs) + } + + /// Parses zero or more inner attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_inner(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + parsing::parse_inner(input, &mut attrs)?; + Ok(attrs) + } +} + +ast_enum! { + /// Distinguishes between attributes that decorate an item and attributes + /// that are contained within an item. + /// + /// # Outer attributes + /// + /// - `#[repr(transparent)]` + /// - `/// # Example` + /// - `/** Please file an issue */` + /// + /// # Inner attributes + /// + /// - `#![feature(proc_macro)]` + /// - `//! # Example` + /// - `/*! Please file an issue */` + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum AttrStyle { + Outer, + Inner(Token![!]), + } +} + +ast_enum! { + /// Content of a compile-time structured attribute. + /// + /// ## Path + /// + /// A meta path is like the `test` in `#[test]`. + /// + /// ## List + /// + /// A meta list is like the `derive(Copy)` in `#[derive(Copy)]`. + /// + /// ## NameValue + /// + /// A name-value meta is like the `path = "..."` in `#[path = + /// "sys/windows.rs"]`. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Meta { + Path(Path), + + /// A structured list within an attribute, like `derive(Copy, Clone)`. + List(MetaList), + + /// A name-value pair within an attribute, like `feature = "nightly"`. + NameValue(MetaNameValue), + } +} + +ast_struct! { + /// A structured list within an attribute, like `derive(Copy, Clone)`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaList { + pub path: Path, + pub delimiter: MacroDelimiter, + pub tokens: TokenStream, + } +} + +ast_struct! { + /// A name-value pair within an attribute, like `feature = "nightly"`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaNameValue { + pub path: Path, + pub eq_token: Token![=], + pub value: Expr, + } +} + +impl Meta { + /// Returns the path that begins this structured meta item. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + match self { + Meta::Path(path) => path, + Meta::List(meta) => &meta.path, + Meta::NameValue(meta) => &meta.path, + } + } + + /// Error if this is a `Meta::List` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_path_only(&self) -> Result<&Path> { + let error_span = match self { + Meta::Path(path) => return Ok(path), + Meta::List(meta) => meta.delimiter.span().open(), + Meta::NameValue(meta) => meta.eq_token.span, + }; + Err(Error::new(error_span, "unexpected token in attribute")) + } + + /// Error if this is a `Meta::Path` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_list(&self) -> Result<&MetaList> { + match self { + Meta::List(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: `{}(...)`", + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new(meta.eq_token.span, "expected `(`")), + } + } + + /// Error if this is a `Meta::Path` or `Meta::List`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_name_value(&self) -> Result<&MetaNameValue> { + match self { + Meta::NameValue(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected a value for this attribute: `{} = ...`", + parsing::DisplayPath(path), + ), + )), + Meta::List(meta) => Err(Error::new(meta.delimiter.span().open(), "expected `=`")), + } + } +} + +impl MetaList { + /// See [`Attribute::parse_args`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// See [`Attribute::parse_args_with`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + let scope = self.delimiter.span().close(); + crate::parse::parse_scoped(parser, scope, self.tokens.clone()) + } + + /// See [`Attribute::parse_nested_meta`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } +} + +#[cfg(feature = "printing")] +pub(crate) trait FilterAttrs<'a> { + type Ret: Iterator; + + fn outer(self) -> Self::Ret; + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret; +} + +#[cfg(feature = "printing")] +impl<'a> FilterAttrs<'a> for &'a [Attribute] { + type Ret = iter::Filter, fn(&&Attribute) -> bool>; + + fn outer(self) -> Self::Ret { + fn is_outer(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Outer => true, + AttrStyle::Inner(_) => false, + } + } + self.iter().filter(is_outer) + } + + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret { + fn is_inner(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Inner(_) => true, + AttrStyle::Outer => false, + } + } + self.iter().filter(is_inner) + } +} + +impl From for Meta { + fn from(meta: Path) -> Meta { + Meta::Path(meta) + } +} + +impl From for Meta { + fn from(meta: MetaList) -> Meta { + Meta::List(meta) + } +} + +impl From for Meta { + fn from(meta: MetaNameValue) -> Meta { + Meta::NameValue(meta) + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; + use crate::error::Result; + use crate::expr::{Expr, ExprLit}; + use crate::lit::Lit; + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::path::Path; + use crate::{mac, token}; + use alloc::vec::Vec; + use core::fmt::{self, Display}; + use proc_macro2::Ident; + + pub(crate) fn parse_inner(input: ParseStream, attrs: &mut Vec) -> Result<()> { + while input.peek(Token![#]) && input.peek2(Token![!]) { + attrs.push(input.call(single_parse_inner)?); + } + Ok(()) + } + + pub(crate) fn single_parse_inner(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Inner(input.parse()?), + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + pub(crate) fn single_parse_outer(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Outer, + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for Meta { + fn parse(input: ParseStream) -> Result { + let path = parse_outermost_meta_path(input)?; + parse_meta_after_path(path, input) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for MetaList { + fn parse(input: ParseStream) -> Result { + let path = parse_outermost_meta_path(input)?; + parse_meta_list_after_path(path, input) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for MetaNameValue { + fn parse(input: ParseStream) -> Result { + let path = parse_outermost_meta_path(input)?; + parse_meta_name_value_after_path(path, input) + } + } + + // Unlike meta::parse_meta_path which accepts arbitrary keywords in the path, + // only the `unsafe` keyword is accepted as an attribute's outermost path. + fn parse_outermost_meta_path(input: ParseStream) -> Result { + if input.peek(Token![unsafe]) { + let unsafe_token: Token![unsafe] = input.parse()?; + Ok(Path::from(Ident::new("unsafe", unsafe_token.span))) + } else { + Path::parse_mod_style(input) + } + } + + pub(crate) fn parse_meta_after_path(path: Path, input: ParseStream) -> Result { + if input.peek(token::Paren) || input.peek(token::Bracket) || input.peek(token::Brace) { + parse_meta_list_after_path(path, input).map(Meta::List) + } else if input.peek(Token![=]) && !input.peek(Token![==]) && !input.peek(Token![=>]) { + parse_meta_name_value_after_path(path, input).map(Meta::NameValue) + } else { + Ok(Meta::Path(path)) + } + } + + fn parse_meta_list_after_path(path: Path, input: ParseStream) -> Result { + let (delimiter, tokens) = mac::parse_delimiter(input)?; + Ok(MetaList { + path, + delimiter, + tokens, + }) + } + + fn parse_meta_name_value_after_path(path: Path, input: ParseStream) -> Result { + let eq_token: Token![=] = input.parse()?; + let ahead = input.fork(); + let lit: Option = ahead.parse()?; + let value = if let (Some(lit), true) = (lit, ahead.is_empty()) { + input.advance_to(&ahead); + Expr::Lit(ExprLit { + attrs: Vec::new(), + lit, + }) + } else if input.peek(Token![#]) && input.peek2(token::Bracket) { + return Err(input.error("unexpected attribute inside of attribute")); + } else { + input.parse()? + }; + Ok(MetaNameValue { + path, + eq_token, + value, + }) + } + + pub(super) struct DisplayAttrStyle<'a>(pub &'a AttrStyle); + + impl<'a> Display for DisplayAttrStyle<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(match self.0 { + AttrStyle::Outer => "#", + AttrStyle::Inner(_) => "#!", + }) + } + } + + pub(super) struct DisplayPath<'a>(pub &'a Path); + + impl<'a> Display for DisplayPath<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + for (i, segment) in self.0.segments.iter().enumerate() { + if i > 0 || self.0.leading_colon.is_some() { + formatter.write_str("::")?; + } + write!(formatter, "{}", segment.ident)?; + } + Ok(()) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; + use crate::path; + use crate::path::printing::PathStyle; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Attribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.pound_token.to_tokens(tokens); + if let AttrStyle::Inner(b) = &self.style { + b.to_tokens(tokens); + } + self.bracket_token.surround(tokens, |tokens| { + self.meta.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Meta { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Meta::Path(path) => path::printing::print_path(tokens, path, PathStyle::Mod), + Meta::List(meta_list) => meta_list.to_tokens(tokens), + Meta::NameValue(meta_name_value) => meta_name_value.to_tokens(tokens), + } + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for MetaList { + fn to_tokens(&self, tokens: &mut TokenStream) { + path::printing::print_path(tokens, &self.path, PathStyle::Mod); + self.delimiter.surround(tokens, self.tokens.clone()); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for MetaNameValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + path::printing::print_path(tokens, &self.path, PathStyle::Mod); + self.eq_token.to_tokens(tokens); + self.value.to_tokens(tokens); + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/bigint.rs b/zerocopy/vendor/syn-3.0.3/src/bigint.rs new file mode 100644 index 0000000000..d32298b793 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/bigint.rs @@ -0,0 +1,68 @@ +use alloc::string::String; +use alloc::vec::Vec; +use core::ops::{AddAssign, MulAssign}; + +// For implementing base10_digits() accessor on LitInt. +pub(crate) struct BigInt { + digits: Vec, +} + +impl BigInt { + pub(crate) fn new() -> Self { + BigInt { digits: Vec::new() } + } + + pub(crate) fn to_string(&self) -> String { + let mut repr = String::with_capacity(self.digits.len()); + + let mut has_nonzero = false; + for digit in self.digits.iter().rev() { + has_nonzero |= *digit != 0; + if has_nonzero { + repr.push((*digit + b'0') as char); + } + } + + if repr.is_empty() { + repr.push('0'); + } + + repr + } + + fn reserve_two_digits(&mut self) { + let len = self.digits.len(); + let desired = + len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize; + self.digits.resize(desired, 0); + } +} + +impl AddAssign for BigInt { + // Assumes increment <16. + fn add_assign(&mut self, mut increment: u8) { + self.reserve_two_digits(); + + let mut i = 0; + while increment > 0 { + let sum = self.digits[i] + increment; + self.digits[i] = sum % 10; + increment = sum / 10; + i += 1; + } + } +} + +impl MulAssign for BigInt { + // Assumes base <=16. + fn mul_assign(&mut self, base: u8) { + self.reserve_two_digits(); + + let mut carry = 0; + for digit in &mut self.digits { + let prod = *digit * base + carry; + *digit = prod % 10; + carry = prod / 10; + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/buffer.rs b/zerocopy/vendor/syn-3.0.3/src/buffer.rs new file mode 100644 index 0000000000..f2e205bd3b --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/buffer.rs @@ -0,0 +1,462 @@ +//! A stably addressed token buffer supporting efficient traversal based on a +//! cheaply copyable cursor. + +// This module is heavily commented as it contains most of the unsafe code in +// Syn, and caution should be used when editing it. The public-facing interface +// is 100% safe but the implementation is fragile internally. + +use crate::ext::TokenStreamExt as _; +use crate::Lifetime; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::marker::PhantomData; +use core::ptr; +use proc_macro2::extra::DelimSpan; +use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; + +/// Internal type which is used instead of `TokenTree` to represent a token tree +/// within a `TokenBuffer`. +enum Entry { + // Mimicking types from proc-macro. + // Group entries contain the offset to the matching End entry. + Group(Group, usize), + Ident(Ident), + Punct(Punct), + Literal(Literal), + // End entries contain the offset (negative) to the start of the buffer, and + // offset (negative) to the matching Group entry. + End(isize, isize), +} + +/// A buffer that can be efficiently traversed multiple times, unlike +/// `TokenStream` which requires a deep copy in order to traverse more than +/// once. +pub struct TokenBuffer { + // NOTE: Do not implement clone on this - while the current design could be + // cloned, other designs which could be desirable may not be cloneable. + entries: Box<[Entry]>, +} + +impl TokenBuffer { + fn recursive_new(entries: &mut Vec, stream: TokenStream) { + for tt in stream { + match tt { + TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)), + TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)), + TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)), + TokenTree::Group(group) => { + let group_start_index = entries.len(); + entries.push(Entry::End(0, 0)); // we replace this below + Self::recursive_new(entries, group.stream()); + let group_end_index = entries.len(); + let group_offset = group_end_index - group_start_index; + entries.push(Entry::End( + -(group_end_index as isize), + -(group_offset as isize), + )); + entries[group_start_index] = Entry::Group(group, group_offset); + } + } + } + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro::TokenStream`. + #[cfg(feature = "proc-macro")] + #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] + pub fn new(stream: proc_macro::TokenStream) -> Self { + Self::new2(stream.into()) + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro2::TokenStream`. + pub fn new2(stream: TokenStream) -> Self { + let mut entries = Vec::new(); + Self::recursive_new(&mut entries, stream); + entries.push(Entry::End(-(entries.len() as isize), 0)); + Self { + entries: entries.into_boxed_slice(), + } + } + + /// Creates a cursor referencing the first token in the buffer and able to + /// traverse until the end of the buffer. + pub fn begin(&self) -> Cursor { + let ptr = self.entries.as_ptr(); + unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) } + } +} + +/// A cheaply copyable cursor into a `TokenBuffer`. +/// +/// This cursor holds a shared reference into the immutable data which is used +/// internally to represent a `TokenStream`, and can be efficiently manipulated +/// and copied around. +/// +/// An empty `Cursor` can be created directly, or one may create a `TokenBuffer` +/// object and get a cursor to its first token with `begin()`. +pub struct Cursor<'a> { + // The current entry which the `Cursor` is pointing at. + ptr: *const Entry, + // This is the only `Entry::End` object which this cursor is allowed to + // point at. All other `End` objects are skipped over in `Cursor::create`. + scope: *const Entry, + // Cursor is covariant in 'a. This field ensures that our pointers are still + // valid. + marker: PhantomData<&'a Entry>, +} + +impl<'a> Cursor<'a> { + /// Creates a cursor referencing a static empty TokenStream. + pub fn empty() -> Self { + // It's safe in this situation for us to put an `Entry` object in global + // storage, despite it not actually being safe to send across threads + // (`Ident` is a reference into a thread-local table). This is because + // this entry never includes a `Ident` object. + // + // This wrapper struct allows us to break the rules and put a `Sync` + // object in global storage. + struct UnsafeSyncEntry(Entry); + unsafe impl Sync for UnsafeSyncEntry {} + static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0, 0)); + + Cursor { + ptr: &EMPTY_ENTRY.0, + scope: &EMPTY_ENTRY.0, + marker: PhantomData, + } + } + + /// This create method intelligently exits non-explicitly-entered + /// `None`-delimited scopes when the cursor reaches the end of them, + /// allowing for them to be treated transparently. + unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self { + // NOTE: If we're looking at a `End`, we want to advance the cursor + // past it, unless `ptr == scope`, which means that we're at the edge of + // our cursor's scope. We should only have `ptr != scope` at the exit + // from None-delimited groups entered with `ignore_none`. + while let Entry::End(..) = unsafe { &*ptr } { + if ptr::eq(ptr, scope) { + break; + } + ptr = unsafe { ptr.add(1) }; + } + + Cursor { + ptr, + scope, + marker: PhantomData, + } + } + + /// Get the current entry. + fn entry(self) -> &'a Entry { + unsafe { &*self.ptr } + } + + /// Bump the cursor to point at the next token after the current one. This + /// is undefined behavior if the cursor is currently looking at an + /// `Entry::End`. + /// + /// If the cursor is looking at an `Entry::Group`, the bumped cursor will + /// point at the first token in the group (with the same scope end). + unsafe fn bump_ignore_group(self) -> Cursor<'a> { + unsafe { Cursor::create(self.ptr.add(1), self.scope) } + } + + /// While the cursor is looking at a `None`-delimited group, move it to look + /// at the first token inside instead. If the group is empty, this will move + /// the cursor past the `None`-delimited group. + /// + /// WARNING: This mutates its argument. + fn ignore_none(&mut self) { + while let Entry::Group(group, _) = self.entry() { + if group.delimiter() == Delimiter::None { + unsafe { *self = self.bump_ignore_group() }; + } else { + break; + } + } + } + + /// Checks whether the cursor is currently pointing at the end of its valid + /// scope. + pub fn eof(self) -> bool { + // We're at eof if we're at the end of our scope. + ptr::eq(self.ptr, self.scope) + } + + /// If the cursor is pointing at a `Ident`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + pub(crate) fn peek_keyword(mut self, token: &str) -> bool { + self.ignore_none(); + match self.entry() { + Entry::Ident(ident) => ident == token, + _ => false, + } + } + + /// If the cursor is pointing at a `Punct`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() != '\'' => { + Some((punct.clone(), unsafe { self.bump_ignore_group() })) + } + _ => None, + } + } + + pub(crate) fn peek_punct(mut self, token: &str) -> bool { + for (i, ch) in token.chars().enumerate() { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() == ch => { + if i == token.len() - 1 { + return true; + } else if punct.spacing() != Spacing::Joint { + break; + } + self = unsafe { self.bump_ignore_group() }; + } + _ => break, + } + } + false + } + + /// If the cursor is pointing at a `Literal`, return it along with a cursor + /// pointing at the next `TokenTree`. + pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + /// If the cursor is pointing at a `Lifetime`, returns it along with a + /// cursor pointing at the next `TokenTree`. + pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + let next = unsafe { self.bump_ignore_group() }; + let (ident, rest) = next.ident()?; + let lifetime = Lifetime { + apostrophe: punct.span(), + ident, + }; + Some((lifetime, rest)) + } + _ => None, + } + } + + /// If the cursor is pointing at a `Group` with the given delimiter, returns + /// a cursor into that group and one pointing to the next `TokenTree`. + pub fn group(mut self, delim: Delimiter) -> Option<(Cursor<'a>, DelimSpan, Cursor<'a>)> { + // If we're not trying to enter a none-delimited group, we want to + // ignore them. We have to make sure to _not_ ignore them when we want + // to enter them, of course. For obvious reasons. + if delim != Delimiter::None { + self.ignore_none(); + } + + if let Entry::Group(group, end_offset) = self.entry() { + if group.delimiter() == delim { + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, span, after_group)); + } + } + + None + } + + /// If the cursor is pointing at a `Group`, returns a cursor into the group + /// and one pointing to the next `TokenTree`. + pub fn any_group(self) -> Option<(Cursor<'a>, Delimiter, DelimSpan, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let delimiter = group.delimiter(); + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, delimiter, span, after_group)); + } + + None + } + + pub(crate) fn any_group_token(self) -> Option<(Group, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((group.clone(), after_group)); + } + + None + } + + /// Copies all remaining tokens visible from this cursor into a + /// `TokenStream`. + pub fn token_stream(self) -> TokenStream { + let mut tokens = TokenStream::new(); + let mut cursor = self; + while let Some((tt, rest)) = cursor.token_tree() { + tokens.append(tt); + cursor = rest; + } + tokens + } + + /// If the cursor is pointing at a `TokenTree`, returns it along with a + /// cursor pointing at the next `TokenTree`. + /// + /// Returns `None` if the cursor has reached the end of its stream. + /// + /// This method does not treat `None`-delimited groups as transparent, and + /// will return a `Group(None, ..)` if the cursor is looking at one. + pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> { + let (tree, len) = match self.entry() { + Entry::Group(group, end_offset) => (group.clone().into(), *end_offset), + Entry::Literal(literal) => (literal.clone().into(), 1), + Entry::Ident(ident) => (ident.clone().into(), 1), + Entry::Punct(punct) => (punct.clone().into(), 1), + Entry::End(..) => return None, + }; + + let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) }; + Some((tree, rest)) + } + + /// Returns the `Span` of the current token, or `Span::call_site()` if this + /// cursor points to eof. + pub fn span(mut self) -> Span { + match self.entry() { + Entry::Group(group, _) => group.span(), + Entry::Literal(literal) => literal.span(), + Entry::Ident(ident) => ident.span(), + Entry::Punct(punct) => punct.span(), + Entry::End(_, offset) => { + self.ptr = unsafe { self.ptr.offset(*offset) }; + if let Entry::Group(group, _) = self.entry() { + group.span_close() + } else { + Span::call_site() + } + } + } + } + + /// Returns the `Span` of the token immediately prior to the position of + /// this cursor, or of the current token if there is no previous one. + pub fn prev_span(mut self) -> Span { + if start_of_buffer(self) < self.ptr { + self.ptr = unsafe { self.ptr.sub(1) }; + } + self.span() + } + + /// Skip over the next token that is not a None-delimited group, without + /// cloning it. Returns `None` if this cursor points to eof. + /// + /// This method treats `'lifetimes` as a single token. + pub(crate) fn skip(mut self) -> Option> { + self.ignore_none(); + + let len = match self.entry() { + Entry::End(..) => return None, + + // Treat lifetimes as a single tt for the purposes of 'skip'. + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + match unsafe { &*self.ptr.add(1) } { + Entry::Ident(_) => 2, + _ => 1, + } + } + + Entry::Group(_, end_offset) => *end_offset, + _ => 1, + }; + + Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) }) + } + + pub(crate) fn scope_delimiter(self) -> Delimiter { + match unsafe { &*self.scope } { + Entry::End(_, offset) => match unsafe { &*self.scope.offset(*offset) } { + Entry::Group(group, _) => group.delimiter(), + _ => Delimiter::None, + }, + _ => unreachable!(), + } + } +} + +impl<'a> Copy for Cursor<'a> {} + +impl<'a> Clone for Cursor<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Eq for Cursor<'a> {} + +impl<'a> PartialEq for Cursor<'a> { + fn eq(&self, other: &Self) -> bool { + ptr::eq(self.ptr, other.ptr) + } +} + +impl<'a> PartialOrd for Cursor<'a> { + fn partial_cmp(&self, other: &Self) -> Option { + if same_buffer(*self, *other) { + Some(cmp_assuming_same_buffer(*self, *other)) + } else { + None + } + } +} + +pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool { + ptr::eq(a.scope, b.scope) +} + +pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool { + ptr::eq(start_of_buffer(a), start_of_buffer(b)) +} + +fn start_of_buffer(cursor: Cursor) -> *const Entry { + unsafe { + match &*cursor.scope { + Entry::End(offset, _) => cursor.scope.offset(*offset), + _ => unreachable!(), + } + } +} + +pub(crate) fn cmp_assuming_same_buffer(a: Cursor, b: Cursor) -> Ordering { + a.ptr.cmp(&b.ptr) +} + +pub(crate) fn open_span_of_group(cursor: Cursor) -> Span { + match cursor.entry() { + Entry::Group(group, _) => group.span_open(), + _ => cursor.span(), + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/classify.rs b/zerocopy/vendor/syn-3.0.3/src/classify.rs new file mode 100644 index 0000000000..10c23e2e34 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/classify.rs @@ -0,0 +1,311 @@ +#[cfg(feature = "full")] +use crate::expr::Expr; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::generics::TypeParamBound; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::path::{Path, PathArguments}; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::punctuated::Punctuated; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::ty::{ReturnType, Type}; +#[cfg(any(feature = "printing", feature = "full"))] +use core::ops::ControlFlow; +#[cfg(feature = "full")] +use proc_macro2::{Delimiter, TokenStream, TokenTree}; + +#[cfg(feature = "full")] +pub(crate) fn requires_semi_to_be_stmt(expr: &Expr) -> bool { + match expr { + Expr::Macro(expr) => !expr.mac.delimiter.is_brace(), + _ => requires_comma_to_be_match_arm(expr), + } +} + +#[cfg(feature = "full")] +pub(crate) fn requires_comma_to_be_match_arm(expr: &Expr) -> bool { + match expr { + Expr::If(_) + | Expr::Match(_) + | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc + | Expr::While(_) + | Expr::Loop(_) + | Expr::ForLoop(_) + | Expr::TryBlock(_) + | Expr::Const(_) => false, + + Expr::Array(_) + | Expr::Assign(_) + | Expr::Async(_) + | Expr::Await(_) + | Expr::Binary(_) + | Expr::Break(_) + | Expr::Call(_) + | Expr::Cast(_) + | Expr::Closure(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Group(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Range(_) + | Expr::RawAddr(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::Try(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Yield(_) + | Expr::Verbatim(_) => true, + } +} + +#[cfg(feature = "printing")] +pub(crate) fn trailing_unparameterized_path(mut ty: &Type) -> bool { + loop { + match ty { + Type::FnPtr(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Path(t) => match last_type_in_path(&t.path) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Macro(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) + | Type::Verbatim(_) => return false, + } + } + + fn last_type_in_path(path: &Path) -> ControlFlow { + match &path.segments.last().unwrap().arguments { + PathArguments::None => ControlFlow::Break(true), + PathArguments::AngleBracketed(_) => ControlFlow::Break(false), + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => ControlFlow::Break(false), + ReturnType::Type(_, ret) => ControlFlow::Continue(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + TypeParamBound::Trait(t) => last_type_in_path(&t.path), + TypeParamBound::Lifetime(_) + | TypeParamBound::PreciseCapture(_) + | TypeParamBound::Verbatim(_) => ControlFlow::Break(false), + } + } +} + +/// Whether the expression's first token is the label of a loop/block. +#[cfg(all(feature = "printing", feature = "full"))] +pub(crate) fn expr_leading_label(mut expr: &Expr) -> bool { + loop { + match expr { + Expr::Block(e) => return e.label.is_some(), + Expr::ForLoop(e) => return e.label.is_some(), + Expr::Loop(e) => return e.label.is_some(), + Expr::While(e) => return e.label.is_some(), + + Expr::Assign(e) => expr = &e.left, + Expr::Await(e) => expr = &e.base, + Expr::Binary(e) => expr = &e.left, + Expr::Call(e) => expr = &e.func, + Expr::Cast(e) => expr = &e.expr, + Expr::Field(e) => expr = &e.base, + Expr::Index(e) => expr = &e.expr, + Expr::MethodCall(e) => expr = &e.receiver, + Expr::Range(e) => match &e.start { + Some(start) => expr = start, + None => return false, + }, + Expr::Try(e) => expr = &e.expr, + + Expr::Array(_) + | Expr::Async(_) + | Expr::Break(_) + | Expr::Closure(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::Group(_) + | Expr::If(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::RawAddr(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::Yield(_) => return false, + } + } +} + +/// Whether the expression's last token is `}`. +#[cfg(feature = "full")] +pub(crate) fn expr_trailing_brace(mut expr: &Expr) -> bool { + loop { + match expr { + Expr::Async(_) + | Expr::Block(_) + | Expr::Const(_) + | Expr::ForLoop(_) + | Expr::If(_) + | Expr::Loop(_) + | Expr::Match(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Unsafe(_) + | Expr::While(_) => return true, + + Expr::Assign(e) => expr = &e.right, + Expr::Binary(e) => expr = &e.right, + Expr::Break(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Cast(e) => return type_trailing_brace(&e.ty), + Expr::Closure(e) => expr = &e.body, + Expr::Let(e) => expr = &e.expr, + Expr::Macro(e) => return e.mac.delimiter.is_brace(), + Expr::Range(e) => match &e.end { + Some(end) => expr = end, + None => return false, + }, + Expr::RawAddr(e) => expr = &e.expr, + Expr::Reference(e) => expr = &e.expr, + Expr::Return(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Unary(e) => expr = &e.expr, + Expr::Verbatim(e) => return tokens_trailing_brace(e), + Expr::Yield(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + + Expr::Array(_) + | Expr::Await(_) + | Expr::Call(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Group(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Lit(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Repeat(_) + | Expr::Try(_) + | Expr::Tuple(_) => return false, + } + } + + fn type_trailing_brace(mut ty: &Type) -> bool { + loop { + match ty { + Type::FnPtr(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Macro(t) => return t.mac.delimiter.is_brace(), + Type::Path(t) => match last_type_in_path(&t.path) { + Some(t) => ty = t, + None => return false, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Verbatim(t) => return tokens_trailing_brace(t), + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) => return false, + } + } + } + + fn last_type_in_path(path: &Path) -> Option<&Type> { + match &path.segments.last().unwrap().arguments { + PathArguments::None | PathArguments::AngleBracketed(_) => None, + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => None, + ReturnType::Type(_, ret) => Some(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + TypeParamBound::Trait(t) => match last_type_in_path(&t.path) { + Some(t) => ControlFlow::Continue(t), + None => ControlFlow::Break(false), + }, + TypeParamBound::Lifetime(_) | TypeParamBound::PreciseCapture(_) => { + ControlFlow::Break(false) + } + TypeParamBound::Verbatim(t) => ControlFlow::Break(tokens_trailing_brace(t)), + } + } + + fn tokens_trailing_brace(tokens: &TokenStream) -> bool { + if let Some(TokenTree::Group(last)) = tokens.clone().into_iter().last() { + last.delimiter() == Delimiter::Brace + } else { + false + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/custom_keyword.rs b/zerocopy/vendor/syn-3.0.3/src/custom_keyword.rs new file mode 100644 index 0000000000..cc4f632c98 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/custom_keyword.rs @@ -0,0 +1,260 @@ +/// Define a type that supports parsing and printing a given identifier as if it +/// were a keyword. +/// +/// # Usage +/// +/// As a convention, it is recommended that this macro be invoked within a +/// module called `kw` or `keyword` and that the resulting parser be invoked +/// with a `kw::` or `keyword::` prefix. +/// +/// ``` +/// mod kw { +/// syn::custom_keyword!(whatever); +/// } +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in keyword token. +/// +/// - [Peeking] — `input.peek(kw::whatever)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #whatever_token ... )` +/// +/// - Construction from a [`Span`] — `let whatever_token = kw::whatever(sp)` +/// +/// - Field access to its span — `let sp = whatever_token.span` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// This example parses input that looks like `bool = true` or `str = "value"`. +/// The key must be either the identifier `bool` or the identifier `str`. If +/// `bool`, the value may be either `true` or `false`. If `str`, the value may +/// be any string literal. +/// +/// The symbols `bool` and `str` are not reserved keywords in Rust so these are +/// not considered keywords in the `syn::token` module. Like any other +/// identifier that is not a keyword, these can be declared as custom keywords +/// by crates that need to use them as such. +/// +/// ``` +/// use syn::{LitBool, LitStr, Result, Token}; +/// use syn::parse::{Parse, ParseStream}; +/// +/// mod kw { +/// syn::custom_keyword!(bool); +/// syn::custom_keyword!(str); +/// } +/// +/// enum Argument { +/// Bool { +/// bool_token: kw::bool, +/// eq_token: Token![=], +/// value: LitBool, +/// }, +/// Str { +/// str_token: kw::str, +/// eq_token: Token![=], +/// value: LitStr, +/// }, +/// } +/// +/// impl Parse for Argument { +/// fn parse(input: ParseStream) -> Result { +/// let lookahead = input.lookahead1(); +/// if lookahead.peek(kw::bool) { +/// Ok(Argument::Bool { +/// bool_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else if lookahead.peek(kw::str) { +/// Ok(Argument::Str { +/// str_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else { +/// Err(lookahead.error()) +/// } +/// } +/// } +/// ``` +#[macro_export] +macro_rules! custom_keyword { + ($ident:ident) => { + #[allow(non_camel_case_types)] + pub struct $ident { + #[allow(dead_code)] + pub span: $crate::__private::Span, + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::__private::Span>>( + span: __S, + ) -> $ident { + $ident { + span: $crate::__private::IntoSpans::into_spans(span), + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident { + span: $crate::__private::Span::call_site(), + } + } + } + + $crate::impl_parse_for_custom_keyword!($ident); + $crate::impl_to_tokens_for_custom_keyword!($ident); + $crate::impl_clone_for_custom_keyword!($ident); + $crate::impl_extra_traits_for_custom_keyword!($ident); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => { + // For peek. + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + if let $crate::__private::Some((ident, _rest)) = cursor.ident() { + ident == $crate::__private::stringify!($ident) + } else { + false + } + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::__private::stringify!($ident), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + input.step(|cursor| { + if let $crate::__private::Some((ident, rest)) = cursor.ident() { + if ident == $crate::__private::stringify!($ident) { + return $crate::__private::Ok(($ident { span: ident.span() }, rest)); + } + } + $crate::__private::Err(cursor.error($crate::__private::concat!( + "expected `", + $crate::__private::stringify!($ident), + "`", + ))) + }) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + let ident = $crate::Ident::new($crate::__private::stringify!($ident), self.span); + $crate::__private::TokenStreamExt::append(tokens, ident); + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str( + f, + $crate::__private::concat!( + "Keyword [", + $crate::__private::stringify!($ident), + "]", + ), + ) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => {}; +} diff --git a/zerocopy/vendor/syn-3.0.3/src/custom_punctuation.rs b/zerocopy/vendor/syn-3.0.3/src/custom_punctuation.rs new file mode 100644 index 0000000000..58955c7ff1 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/custom_punctuation.rs @@ -0,0 +1,305 @@ +/// Define a type that supports parsing and printing a multi-character symbol +/// as if it were a punctuation token. +/// +/// # Usage +/// +/// ``` +/// syn::custom_punctuation!(LeftRightArrow, <=>); +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in punctuation token. +/// +/// - [Peeking] — `input.peek(LeftRightArrow)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #lrarrow ... )` +/// +/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` +/// +/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` +/// +/// - Field access to its spans — `let spans = lrarrow.spans` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// ``` +/// use core::iter; +/// use proc_macro2::{TokenStream, TokenTree}; +/// use syn::parse::{Parse, ParseStream, Peek, Result}; +/// use syn::punctuated::Punctuated; +/// use syn::Expr; +/// +/// syn::custom_punctuation!(PathSeparator, ); +/// +/// // expr expr expr ... +/// struct PathSegments { +/// segments: Punctuated, +/// } +/// +/// impl Parse for PathSegments { +/// fn parse(input: ParseStream) -> Result { +/// let mut segments = Punctuated::new(); +/// +/// let first = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(first)?); +/// +/// while input.peek(PathSeparator) { +/// segments.push_punct(input.parse()?); +/// +/// let next = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(next)?); +/// } +/// +/// Ok(PathSegments { segments }) +/// } +/// } +/// +/// fn parse_until(input: ParseStream, end: E) -> Result { +/// let mut tokens = TokenStream::new(); +/// while !input.is_empty() && !input.peek(end) { +/// let next: TokenTree = input.parse()?; +/// tokens.extend(iter::once(next)); +/// } +/// Ok(tokens) +/// } +/// +/// fn main() { +/// let input = r#" a::b c::d::e "#; +/// let _: PathSegments = syn::parse_str(input).unwrap(); +/// } +/// ``` +#[macro_export] +macro_rules! custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + pub struct $ident { + #[allow(dead_code)] + pub spans: $crate::custom_punctuation_repr!($($tt)+), + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>( + spans: __S, + ) -> $ident { + let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*; + $ident { + spans: $crate::__private::IntoSpans::into_spans(spans) + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident($crate::__private::Span::call_site()) + } + } + + $crate::impl_parse_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_clone_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + $crate::__private::peek_punct(cursor, $crate::stringify_punct!($($tt)+)) + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::stringify_punct!($($tt)+), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + let spans: $crate::custom_punctuation_repr!($($tt)+) = + $crate::__private::parse_punct(input, $crate::stringify_punct!($($tt)+))?; + Ok($ident(spans)) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + $crate::__private::print_punct($crate::stringify_punct!($($tt)+), &self.spans, tokens) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str(f, $crate::__private::stringify!($ident)) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_repr { + ($($tt:tt)+) => { + [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+] + }; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +#[rustfmt::skip] +macro_rules! custom_punctuation_len { + ($mode:ident, &) => { 1 }; + ($mode:ident, &&) => { 2 }; + ($mode:ident, &=) => { 2 }; + ($mode:ident, @) => { 1 }; + ($mode:ident, ^) => { 1 }; + ($mode:ident, ^=) => { 2 }; + ($mode:ident, :) => { 1 }; + ($mode:ident, ,) => { 1 }; + ($mode:ident, $) => { 1 }; + ($mode:ident, .) => { 1 }; + ($mode:ident, ..) => { 2 }; + ($mode:ident, ...) => { 3 }; + ($mode:ident, ..=) => { 3 }; + ($mode:ident, =) => { 1 }; + ($mode:ident, ==) => { 2 }; + ($mode:ident, =>) => { 2 }; + ($mode:ident, >=) => { 2 }; + ($mode:ident, >) => { 1 }; + ($mode:ident, <-) => { 2 }; + ($mode:ident, <=) => { 2 }; + ($mode:ident, <) => { 1 }; + ($mode:ident, -) => { 1 }; + ($mode:ident, -=) => { 2 }; + ($mode:ident, !=) => { 2 }; + ($mode:ident, !) => { 1 }; + ($mode:ident, |) => { 1 }; + ($mode:ident, |=) => { 2 }; + ($mode:ident, ||) => { 2 }; + ($mode:ident, ::) => { 2 }; + ($mode:ident, %) => { 1 }; + ($mode:ident, %=) => { 2 }; + ($mode:ident, +) => { 1 }; + ($mode:ident, +=) => { 2 }; + ($mode:ident, #) => { 1 }; + ($mode:ident, ?) => { 1 }; + ($mode:ident, ->) => { 2 }; + ($mode:ident, ;) => { 1 }; + ($mode:ident, <<) => { 2 }; + ($mode:ident, <<=) => { 3 }; + ($mode:ident, >>) => { 2 }; + ($mode:ident, >>=) => { 3 }; + ($mode:ident, /) => { 1 }; + ($mode:ident, /=) => { 2 }; + ($mode:ident, *) => { 1 }; + ($mode:ident, *=) => { 2 }; + ($mode:ident, ~) => { 1 }; + (lenient, $tt:tt) => { 0 }; + (strict, $tt:tt) => {{ $crate::custom_punctuation_unexpected!($tt); 0 }}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_unexpected { + () => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! stringify_punct { + ($($tt:tt)+) => { + $crate::__private::concat!($($crate::__private::stringify!($tt)),+) + }; +} diff --git a/zerocopy/vendor/syn-3.0.3/src/data.rs b/zerocopy/vendor/syn-3.0.3/src/data.rs new file mode 100644 index 0000000000..e2e936ab21 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/data.rs @@ -0,0 +1,489 @@ +use crate::attr::Attribute; +#[cfg(feature = "parsing")] +use crate::error::Result; +use crate::expr::{Expr, Index, Member}; +use crate::ident::Ident; +use crate::punctuated::{self, Punctuated}; +use crate::restriction::Visibility; +use crate::token; +use crate::ty::Type; +use alloc::vec::Vec; + +ast_struct! { + /// An enum variant. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Variant { + pub attrs: Vec, + + /// Name of the variant. + pub ident: Ident, + + /// Content stored in the variant. + pub fields: Fields, + + /// Explicit discriminant: `Variant = 1` + pub discriminant: Option<(Token![=], Expr)>, + } +} + +ast_enum_of_structs! { + /// Data stored within an enum variant or struct. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Fields { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + Named(FieldsNamed), + + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + Unnamed(FieldsUnnamed), + + /// Unit struct or unit variant such as `None`. + Unit, + } +} + +ast_struct! { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsNamed { + pub brace_token: token::Brace, + pub named: Punctuated, + } +} + +ast_struct! { + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsUnnamed { + pub paren_token: token::Paren, + pub unnamed: Punctuated, + } +} + +impl Fields { + /// Get an iterator over the borrowed [`Field`] items in this object. This + /// iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + pub fn iter(&self) -> punctuated::Iter { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter(), + Fields::Named(f) => f.named.iter(), + Fields::Unnamed(f) => f.unnamed.iter(), + } + } + + /// Get an iterator over the mutably borrowed [`Field`] items in this + /// object. This iterator can be used to iterate over a named or unnamed + /// struct or variant's fields uniformly. + pub fn iter_mut(&mut self) -> punctuated::IterMut { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter_mut(), + Fields::Named(f) => f.named.iter_mut(), + Fields::Unnamed(f) => f.unnamed.iter_mut(), + } + } + + /// Returns the number of fields. + pub fn len(&self) -> usize { + match self { + Fields::Unit => 0, + Fields::Named(f) => f.named.len(), + Fields::Unnamed(f) => f.unnamed.len(), + } + } + + /// Returns `true` if there are zero fields. + pub fn is_empty(&self) -> bool { + match self { + Fields::Unit => true, + Fields::Named(f) => f.named.is_empty(), + Fields::Unnamed(f) => f.unnamed.is_empty(), + } + } + + return_impl_trait! { + /// Get an iterator over the fields of a struct or variant as [`Member`]s. + /// This iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + /// + /// # Example + /// + /// The following is a simplistic [`Clone`] derive for structs. (A more + /// complete implementation would additionally want to infer trait bounds on + /// the generic type parameters.) + /// + /// ``` + /// # use quote::quote; + /// # + /// fn derive_clone(input: &syn::ItemStruct) -> proc_macro2::TokenStream { + /// let ident = &input.ident; + /// let members = input.fields.members(); + /// let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + /// quote! { + /// impl #impl_generics Clone for #ident #ty_generics #where_clause { + /// fn clone(&self) -> Self { + /// Self { + /// #(#members: self.#members.clone()),* + /// } + /// } + /// } + /// } + /// } + /// ``` + /// + /// For structs with named fields, it produces an expression like `Self { a: + /// self.a.clone() }`. For structs with unnamed fields, `Self { 0: + /// self.0.clone() }`. And for unit structs, `Self {}`. + pub fn members(&self) -> impl Iterator + Clone + '_ [Members] { + Members { + fields: self.iter(), + index: 0, + } + } + } +} + +impl IntoIterator for Fields { + type Item = Field; + type IntoIter = punctuated::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + match self { + Fields::Unit => Punctuated::::new().into_iter(), + Fields::Named(f) => f.named.into_iter(), + Fields::Unnamed(f) => f.unnamed.into_iter(), + } + } +} + +impl<'a> IntoIterator for &'a Fields { + type Item = &'a Field; + type IntoIter = punctuated::Iter<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> IntoIterator for &'a mut Fields { + type Item = &'a mut Field; + type IntoIter = punctuated::IterMut<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +ast_struct! { + /// A field of a struct or enum variant. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Field { + pub attrs: Vec, + + pub vis: Visibility, + + /// (Non-exhaustive) Additional optional information about a field. + pub modifiers: FieldModifiers, + + /// Name of the field, if any. + /// + /// Fields of tuple structs have no names. + pub ident: Option, + + pub colon_token: Option, + + pub ty: Type, + + pub default: Option<(Token![=], Expr)>, + } +} + +ast_struct! { + /// Additional optional information about a field. + /// + /// This data structure may grow to accommodate future Rust language + /// changes, including the following in-progress RFCs: + /// + /// - [RFC 3323] "Restrictions", such as `mut(crate)` + /// - [RFC 3458] "Unsafe fields" + /// + /// [RFC 3323]: https://rust-lang.github.io/rfcs/3323-restrictions.html + /// [RFC 3458]: https://github.com/rust-lang/rfcs/pull/3458 + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + #[non_exhaustive] + pub struct FieldModifiers {} +} + +impl Default for FieldModifiers { + fn default() -> Self { + FieldModifiers {} + } +} + +impl FieldModifiers { + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_empty(&self) -> Result<()> { + Ok(()) + } +} + +pub struct Members<'a> { + fields: punctuated::Iter<'a, Field>, + index: u32, +} + +impl<'a> Iterator for Members<'a> { + type Item = Member; + + fn next(&mut self) -> Option { + let field = self.fields.next()?; + let member = match &field.ident { + Some(ident) => Member::Named(ident.clone()), + None => { + #[cfg(all(feature = "parsing", feature = "printing"))] + let span = crate::spanned::Spanned::span(&field.ty); + #[cfg(not(all(feature = "parsing", feature = "printing")))] + let span = proc_macro2::Span::call_site(); + Member::Unnamed(Index { + index: self.index, + span, + }) + } + }; + self.index += 1; + Some(member) + } +} + +impl<'a> Clone for Members<'a> { + fn clone(&self) -> Self { + Members { + fields: self.fields.clone(), + index: self.index, + } + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Field, FieldModifiers, Fields, FieldsNamed, FieldsUnnamed, Variant}; + use crate::error::{Error, Result}; + use crate::expr::Expr; + use crate::ext::IdentExt as _; + use crate::ident::Ident; + #[cfg(not(feature = "full"))] + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::restriction::Visibility; + #[cfg(not(feature = "full"))] + use crate::scan_expr::scan_expr; + use crate::token; + use crate::ty::Type; + use crate::verbatim; + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for Variant { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let _visibility: Visibility = input.parse()?; + let ident: Ident = input.parse()?; + let fields = if input.peek(token::Brace) { + Fields::Named(input.parse()?) + } else if input.peek(token::Paren) { + Fields::Unnamed(input.parse()?) + } else { + Fields::Unit + }; + let discriminant = if input.peek(Token![=]) { + let eq_token: Token![=] = input.parse()?; + #[cfg(feature = "full")] + let discriminant: Expr = input.parse()?; + #[cfg(not(feature = "full"))] + let discriminant = { + let begin = input.cursor(); + let ahead = input.fork(); + let mut discriminant: Result = ahead.parse(); + if discriminant.is_ok() { + input.advance_to(&ahead); + } else if scan_expr(input).is_ok() { + discriminant = Ok(Expr::Verbatim(verbatim::between(begin, input.cursor()))); + } + discriminant? + }; + Some((eq_token, discriminant)) + } else { + None + }; + Ok(Variant { + attrs, + ident, + fields, + discriminant, + }) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for FieldsNamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsNamed { + brace_token: braced!(content in input), + named: content.parse_terminated(Field::parse_named, Token![,])?, + }) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for FieldsUnnamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsUnnamed { + paren_token: parenthesized!(content in input), + unnamed: content.parse_terminated(Field::parse_unnamed, Token![,])?, + }) + } + } + + impl Field { + /// Parses a named (braced struct) field. + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_named(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + + let unnamed_field = cfg!(feature = "full") && input.peek(Token![_]); + let ident = if unnamed_field { + input.call(Ident::parse_any) + } else { + input.parse() + }?; + + let colon_token: Token![:] = input.parse()?; + + let ty: Type = if unnamed_field + && (input.peek(Token![struct]) + || input.peek(Token![union]) && input.peek2(token::Brace)) + { + let begin = input.cursor(); + input.call(Ident::parse_any)?; + input.parse::()?; + Type::Verbatim(verbatim::between(begin, input.cursor())) + } else { + input.parse()? + }; + + let default = if input.peek(Token![=]) { + let eq_token: Token![=] = input.parse()?; + let expr: Expr = input.parse()?; + Some((eq_token, expr)) + } else { + None + }; + + Ok(Field { + attrs, + vis, + modifiers: FieldModifiers {}, + ident: Some(ident), + colon_token: Some(colon_token), + ty, + default, + }) + } + + /// Parses an unnamed (tuple struct) field. + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_unnamed(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + let ty: Type = input.parse()?; + + if input.peek(Token![=]) { + input.parse::()?; + let expr_start = input.cursor(); + input.parse::()?; + let expr_end = input.cursor(); + return Err(Error::new_range( + expr_start..expr_end, + "field default value is only supported in structs with named fields", + )); + } + + Ok(Field { + attrs, + vis, + modifiers: FieldModifiers {}, + ident: None, + colon_token: None, + ty, + default: None, + }) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::data::{Field, FieldsNamed, FieldsUnnamed, Variant}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::{ToTokens, TokenStreamExt as _}; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Variant { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.ident.to_tokens(tokens); + self.fields.to_tokens(tokens); + if let Some((eq_token, disc)) = &self.discriminant { + eq_token.to_tokens(tokens); + disc.to_tokens(tokens); + } + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsNamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.brace_token.surround(tokens, |tokens| { + self.named.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsUnnamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.paren_token.surround(tokens, |tokens| { + self.unnamed.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Field { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.vis.to_tokens(tokens); + if let Some(ident) = &self.ident { + ident.to_tokens(tokens); + TokensOrDefault(&self.colon_token).to_tokens(tokens); + } + self.ty.to_tokens(tokens); + if let Some((eq_token, default)) = &self.default { + eq_token.to_tokens(tokens); + default.to_tokens(tokens); + } + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/derive.rs b/zerocopy/vendor/syn-3.0.3/src/derive.rs new file mode 100644 index 0000000000..573b88fb16 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/derive.rs @@ -0,0 +1,260 @@ +use crate::attr::Attribute; +use crate::data::{Fields, FieldsNamed, Variant}; +use crate::generics::Generics; +use crate::ident::Ident; +use crate::punctuated::Punctuated; +use crate::restriction::Visibility; +use crate::token; +use alloc::vec::Vec; + +ast_struct! { + /// Data structure sent to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DeriveInput { + pub attrs: Vec, + pub vis: Visibility, + pub ident: Ident, + pub generics: Generics, + pub data: Data, + } +} + +ast_enum! { + /// The storage of a struct, enum or union data structure. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub enum Data { + Struct(DataStruct), + Enum(DataEnum), + Union(DataUnion), + } +} + +ast_struct! { + /// A struct input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataStruct { + pub struct_token: Token![struct], + pub fields: Fields, + pub semi_token: Option, + } +} + +ast_struct! { + /// An enum input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataEnum { + pub enum_token: Token![enum], + pub brace_token: token::Brace, + pub variants: Punctuated, + } +} + +ast_struct! { + /// An untagged union input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataUnion { + pub union_token: Token![union], + pub fields: FieldsNamed, + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Fields, FieldsNamed, Variant}; + use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; + use crate::error::Result; + use crate::generics::{Generics, WhereClause}; + use crate::ident::Ident; + use crate::parse::{Parse, ParseStream}; + use crate::punctuated::Punctuated; + use crate::restriction::Visibility; + use crate::token; + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for DeriveInput { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis = input.parse::()?; + + let lookahead = input.lookahead1(); + if lookahead.peek(Token![struct]) { + let struct_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields, semi) = data_struct(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Struct(DataStruct { + struct_token, + fields, + semi_token: semi, + }), + }) + } else if lookahead.peek(Token![enum]) { + let enum_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, brace, variants) = data_enum(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Enum(DataEnum { + enum_token, + brace_token: brace, + variants, + }), + }) + } else if lookahead.peek(Token![union]) { + let union_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields) = data_union(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Union(DataUnion { + union_token, + fields, + }), + }) + } else { + Err(lookahead.error()) + } + } + } + + pub(crate) fn data_struct( + input: ParseStream, + ) -> Result<(Option, Fields, Option)> { + let mut lookahead = input.lookahead1(); + let mut where_clause = None; + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if where_clause.is_none() && lookahead.peek(token::Paren) { + let fields = input.parse()?; + + lookahead = input.lookahead1(); + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unnamed(fields), Some(semi))) + } else { + Err(lookahead.error()) + } + } else if lookahead.peek(token::Brace) { + let fields = input.parse()?; + Ok((where_clause, Fields::Named(fields), None)) + } else if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unit, Some(semi))) + } else { + Err(lookahead.error()) + } + } + + pub(crate) fn data_enum( + input: ParseStream, + ) -> Result<( + Option, + token::Brace, + Punctuated, + )> { + let where_clause = input.parse()?; + + let content; + let brace = braced!(content in input); + let variants = content.parse_terminated(Variant::parse, Token![,])?; + + Ok((where_clause, brace, variants)) + } + + pub(crate) fn data_union(input: ParseStream) -> Result<(Option, FieldsNamed)> { + let where_clause = input.parse()?; + let fields = input.parse()?; + Ok((where_clause, fields)) + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::FilterAttrs; + use crate::data::Fields; + use crate::derive::{Data, DeriveInput}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for DeriveInput { + fn to_tokens(&self, tokens: &mut TokenStream) { + for attr in self.attrs.outer() { + attr.to_tokens(tokens); + } + self.vis.to_tokens(tokens); + match &self.data { + Data::Struct(d) => d.struct_token.to_tokens(tokens), + Data::Enum(d) => d.enum_token.to_tokens(tokens), + Data::Union(d) => d.union_token.to_tokens(tokens), + } + self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); + match &self.data { + Data::Struct(data) => match &data.fields { + Fields::Named(fields) => { + self.generics.where_clause.to_tokens(tokens); + fields.to_tokens(tokens); + } + Fields::Unnamed(fields) => { + fields.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + Fields::Unit => { + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + }, + Data::Enum(data) => { + self.generics.where_clause.to_tokens(tokens); + data.brace_token.surround(tokens, |tokens| { + data.variants.to_tokens(tokens); + }); + } + Data::Union(data) => { + self.generics.where_clause.to_tokens(tokens); + data.fields.to_tokens(tokens); + } + } + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/discouraged.rs b/zerocopy/vendor/syn-3.0.3/src/discouraged.rs new file mode 100644 index 0000000000..60584809da --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/discouraged.rs @@ -0,0 +1,233 @@ +//! Extensions to the parsing API with niche applicability. + +use crate::buffer::Cursor; +use crate::error::Result; +use crate::parse::{inner_unexpected, ParseBuffer, Unexpected}; +use alloc::rc::Rc; +use core::cell::Cell; +use core::mem; +use proc_macro2::extra::DelimSpan; +use proc_macro2::Delimiter; + +/// Extensions to the `ParseStream` API to support speculative parsing. +pub trait Speculative: private::Sealed { + /// Advance this parse stream to the position of a forked parse stream. + /// + /// This is the opposite operation to [`ParseStream::fork`]. You can fork a + /// parse stream, perform some speculative parsing, then join the original + /// stream to the fork to "commit" the parsing from the fork to the main + /// stream. + /// + /// If you can avoid doing this, you should, as it limits the ability to + /// generate useful errors. That said, it is often the only way to parse + /// syntax of the form `A* B*` for arbitrary syntax `A` and `B`. The problem + /// is that when the fork fails to parse an `A`, it's impossible to tell + /// whether that was because of a syntax error and the user meant to provide + /// an `A`, or that the `A`s are finished and it's time to start parsing + /// `B`s. Use with care. + /// + /// Also note that if `A` is a subset of `B`, `A* B*` can be parsed by + /// parsing `B*` and removing the leading members of `A` from the + /// repetition, bypassing the need to involve the downsides associated with + /// speculative parsing. + /// + /// [`ParseStream::fork`]: ParseBuffer::fork + /// + /// # Example + /// + /// There has been chatter about the possibility of making the colons in the + /// turbofish syntax like `path::to::` no longer required by accepting + /// `path::to` in expression position. Specifically, according to [RFC + /// 2544], [`PathSegment`] parsing should always try to consume a following + /// `<` token as the start of generic arguments, and reset to the `<` if + /// that fails (e.g. the token is acting as a less-than operator). + /// + /// This is the exact kind of parsing behavior which requires the "fork, + /// try, commit" behavior that [`ParseStream::fork`] discourages. With + /// `advance_to`, we can avoid having to parse the speculatively parsed + /// content a second time. + /// + /// This change in behavior can be implemented in syn by replacing just the + /// `Parse` implementation for `PathSegment`: + /// + /// ``` + /// # use syn::ext::IdentExt; + /// use syn::parse::discouraged::Speculative; + /// # use syn::parse::{Parse, ParseStream}; + /// # use syn::{Ident, PathArguments, Result, Token}; + /// + /// pub struct PathSegment { + /// pub ident: Ident, + /// pub arguments: PathArguments, + /// } + /// # + /// # impl From for PathSegment + /// # where + /// # T: Into, + /// # { + /// # fn from(ident: T) -> Self { + /// # PathSegment { + /// # ident: ident.into(), + /// # arguments: PathArguments::None, + /// # } + /// # } + /// # } + /// + /// impl Parse for PathSegment { + /// fn parse(input: ParseStream) -> Result { + /// if input.peek(Token![super]) + /// || input.peek(Token![self]) + /// || input.peek(Token![Self]) + /// || input.peek(Token![crate]) + /// { + /// let ident = input.call(Ident::parse_any)?; + /// return Ok(PathSegment::from(ident)); + /// } + /// + /// let ident = input.parse()?; + /// if input.peek(Token![::]) && input.peek3(Token![<]) { + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(input.parse()?), + /// }); + /// } + /// if input.peek(Token![<]) && !input.peek(Token![<=]) { + /// let fork = input.fork(); + /// if let Ok(arguments) = fork.parse() { + /// input.advance_to(&fork); + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(arguments), + /// }); + /// } + /// } + /// Ok(PathSegment::from(ident)) + /// } + /// } + /// + /// # syn::parse_str::("a").unwrap(); + /// ``` + /// + /// # Drawbacks + /// + /// The main drawback of this style of speculative parsing is in error + /// presentation. Even if the lookahead is the "correct" parse, the error + /// that is shown is that of the "fallback" parse. To use the same example + /// as the turbofish above, take the following unfinished "turbofish": + /// + /// ```text + /// let _ = f<&'a fn(), for<'a> serde::>(); + /// ``` + /// + /// If this is parsed as generic arguments, we can provide the error message + /// + /// ```text + /// error: expected identifier + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^ + /// ``` + /// + /// but if parsed using the above speculative parsing, it falls back to + /// assuming that the `<` is a less-than when it fails to parse the generic + /// arguments, and tries to interpret the `&'a` as the start of a labelled + /// loop, resulting in the much less helpful error + /// + /// ```text + /// error: expected `:` + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^^ + /// ``` + /// + /// This can be mitigated with various heuristics (two examples: show both + /// forks' parse errors, or show the one that consumed more tokens), but + /// when you can control the grammar, sticking to something that can be + /// parsed LL(3) and without the LL(*) speculative parsing this makes + /// possible, displaying reasonable errors becomes much more simple. + /// + /// [RFC 2544]: https://github.com/rust-lang/rfcs/pull/2544 + /// [`PathSegment`]: crate::PathSegment + /// + /// # Performance + /// + /// This method performs a cheap fixed amount of work that does not depend + /// on how far apart the two streams are positioned. + /// + /// # Panics + /// + /// The forked stream in the argument of `advance_to` must have been + /// obtained by forking `self`. Attempting to advance to any other stream + /// will cause a panic. + fn advance_to(&self, fork: &Self); +} + +impl<'a> Speculative for ParseBuffer<'a> { + fn advance_to(&self, fork: &Self) { + if !crate::buffer::same_scope(self.cursor(), fork.cursor()) { + panic!("fork was not derived from the advancing parse stream"); + } + + let (self_unexp, self_sp) = inner_unexpected(self); + let (fork_unexp, fork_sp) = inner_unexpected(fork); + if !Rc::ptr_eq(&self_unexp, &fork_unexp) { + match (fork_sp, self_sp) { + // Unexpected set on the fork, but not on `self`, copy it over. + (Some((span, delimiter)), None) => { + self_unexp.set(Unexpected::Some(span, delimiter)); + } + // Unexpected unset. Use chain to propagate errors from fork. + (None, None) => { + fork_unexp.set(Unexpected::Chain(self_unexp)); + + // Ensure toplevel 'unexpected' tokens from the fork don't + // propagate up the chain by replacing the root `unexpected` + // pointer, only 'unexpected' tokens from existing group + // parsers should propagate. + fork.unexpected + .set(Some(Rc::new(Cell::new(Unexpected::None)))); + } + // Unexpected has been set on `self`. No changes needed. + (_, Some(_)) => {} + } + } + + // See comment on `cell` in the struct definition. + self.cell + .set(unsafe { mem::transmute::>(fork.cursor()) }); + } +} + +/// Extensions to the `ParseStream` API to support manipulating invisible +/// delimiters the same as if they were visible. +pub trait AnyDelimiter: private::Sealed { + /// Returns the delimiter, the span of the delimiter token, and the nested + /// contents for further parsing. + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)>; +} + +impl<'a> AnyDelimiter for ParseBuffer<'a> { + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)> { + self.step(|cursor| { + if let Some((content, delimiter, span, rest)) = cursor.any_group() { + let scope = span.close(); + let nested = crate::parse::advance_step_cursor(cursor, content); + let unexpected = crate::parse::get_unexpected(self); + let content = crate::parse::new_parse_buffer(scope, nested, unexpected); + Ok(((delimiter, span, content), rest)) + } else { + Err(cursor.error("expected any delimiter")) + } + }) + } +} + +mod private { + use crate::parse::ParseBuffer; + + pub trait Sealed {} + + impl<'a> Sealed for ParseBuffer<'a> {} +} diff --git a/zerocopy/vendor/syn-3.0.3/src/drops.rs b/zerocopy/vendor/syn-3.0.3/src/drops.rs new file mode 100644 index 0000000000..20ab75e421 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/drops.rs @@ -0,0 +1,58 @@ +use core::iter; +use core::mem::ManuallyDrop; +use core::ops::{Deref, DerefMut}; +use core::option; +use core::slice; + +#[repr(transparent)] +pub(crate) struct NoDrop(ManuallyDrop); + +impl NoDrop { + pub(crate) fn new(value: T) -> Self + where + T: TrivialDrop, + { + NoDrop(ManuallyDrop::new(value)) + } +} + +impl Deref for NoDrop { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NoDrop { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub(crate) trait TrivialDrop {} + +impl TrivialDrop for iter::Empty {} +impl TrivialDrop for slice::Iter<'_, T> {} +impl TrivialDrop for slice::IterMut<'_, T> {} +impl TrivialDrop for option::IntoIter<&T> {} +impl TrivialDrop for option::IntoIter<&mut T> {} + +#[test] +fn test_needs_drop() { + use core::mem::needs_drop; + + struct NeedsDrop; + + impl Drop for NeedsDrop { + fn drop(&mut self) {} + } + + assert!(needs_drop::()); + + // Test each of the types with a handwritten TrivialDrop impl above. + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); +} diff --git a/zerocopy/vendor/syn-3.0.3/src/error.rs b/zerocopy/vendor/syn-3.0.3/src/error.rs new file mode 100644 index 0000000000..16fb7d9431 --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/error.rs @@ -0,0 +1,552 @@ +#[cfg(feature = "parsing")] +use crate::buffer::Cursor; +use crate::ext::{PunctExt as _, TokenStreamExt as _}; +use crate::thread::ThreadBound; +#[cfg(feature = "parsing")] +use alloc::format; +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display}; +#[cfg(feature = "parsing")] +use core::ops::Range; +use core::slice; +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; +#[cfg(feature = "printing")] +use quote::ToTokens; + +/// The result of a Syn parser. +pub type Result = core::result::Result; + +/// Error returned when a Syn parser cannot parse the input tokens. +/// +/// # Error reporting in proc macros +/// +/// The correct way to report errors back to the compiler from a procedural +/// macro is by emitting an appropriately spanned invocation of +/// [`compile_error!`] in the generated code. This produces a better diagnostic +/// message than simply panicking the macro. +/// +/// [`compile_error!`]: core::compile_error! +/// +/// When parsing macro input, the [`parse_macro_input!`] macro handles the +/// conversion to `compile_error!` automatically. +/// +/// [`parse_macro_input!`]: crate::parse_macro_input! +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// use proc_macro::TokenStream; +/// use syn::parse::{Parse, ParseStream, Result}; +/// use syn::{parse_macro_input, ItemFn}; +/// +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_attribute] +/// # }; +/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream { +/// let args = parse_macro_input!(args as MyAttrArgs); +/// let input = parse_macro_input!(input as ItemFn); +/// +/// /* ... */ +/// # TokenStream::new() +/// } +/// +/// struct MyAttrArgs { +/// # _k: [(); { stringify! { +/// ... +/// # }; 0 }] +/// } +/// +/// impl Parse for MyAttrArgs { +/// fn parse(input: ParseStream) -> Result { +/// # stringify! { +/// ... +/// # }; +/// # unimplemented!() +/// } +/// } +/// ``` +/// +/// For errors that arise later than the initial parsing stage, the +/// [`.to_compile_error()`] or [`.into_compile_error()`] methods can be used to +/// perform an explicit conversion to `compile_error!`. +/// +/// [`.to_compile_error()`]: Error::to_compile_error +/// [`.into_compile_error()`]: Error::into_compile_error +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// # use proc_macro::TokenStream; +/// # use syn::{parse_macro_input, DeriveInput}; +/// # +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_derive(MyDerive)] +/// # }; +/// pub fn my_derive(input: TokenStream) -> TokenStream { +/// let input = parse_macro_input!(input as DeriveInput); +/// +/// // fn(DeriveInput) -> syn::Result +/// expand::my_derive(input) +/// .unwrap_or_else(syn::Error::into_compile_error) +/// .into() +/// } +/// # +/// # mod expand { +/// # use proc_macro2::TokenStream; +/// # use syn::{DeriveInput, Result}; +/// # +/// # pub fn my_derive(input: DeriveInput) -> Result { +/// # unimplemented!() +/// # } +/// # } +/// ``` +pub struct Error { + messages: Vec, +} + +struct ErrorMessage { + // Span is implemented as an index into a thread-local interner to keep the + // size small. It is not safe to access from a different thread. We want + // errors to be Send and Sync to play nicely with ecosystem crates for error + // handling, so pin the span we're given to its original thread and assume + // it is Span::call_site if accessed from any other thread. + span: ThreadBound, + message: String, +} + +// Cannot use core::ops::Range because that does not implement Copy, +// whereas ThreadBound requires a Copy impl as a way to ensure no Drop impls +// are involved. +struct SpanRange { + start: Span, + end: Span, +} + +#[cfg(test)] +struct _Test +where + Error: Send + Sync; + +impl Error { + /// Usually the [`ParseStream::error`] method will be used instead, which + /// automatically uses the correct span from the current position of the + /// parse stream. + /// + /// Use `Error::new` when the error needs to be triggered on some span other + /// than where the parse stream is currently positioned. + /// + /// [`ParseStream::error`]: crate::parse::ParseBuffer::error + /// + /// # Example + /// + /// ``` + /// use syn::{Error, Ident, LitStr, Result, Token}; + /// use syn::parse::ParseStream; + /// + /// // Parses input that looks like `name = "string"` where the key must be + /// // the identifier `name` and the value may be any string literal. + /// // Returns the string literal. + /// fn parse_name(input: ParseStream) -> Result { + /// let name_token: Ident = input.parse()?; + /// if name_token != "name" { + /// // Trigger an error not on the current position of the stream, + /// // but on the position of the unexpected identifier. + /// return Err(Error::new(name_token.span(), "expected `name`")); + /// } + /// input.parse::()?; + /// let s: LitStr = input.parse()?; + /// Ok(s) + /// } + /// ``` + pub fn new(span: Span, message: impl Display) -> Self { + return new(span, message.to_string()); + + fn new(span: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { + start: span, + end: span, + }), + message, + }], + } + } + } + + /// Creates an error with the specified message spanning the given syntax + /// tree node. + /// + /// Unlike the `Error::new` constructor, this constructor takes an argument + /// `tokens` which is a syntax tree node. This allows the resulting `Error` + /// to attempt to span all tokens inside of `tokens`. While you would + /// typically be able to use the `Spanned` trait with the above `Error::new` + /// constructor, implementation limitations today mean that + /// `Error::new_spanned` may provide a higher-quality error message on + /// stable Rust. + /// + /// When in doubt it's recommended to stick to `Error::new` (or + /// `ParseStream::error`)! + #[cfg(feature = "printing")] + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + pub fn new_spanned(tokens: impl ToTokens, message: impl Display) -> Self { + return new_spanned(tokens.into_token_stream(), message.to_string()); + + fn new_spanned(tokens: TokenStream, message: String) -> Error { + let mut iter = tokens.into_iter(); + let start = iter.next().map_or_else(Span::call_site, |t| t.span()); + let end = iter.last().map_or(start, |t| t.span()); + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } + } + + /// Creates an error spanning the given cursor range. + /// + /// # Example + /// + /// This parses a sequence of '+'-separated lifetimes and types like + /// `Vec + dyn Display + 'static`, at least one of which must be a type. + /// + /// ``` + /// use syn::{Lifetime, Token, Type}; + /// use syn::parse::{Error, ParseStream, Result}; + /// + /// enum Thing { + /// Lifetime(Lifetime), + /// Type(Type), + /// } + /// + /// fn parse_things(input: ParseStream) -> Result> { + /// let things_begin = input.cursor(); + /// let things_end; + /// let mut things = Vec::new(); + /// let mut has_type = false; + /// loop { + /// if input.peek(Lifetime) { + /// let lifetime: Lifetime = input.parse()?; + /// things.push(Thing::Lifetime(lifetime)); + /// } else { + /// let ty = input.call(Type::without_plus)?; + /// things.push(Thing::Type(ty)); + /// has_type = true; + /// } + /// let plus_token: Option = input.parse()?; + /// if plus_token.is_none() { + /// things_end = input.cursor(); + /// break; + /// } + /// } + /// + /// if has_type { + /// Ok(things) + /// } else { + /// let msg = "things must not be all lifetimes, at least one type is required"; + /// Err(Error::new_range(things_begin..things_end, msg)) + /// } + /// } + /// ``` + /// + /// ```text + /// error: things must not be all lifetimes, at least one type is required + /// --> example.rs:4:23 + /// | + /// 4 | example!(THINGS = 'a + 'b, ...); + /// | ^^^^^^^ + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn new_range<'a>(span: impl Into>>, message: impl Display) -> Self { + return new_range(span.into(), message.to_string()); + + fn new_range(span: Range, message: String) -> Error { + assert!(crate::buffer::same_buffer(span.start, span.end)); + assert!(span.start <= span.end); + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { + start: span.start.span(), + end: if span.start == span.end { + span.end.span() + } else { + span.end.prev_span() + }, + }), + message, + }], + } + } + } + + /// The source location of the error. + /// + /// Spans are not thread-safe so this function returns `Span::call_site()` + /// if called from a different thread than the one on which the `Error` was + /// originally created. + pub fn span(&self) -> Span { + let SpanRange { start, end } = match self.messages[0].span.get() { + Some(span) => *span, + None => return Span::call_site(), + }; + start.join(end).unwrap_or(start) + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// The [`parse_macro_input!`] macro provides a convenient way to invoke + /// this method correctly in a procedural macro. + /// + /// [`compile_error!`]: core::compile_error! + /// [`parse_macro_input!`]: crate::parse_macro_input! + pub fn to_compile_error(&self) -> TokenStream { + let mut tokens = TokenStream::new(); + for msg in &self.messages { + ErrorMessage::to_compile_error(msg, &mut tokens); + } + tokens + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// [`compile_error!`]: core::compile_error! + /// + /// # Example + /// + /// ``` + /// # extern crate proc_macro; + /// # + /// use proc_macro::TokenStream; + /// use syn::{parse_macro_input, DeriveInput, Error}; + /// + /// # const _: &str = stringify! { + /// #[proc_macro_derive(MyTrait)] + /// # }; + /// pub fn derive_my_trait(input: TokenStream) -> TokenStream { + /// let input = parse_macro_input!(input as DeriveInput); + /// my_trait::expand(input) + /// .unwrap_or_else(Error::into_compile_error) + /// .into() + /// } + /// + /// mod my_trait { + /// use proc_macro2::TokenStream; + /// use syn::{DeriveInput, Result}; + /// + /// pub(crate) fn expand(input: DeriveInput) -> Result { + /// /* ... */ + /// # unimplemented!() + /// } + /// } + /// ``` + pub fn into_compile_error(self) -> TokenStream { + self.to_compile_error() + } + + /// Add another error message to self such that when `to_compile_error()` is + /// called, both errors will be emitted together. + pub fn combine(&mut self, another: Error) { + self.messages.extend(another.messages); + } +} + +impl ErrorMessage { + fn to_compile_error(&self, tokens: &mut TokenStream) { + let (start, end) = match self.span.get() { + Some(range) => (range.start, range.end), + None => (Span::call_site(), Span::call_site()), + }; + + // ::core::compile_error!($message) + tokens.append(TokenTree::Punct(Punct::new_spanned( + ':', + Spacing::Joint, + start, + ))); + tokens.append(TokenTree::Punct(Punct::new_spanned( + ':', + Spacing::Alone, + start, + ))); + tokens.append(TokenTree::Ident(Ident::new("core", start))); + tokens.append(TokenTree::Punct(Punct::new_spanned( + ':', + Spacing::Joint, + start, + ))); + tokens.append(TokenTree::Punct(Punct::new_spanned( + ':', + Spacing::Alone, + start, + ))); + tokens.append(TokenTree::Ident(Ident::new("compile_error", start))); + tokens.append(TokenTree::Punct(Punct::new_spanned( + '!', + Spacing::Alone, + start, + ))); + tokens.append(TokenTree::Group({ + let mut group = Group::new( + Delimiter::Brace, + TokenStream::from({ + let mut string = Literal::string(&self.message); + string.set_span(end); + TokenTree::Literal(string) + }), + ); + group.set_span(end); + group + })); + } +} + +#[cfg(feature = "parsing")] +pub(crate) fn new_at(scope: Span, cursor: Cursor, message: T) -> Error { + if cursor.eof() { + Error::new(scope, format!("unexpected end of input, {}", message)) + } else { + let span = crate::buffer::open_span_of_group(cursor); + Error::new(span, message) + } +} + +#[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))] +pub(crate) fn new2(start: Span, end: Span, message: T) -> Error { + return new2(start, end, message.to_string()); + + fn new2(start: Span, end: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } +} + +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.messages.len() == 1 { + formatter + .debug_tuple("Error") + .field(&self.messages[0]) + .finish() + } else { + formatter + .debug_tuple("Error") + .field(&self.messages) + .finish() + } + } +} + +impl Debug for ErrorMessage { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.message, formatter) + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(&self.messages[0].message) + } +} + +impl Clone for Error { + fn clone(&self) -> Self { + Error { + messages: self.messages.clone(), + } + } +} + +impl Clone for ErrorMessage { + fn clone(&self) -> Self { + ErrorMessage { + span: self.span, + message: self.message.clone(), + } + } +} + +impl Clone for SpanRange { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SpanRange {} + +// TODO: impl core::error::Error (requires Rust 1.81+) +impl std::error::Error for Error {} + +impl From for Error { + fn from(err: LexError) -> Self { + Error::new(err.span(), err) + } +} + +impl IntoIterator for Error { + type Item = Error; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { + messages: self.messages.into_iter(), + } + } +} + +pub struct IntoIter { + messages: vec::IntoIter, +} + +impl Iterator for IntoIter { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?], + }) + } +} + +impl<'a> IntoIterator for &'a Error { + type Item = Error; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Iter { + messages: self.messages.iter(), + } + } +} + +pub struct Iter<'a> { + messages: slice::Iter<'a, ErrorMessage>, +} + +impl<'a> Iterator for Iter<'a> { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?.clone()], + }) + } +} + +impl Extend for Error { + fn extend>(&mut self, iter: T) { + for err in iter { + self.combine(err); + } + } +} diff --git a/zerocopy/vendor/syn-3.0.3/src/export.rs b/zerocopy/vendor/syn-3.0.3/src/export.rs new file mode 100644 index 0000000000..eca67f6ada --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/export.rs @@ -0,0 +1,73 @@ +#[doc(hidden)] +pub use core::clone::Clone; +#[doc(hidden)] +pub use core::cmp::{Eq, PartialEq}; +#[doc(hidden)] +pub use core::concat; +#[doc(hidden)] +pub use core::default::Default; +#[doc(hidden)] +pub use core::fmt::Debug; +#[doc(hidden)] +pub use core::hash::{Hash, Hasher}; +#[doc(hidden)] +pub use core::marker::Copy; +#[doc(hidden)] +pub use core::option::Option::{None, Some}; +#[doc(hidden)] +pub use core::result::Result::{Err, Ok}; +#[doc(hidden)] +pub use core::stringify; + +#[doc(hidden)] +pub type Formatter<'a> = core::fmt::Formatter<'a>; +#[doc(hidden)] +pub type FmtResult = core::fmt::Result; + +#[doc(hidden)] +pub type bool = core::primitive::bool; +#[doc(hidden)] +pub type str = core::primitive::str; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote; + +#[doc(hidden)] +pub type Span = proc_macro2::Span; +#[doc(hidden)] +pub type TokenStream2 = proc_macro2::TokenStream; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::group::{parse_braces, parse_brackets, parse_parens}; + +#[doc(hidden)] +pub use crate::span::IntoSpans; + +#[cfg(all(feature = "parsing", feature = "printing"))] +#[doc(hidden)] +pub use crate::parse_quote::parse as parse_quote; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::parsing::{peek_punct, punct as parse_punct}; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use crate::token::printing::punct as print_punct; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::private::CustomToken; + +#[cfg(feature = "proc-macro")] +#[doc(hidden)] +pub type TokenStream = proc_macro::TokenStream; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote::{ToTokens, TokenStreamExt}; + +#[doc(hidden)] +pub struct private(pub(crate) ()); diff --git a/zerocopy/vendor/syn-3.0.3/src/expr.rs b/zerocopy/vendor/syn-3.0.3/src/expr.rs new file mode 100644 index 0000000000..c9437d50cf --- /dev/null +++ b/zerocopy/vendor/syn-3.0.3/src/expr.rs @@ -0,0 +1,4237 @@ +use crate::attr::Attribute; +#[cfg(all(feature = "parsing", feature = "full"))] +use crate::error::Result; +#[cfg(feature = "parsing")] +use crate::ext::IdentExt as _; +#[cfg(feature = "full")] +use crate::generics::BoundLifetimes; +use crate::ident::Ident; +#[cfg(any(feature = "parsing", feature = "full"))] +use crate::lifetime::Lifetime; +use crate::lit::Lit; +use crate::mac::Macro; +use crate::op::{BinOp, UnOp}; +#[cfg(feature = "parsing")] +use crate::parse::ParseStream; +#[cfg(feature = "full")] +use crate::pat::Pat; +use crate::path::{AngleBracketedGenericArguments, Path, QSelf}; +use crate::punctuated::Punctuated; +#[cfg(feature = "full")] +use crate::stmt::Block; +use crate::token; +use crate::ty::Type; +#[cfg(feature = "full")] +use crate::ty::{PointerMutability, ReturnType}; +use alloc::boxed::Box; +use alloc::vec::Vec; +#[cfg(feature = "printing")] +use core::fmt::{self, Display}; +use core::hash::{Hash, Hasher}; +#[cfg(all(feature = "parsing", feature = "full"))] +use core::mem; +use proc_macro2::{Span, TokenStream}; +#[cfg(feature = "printing")] +use quote::IdentFragment; + +ast_enum_of_structs! { + /// A Rust expression. + /// + /// *This type is available only if Syn is built with the `"derive"` or `"full"` + /// feature, but most of the variants are not available unless "full" is enabled.* + /// + /// # Syntax tree enums + /// + /// This type is a syntax tree enum. In Syn this and other syntax tree enums + /// are designed to be traversed using the following rebinding idiom. + /// + /// ``` + /// # use syn::Expr; + /// # + /// # fn example(expr: Expr) { + /// # const IGNORE: &str = stringify! { + /// let expr: Expr = /* ... */; + /// # }; + /// match expr { + /// Expr::MethodCall(expr) => { + /// /* ... */ + /// } + /// Expr::Cast(expr) => { + /// /* ... */ + /// } + /// Expr::If(expr) => { + /// /* ... */ + /// } + /// + /// /* ... */ + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// We begin with a variable `expr` of type `Expr` that has no fields + /// (because it is an enum), and by matching on it and rebinding a variable + /// with the same name `expr` we effectively imbue our variable with all of + /// the data fields provided by the variant that it turned out to be. So for + /// example above if we ended up in the `MethodCall` case then we get to use + /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get + /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. + /// + /// This approach avoids repeating the variant names twice on every line. + /// + /// ``` + /// # use syn::{Expr, ExprMethodCall}; + /// # + /// # fn example(expr: Expr) { + /// // Repetitive; recommend not doing this. + /// match expr { + /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { + /// # } + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// In general, the name to which a syntax tree enum variant is bound should + /// be a suitable name for the complete syntax tree enum type. + /// + /// ``` + /// # use syn::{Expr, ExprField}; + /// # + /// # fn example(discriminant: ExprField) { + /// // Binding is called `base` which is the name I would use if I were + /// // assigning `*discriminant.base` without an `if let`. + /// if let Expr::Tuple(base) = *discriminant.base { + /// # } + /// # } + /// ``` + /// + /// A sign that you may not be choosing the right variable names is if you + /// see names getting repeated in your code, like accessing + /// `receiver.receiver` or `pat.pat` or `cond.cond`. + /// + /// # Exhaustive matching + /// + /// For testing exhaustiveness in downstream code, use the following idiom: + /// + /// ``` + /// # use syn::Expr; + /// # + /// # fn example(expr: Expr) { + /// match expr { + /// #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))] + /// + /// Expr::Array(expr) => { /*...*/ } + /// Expr::Assign(expr) => { /*...*/ } + #[cfg_attr(not(doctest), doc = " ...")] + /// Expr::Yield(expr) => { /*...*/ } + /// + /// _ => { /* some sane fallback */ } + /// } + /// # } + /// ``` + /// + /// This way we fail your tests but don't break your library when adding a + /// variant. You will be notified by a test failure when a variant is added, + /// so that you can add code to handle it, but your library will continue to + /// compile and work for downstream users in the interim. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + #[non_exhaustive] + pub enum Expr { + /// A slice literal expression: `[a, b, c, d]`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Array(ExprArray), + + /// An assignment expression: `a = compute()`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Assign(ExprAssign), + + /// An async block: `async { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Async(ExprAsync), + + /// An await expression: `fut.await`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Await(ExprAwait), + + /// A binary operation: `a + b`, `a += b`. + Binary(ExprBinary), + + /// A braced block: `{ ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Block(ExprBlock), + + /// A `break`, with an optional label to break and an optional + /// expression. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Break(ExprBreak), + + /// A function call expression: `invoke(a, b)`. + Call(ExprCall), + + /// A cast expression: `foo as f64`. + Cast(ExprCast), + + /// A closure expression: `|a, b| a + b`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Closure(ExprClosure), + + /// A const block: `const { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Const(ExprConst), + + /// A `continue`, with an optional label. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Continue(ExprContinue), + + /// Access of a named struct field (`obj.k`) or unnamed tuple struct + /// field (`obj.0`). + Field(ExprField), + + /// A for loop: `for pat in expr { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + ForLoop(ExprForLoop), + + /// An expression contained within invisible delimiters. + /// + /// This variant is important for faithfully representing the precedence + /// of expressions and is related to `None`-delimited spans in a + /// `TokenStream`. + Group(ExprGroup), + + /// An `if` expression with an optional `else` block: `if expr { ... } + /// else { ... }`. + /// + /// The `else` branch expression may only be an `If` or `Block` + /// expression, not any of the other types of expression. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + If(ExprIf), + + /// A square bracketed indexing expression: `vector[2]`. + Index(ExprIndex), + + /// The inferred value of a const generic argument, denoted `_`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Infer(ExprInfer), + + /// A pattern application: `let Some(x) = opt`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Let(ExprLet), + + /// A literal in place of an expression: `1`, `"foo"`. + Lit(ExprLit), + + /// Conditionless loop: `loop { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Loop(ExprLoop), + + /// A macro invocation expression: `format!("{}", q)`. + Macro(ExprMacro), + + /// A `match` expression: `match n { Some(n) => {}, None => {} }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Match(ExprMatch), + + /// A method call expression: `x.foo::(a, b)`. + MethodCall(ExprMethodCall), + + /// A parenthesized expression: `(a + b)`. + Paren(ExprParen), + + /// A path like `core::mem::replace` possibly containing generic + /// parameters and a qualified self-type. + /// + /// A plain identifier like `x` is a path of length 1. + Path(ExprPath), + + /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Range(ExprRange), + + /// Address-of operation: `&raw const place` or `&raw mut place`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + RawAddr(ExprRawAddr), + + /// A referencing operation: `&a` or `&mut a`. + Reference(ExprReference), + + /// An array literal constructed from one repeated element: `[0u8; N]`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Repeat(ExprRepeat), + + /// A `return`, with an optional value to be returned. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Return(ExprReturn), + + /// A struct literal expression: `Point { x: 1, y: 1 }`. + /// + /// The `rest` provides the value of the remaining fields as in `S { a: + /// 1, b: 1, ..rest }`. + Struct(ExprStruct), + + /// A try-expression: `expr?`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Try(ExprTry), + + /// A try block: `try { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + TryBlock(ExprTryBlock), + + /// A tuple expression: `(a, b, c, d)`. + Tuple(ExprTuple), + + /// A unary operation: `!x`, `*x`, `-x`. + Unary(ExprUnary), + + /// An unsafe block: `unsafe { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Unsafe(ExprUnsafe), + + /// Tokens in expression position not interpreted by Syn. + /// + ///
+ /// + /// Important: see [Compatibility notes][crate#verbatim-variants]. + /// + ///
+ Verbatim(TokenStream), + + /// A while loop: `while expr { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + While(ExprWhile), + + /// A yield expression: `yield expr`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + Yield(ExprYield), + } +} + +ast_struct! { + /// A slice literal expression: `[a, b, c, d]`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprArray #full { + pub attrs: Vec, + pub bracket_token: token::Bracket, + pub elems: Punctuated, + } +} + +ast_struct! { + /// An assignment expression: `a = compute()`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAssign #full { + pub attrs: Vec, + pub left: Box, + pub eq_token: Token![=], + pub right: Box, + } +} + +ast_struct! { + /// An async block: `async { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAsync #full { + pub attrs: Vec, + pub async_token: Token![async], + pub capture: Option, + /// (Non-exhaustive) Additional optional information about a block. + pub modifiers: BlockModifiers, + pub block: Block, + } +} + +ast_struct! { + /// An await expression: `fut.await`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAwait #full { + pub attrs: Vec, + pub base: Box, + pub dot_token: Token![.], + pub await_token: Token![await], + } +} + +ast_struct! { + /// A binary operation: `a + b`, `a += b`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct ExprBinary { + pub attrs: Vec, + pub left: Box, + pub op: BinOp, + pub right: Box, + } +} + +ast_struct! { + /// A braced block: `{ ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprBlock #full { + pub attrs: Vec, + pub label: Option